From 9ed85e1c518adbb2d2ab287f60ef6867d5c9132a Mon Sep 17 00:00:00 2001 From: Thomas SharedInbox Date: Thu, 14 May 2026 23:06:57 +0200 Subject: [PATCH] fix(test): fix _zOrderIndex race by syncing focus before field/screen transitions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit RawAutocomplete's OverlayPortalController.hide() was called twice: once when focus left the To field and again when ComposeScreen was popped, triggering the _zOrderIndex assertion in overlay.dart. Fix by: 1. pump() after entering the To field so the overlay has a frame to close before the Subject field takes focus. 2. unfocus() + pump() before tapping Send so the overlay is already hidden when the screen pops, preventing a second hide() on unmount. Remove the _zOrderIndex string-filter from FlutterError.onError — the root cause is fixed rather than suppressed. Fixes #79 Co-Authored-By: Claude Sonnet 4.6 --- integration_test/app_e2e_test.dart | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/integration_test/app_e2e_test.dart b/integration_test/app_e2e_test.dart index 9c3e22c..ce35213 100644 --- a/integration_test/app_e2e_test.dart +++ b/integration_test/app_e2e_test.dart @@ -167,11 +167,6 @@ void main() { // DEFUNCT/DISPOSED: keyboard-dismiss or teardown layout errors on // Android/Linux that have no effect on real functionality. if (msg.contains('DEFUNCT') || msg.contains('DISPOSED')) return; - // _zOrderIndex: OverlayPortalController.hide() is called twice during - // rapid navigation in tests (once on focus loss, once on widget unmount). - // overlay.dart itself notes this should not happen during rebuilds; - // it's a Flutter framework race that only reproduces in headless tests. - if (msg.contains('_zOrderIndex')) return; bindingError?.call(details); }; addTearDown(() => FlutterError.onError = bindingError); @@ -269,6 +264,10 @@ void main() { find.widgetWithText(TextFormField, 'To'), userEmail, ); + // Pump so RawAutocomplete's OverlayPortal has a frame to close before + // focus moves to the next field — prevents the double hide() race that + // triggers the _zOrderIndex assertion in overlay.dart. + await tester.pump(); await tester.enterText( find.widgetWithText(TextFormField, 'Subject'), subject, @@ -278,6 +277,10 @@ void main() { await tester.ensureVisible(bodyField); await tester.enterText(bodyField, 'Hello from integration test!'); + // Unfocus before sending so the autocomplete overlay closes cleanly + // before ComposeScreen is popped, avoiding a second hide() on unmount. + FocusManager.instance.primaryFocus?.unfocus(); + await tester.pump(); _log('send email'); await tester.tap(find.byIcon(Icons.send)); // Wait for ComposeScreen to pop back to EmailListScreen after send.