From a9f24bb4a6bf7f2e542dce0205b85e278602bc8b Mon Sep 17 00:00:00 2001 From: MdSaifAliMolla <145194907+MdSaifAliMolla@users.noreply.github.com> Date: Mon, 13 Oct 2025 00:12:38 +0530 Subject: [PATCH] Get route-transition duration robustly --- test/widgets/action_sheet_test.dart | 30 +++++++++++++++++---------- test/widgets/compose_box_test.dart | 9 +++++--- test/widgets/emoji_reaction_test.dart | 2 +- 3 files changed, 26 insertions(+), 15 deletions(-) diff --git a/test/widgets/action_sheet_test.dart b/test/widgets/action_sheet_test.dart index 621f759f28..f71a80bda0 100644 --- a/test/widgets/action_sheet_test.dart +++ b/test/widgets/action_sheet_test.dart @@ -140,7 +140,7 @@ Future setupToMessageActionSheet(WidgetTester tester, { // like if it's in padding around a Paragraph. await tester.longPress(find.byType(MessageContent), warnIfMissed: false); // sheet appears onscreen; default duration of bottom-sheet enter animation - await tester.pump(const Duration(milliseconds: 250)); + await transitionDurationObserver.pumpPastTransition(tester); // Check the action sheet did in fact open, so we don't defeat any tests that // use simple `find.byIcon`-style checks to test presence/absence of a button. check(find.byType(BottomSheet)).findsOne(); @@ -199,11 +199,13 @@ void main() { check(find.byType(InboxPageBody)).findsOne(); await tester.longPress(find.text(someChannel.name).hitTestable()); - await tester.pump(const Duration(milliseconds: 250)); + await transitionDurationObserver.pumpPastTransition(tester); } Future showFromSubscriptionList(WidgetTester tester) async { + transitionDurationObserver = TransitionDurationObserver(); await tester.pumpWidget(TestZulipApp(accountId: eg.selfAccount.id, + navigatorObservers: [transitionDurationObserver], child: const HomePage())); await tester.pump(); await tester.tap(find.byIcon(ZulipIcons.hash_italic)); @@ -211,7 +213,7 @@ void main() { check(find.byType(SubscriptionListPageBody)).findsOne(); await tester.longPress(find.text(someChannel.name).hitTestable()); - await tester.pump(const Duration(milliseconds: 250)); + await transitionDurationObserver.pumpPastTransition(tester); } Future showFromMsglistAppBar(WidgetTester tester, { @@ -219,6 +221,7 @@ void main() { required Narrow narrow, }) async { channel ??= someChannel; + transitionDurationObserver = TransitionDurationObserver(); connection.prepare(json: eg.newestGetMessagesResult( foundOldest: true, messages: []).toJson()); @@ -229,6 +232,7 @@ void main() { } await tester.pumpWidget(TestZulipApp( accountId: eg.selfAccount.id, + navigatorObservers: [transitionDurationObserver], child: MessageListPage( initNarrow: narrow))); await tester.pumpAndSettle(); @@ -236,24 +240,26 @@ void main() { await tester.longPress(find.descendant( of: find.byType(ZulipAppBar), matching: find.text(channel.name))); - await tester.pump(const Duration(milliseconds: 250)); + await transitionDurationObserver.pumpPastTransition(tester); } Future showFromRecipientHeader(WidgetTester tester, { StreamMessage? message, }) async { message ??= someMessage; + transitionDurationObserver = TransitionDurationObserver(); connection.prepare(json: eg.newestGetMessagesResult( foundOldest: true, messages: [message]).toJson()); await tester.pumpWidget(TestZulipApp(accountId: eg.selfAccount.id, + navigatorObservers: [transitionDurationObserver], child: const MessageListPage(initNarrow: CombinedFeedNarrow()))); await tester.pumpAndSettle(); await tester.longPress(find.descendant( of: find.byType(RecipientHeader), matching: find.text(message.displayRecipient ?? ''))); - await tester.pump(const Duration(milliseconds: 250)); + await transitionDurationObserver.pumpPastTransition(tester); } Future showFromTopicListAppBar(WidgetTester tester, {int? streamId}) async { @@ -739,7 +745,7 @@ void main() { await tester.longPress(find.text(topic)); // sheet appears onscreen; default duration of bottom-sheet enter animation - await tester.pump(const Duration(milliseconds: 250)); + await transitionDurationObserver.pumpPastTransition(tester); } Future showFromAppBar(WidgetTester tester, { @@ -766,7 +772,7 @@ void main() { effectiveTopic.displayName ?? eg.defaultRealmEmptyTopicDisplayName)); await tester.longPress(topicRow); // sheet appears onscreen; default duration of bottom-sheet enter animation - await tester.pump(const Duration(milliseconds: 250)); + await transitionDurationObserver.pumpPastTransition(tester); } Future showFromRecipientHeader(WidgetTester tester, { @@ -785,7 +791,7 @@ void main() { of: find.byType(RecipientHeader), matching: find.text(effectiveMessage.topic.displayName!))); // sheet appears onscreen; default duration of bottom-sheet enter animation - await tester.pump(const Duration(milliseconds: 250)); + await transitionDurationObserver.pumpPastTransition(tester); } final actionSheetFinder = find.byType(BottomSheet); @@ -2049,9 +2055,11 @@ void main() { delay: const Duration(milliseconds: 500)); await tapCopyMessageTextButton(tester); // … and pump a frame to finish the NavigationState.pop animation… - await tester.pump(const Duration(milliseconds: 250)); + await transitionDurationObserver.pumpPastTransition(tester); // … before the request finishes. This is the repro condition for #732. - await tester.pump(const Duration(milliseconds: 250)); + await transitionDurationObserver.pumpPastTransition(tester); + // …pump for snackbar to show + await tester.pumpAndSettle(); final snackbar = tester.widget(find.byType(SnackBar)); check(snackbar.behavior).equals(SnackBarBehavior.floating); @@ -2283,7 +2291,7 @@ void main() { // See comment in setupToMessageActionSheet about warnIfMissed: false await tester.longPress(find.byType(MessageContent), warnIfMissed: false); // sheet appears onscreen; default duration of bottom-sheet enter animation - await tester.pump(const Duration(milliseconds: 250)); + await transitionDurationObserver.pumpPastTransition(tester); check(find.byType(BottomSheet)).findsOne(); checkButtonIsPresent(expected); diff --git a/test/widgets/compose_box_test.dart b/test/widgets/compose_box_test.dart index 15a0a7f81e..6d360dbc59 100644 --- a/test/widgets/compose_box_test.dart +++ b/test/widgets/compose_box_test.dart @@ -50,6 +50,7 @@ void main() { late PerAccountStore store; late FakeApiConnection connection; late ComposeBoxState state; + late TransitionDurationObserver transitionDurationObserver; // Caution: when testing edit-message UI, this will often be stale; // read state.controller instead. @@ -96,6 +97,7 @@ void main() { store = await testBinding.globalStore.perAccount(selfAccount.id); connection = store.connection as FakeApiConnection; + transitionDurationObserver = TransitionDurationObserver(); connection.prepare(json: eg.newestGetMessagesResult(foundOldest: true, messages: messages).toJson()); @@ -104,6 +106,7 @@ void main() { connection.prepare(json: GetStreamTopicsResult(topics: []).toJson()); } await tester.pumpWidget(TestZulipApp(accountId: selfAccount.id, + navigatorObservers: [transitionDurationObserver], child: MessageListPage(initNarrow: narrow))); await tester.pumpAndSettle(); connection.takeRequests(); @@ -1719,7 +1722,7 @@ void main() { await tester.longPress(find.byWidgetPredicate((widget) => widget is MessageWithPossibleSender && widget.item.message.id == messageId)); // sheet appears onscreen; default duration of bottom-sheet enter animation - await tester.pump(const Duration(milliseconds: 250)); + await transitionDurationObserver.pumpPastTransition(tester); final findEditButton = find.descendant( of: find.byType(BottomSheet), matching: find.byIcon(ZulipIcons.edit, skipOffstage: false)); @@ -1875,7 +1878,7 @@ void main() { await startEditInteractionFromActionSheet(tester, messageId: messageToEdit.id, originalRawContent: 'message to edit', delay: Duration.zero); - await tester.pump(const Duration(milliseconds: 250)); // bottom-sheet animation + await transitionDurationObserver.pumpPastTransition(tester); // bottom-sheet animation await tester.tap(failedMessageFinder); await tester.pump(); @@ -1899,7 +1902,7 @@ void main() { await startEditInteractionFromActionSheet(tester, messageId: messageToEdit.id, originalRawContent: 'message to edit', delay: Duration.zero); - await tester.pump(const Duration(milliseconds: 250)); // bottom-sheet animation + await transitionDurationObserver.pumpPastTransition(tester); // bottom-sheet animation await tester.tap(failedMessageFinder); await tester.pump(); diff --git a/test/widgets/emoji_reaction_test.dart b/test/widgets/emoji_reaction_test.dart index d50b7c8d7b..f0a66fa85a 100644 --- a/test/widgets/emoji_reaction_test.dart +++ b/test/widgets/emoji_reaction_test.dart @@ -434,7 +434,7 @@ void main() { // request the message action sheet await tester.longPress(find.byType(MessageContent)); // sheet appears onscreen; default duration of bottom-sheet enter animation - await tester.pump(const Duration(milliseconds: 250)); + await transitionDurationObserver.pumpPastTransition(tester); await store.handleEvent(RealmEmojiUpdateEvent(id: 1, realmEmoji: { '1': eg.realmEmojiItem(emojiCode: '1', emojiName: 'buzzing'),