@@ -140,7 +140,8 @@ Future<void> setupToMessageActionSheet(WidgetTester tester, {
140140 // like if it's in padding around a Paragraph.
141141 await tester.longPress (find.byType (MessageContent ), warnIfMissed: false );
142142 // sheet appears onscreen; default duration of bottom-sheet enter animation
143- await tester.pump (const Duration (milliseconds: 250 ));
143+ await transitionDurationObserver.pumpPastTransition (tester);
144+
144145 // Check the action sheet did in fact open, so we don't defeat any tests that
145146 // use simple `find.byIcon`-style checks to test presence/absence of a button.
146147 check (find.byType (BottomSheet )).findsOne ();
@@ -199,19 +200,22 @@ void main() {
199200 check (find.byType (InboxPageBody )).findsOne ();
200201
201202 await tester.longPress (find.text (someChannel.name).hitTestable ());
202- await tester. pump ( const Duration (milliseconds : 250 ) );
203+ await transitionDurationObserver. pumpPastTransition (tester );
203204 }
204205
205206 Future <void > showFromSubscriptionList (WidgetTester tester) async {
207+ final transitionDurationObserver = TransitionDurationObserver ();
208+
206209 await tester.pumpWidget (TestZulipApp (accountId: eg.selfAccount.id,
210+ navigatorObservers: [transitionDurationObserver],
207211 child: const HomePage ()));
208212 await tester.pump ();
209213 await tester.tap (find.byIcon (ZulipIcons .hash_italic));
210214 await tester.pump ();
211215 check (find.byType (SubscriptionListPageBody )).findsOne ();
212216
213217 await tester.longPress (find.text (someChannel.name).hitTestable ());
214- await tester. pump ( const Duration (milliseconds : 250 ) );
218+ await transitionDurationObserver. pumpPastTransition (tester );
215219 }
216220
217221 Future <void > showFromMsglistAppBar (WidgetTester tester, {
@@ -220,6 +224,8 @@ void main() {
220224 }) async {
221225 channel ?? = someChannel;
222226
227+ final transitionDurationObserver = TransitionDurationObserver ();
228+
223229 connection.prepare (json: eg.newestGetMessagesResult (
224230 foundOldest: true , messages: []).toJson ());
225231 if (narrow case ChannelNarrow ()) {
@@ -229,31 +235,35 @@ void main() {
229235 }
230236 await tester.pumpWidget (TestZulipApp (
231237 accountId: eg.selfAccount.id,
238+ navigatorObservers: [transitionDurationObserver],
232239 child: MessageListPage (
233240 initNarrow: narrow)));
234241 await tester.pumpAndSettle ();
235242
236243 await tester.longPress (find.descendant (
237244 of: find.byType (ZulipAppBar ),
238245 matching: find.text (channel.name)));
239- await tester. pump ( const Duration (milliseconds : 250 ) );
246+ await transitionDurationObserver. pumpPastTransition (tester );
240247 }
241248
242249 Future <void > showFromRecipientHeader (WidgetTester tester, {
243250 StreamMessage ? message,
244251 }) async {
245252 message ?? = someMessage;
246253
254+ final transitionDurationObserver = TransitionDurationObserver ();
255+
247256 connection.prepare (json: eg.newestGetMessagesResult (
248257 foundOldest: true , messages: [message]).toJson ());
249258 await tester.pumpWidget (TestZulipApp (accountId: eg.selfAccount.id,
259+ navigatorObservers: [transitionDurationObserver],
250260 child: const MessageListPage (initNarrow: CombinedFeedNarrow ())));
251261 await tester.pumpAndSettle ();
252262
253263 await tester.longPress (find.descendant (
254264 of: find.byType (RecipientHeader ),
255265 matching: find.text (message.displayRecipient ?? '' )));
256- await tester. pump ( const Duration (milliseconds : 250 ) );
266+ await transitionDurationObserver. pumpPastTransition (tester );
257267 }
258268
259269 Future <void > showFromTopicListAppBar (WidgetTester tester, {int ? streamId}) async {
@@ -739,7 +749,7 @@ void main() {
739749
740750 await tester.longPress (find.text (topic));
741751 // sheet appears onscreen; default duration of bottom-sheet enter animation
742- await tester. pump ( const Duration (milliseconds : 250 ) );
752+ await transitionDurationObserver. pumpPastTransition (tester );
743753 }
744754
745755 Future <void > showFromAppBar (WidgetTester tester, {
@@ -766,8 +776,7 @@ void main() {
766776 effectiveTopic.displayName ?? eg.defaultRealmEmptyTopicDisplayName));
767777 await tester.longPress (topicRow);
768778 // sheet appears onscreen; default duration of bottom-sheet enter animation
769- await tester.pump (const Duration (milliseconds: 250 ));
770- }
779+ await transitionDurationObserver.pumpPastTransition (tester); }
771780
772781 Future <void > showFromRecipientHeader (WidgetTester tester, {
773782 StreamMessage ? message,
@@ -785,7 +794,7 @@ void main() {
785794 of: find.byType (RecipientHeader ),
786795 matching: find.text (effectiveMessage.topic.displayName! )));
787796 // sheet appears onscreen; default duration of bottom-sheet enter animation
788- await tester. pump ( const Duration (milliseconds : 250 ) );
797+ await transitionDurationObserver. pumpPastTransition (tester );
789798 }
790799
791800 final actionSheetFinder = find.byType (BottomSheet );
@@ -2037,29 +2046,62 @@ void main() {
20372046 check (await Clipboard .getData ('text/plain' )).isNotNull ().text.equals ('Hello world' );
20382047 });
20392048
2040- testWidgets ('can show snackbar on success' , (tester) async {
2041- // Regression test for: https://github.com/zulip/zulip-flutter/issues/732
2042- testBinding.deviceInfoResult = const IosDeviceInfo (systemVersion: '16.0' );
2043-
2049+ testWidgets ('success' , (tester) async {
20442050 final message = eg.streamMessage ();
20452051 await setupToMessageActionSheet (tester, message: message, narrow: TopicNarrow .ofMessage (message));
20462052
2047- // Make the request take a bit of time to complete…
2048- prepareRawContentResponseSuccess (message: message, rawContent: 'Hello world' ,
2049- delay: const Duration (milliseconds: 500 ));
2053+ prepareRawContentResponseSuccess (message: message, rawContent: 'Hello world' );
20502054 await tapCopyMessageTextButton (tester);
2051- // … and pump a frame to finish the NavigationState.pop animation…
2052- await tester.pump (const Duration (milliseconds: 250 ));
2053- // … before the request finishes. This is the repro condition for #732.
2054- await tester.pump (const Duration (milliseconds: 250 ));
2055+ await tester.pump (Duration .zero);
2056+ check (await Clipboard .getData ('text/plain' )).isNotNull ().text.equals ('Hello world' );
2057+ });
20552058
2056- final snackbar = tester.widget <SnackBar >(find.byType (SnackBar ));
2057- check (snackbar.behavior).equals (SnackBarBehavior .floating);
2058- final zulipLocalizations = GlobalLocalizations .zulipLocalizations;
2059- tester.widget (find.descendant (matchRoot: true ,
2059+ testWidgets ('can show snackbar on success' , (WidgetTester tester) async {
2060+ // Regression test for: https://github.com/zulip/zulip-flutter/issues/732
2061+ final TransitionDurationObserver transitionDurationObserver = TransitionDurationObserver ();
2062+ await tester.pumpWidget (
2063+ MaterialApp (
2064+ navigatorObservers: < NavigatorObserver > [transitionDurationObserver],
2065+ home: Scaffold (
2066+ body: Builder (
2067+ builder: (context) {
2068+ testBinding.deviceInfoResult = const IosDeviceInfo (systemVersion: '16.0' );
2069+ final message = eg.streamMessage ();
2070+ setupToMessageActionSheet (
2071+ tester,
2072+ message: message,
2073+ narrow: TopicNarrow .ofMessage (message),
2074+ );
2075+ return const SizedBox .shrink ();
2076+ },
2077+ ),
2078+ ),
2079+ ),
2080+ );
2081+ final message = eg.streamMessage ();
2082+ // Make the request take a bit of time to complete
2083+ prepareRawContentResponseSuccess (
2084+ message: message,
2085+ rawContent: 'Hello world' ,
2086+ delay: const Duration (milliseconds: 500 ),
2087+ );
2088+ await tapCopyMessageTextButton (tester);
2089+ await transitionDurationObserver.pumpPastTransition (tester); // … and pump a frame to finish the NavigationState.pop animation…
2090+ await transitionDurationObserver.pumpPastTransition (tester); // … before the request finishes. This is the repro condition for #732.
2091+
2092+ final snackbar = tester.widget <SnackBar >(find.byType (SnackBar ));
2093+ check (snackbar.behavior).equals (SnackBarBehavior .floating);
2094+
2095+ final zulipLocalizations = GlobalLocalizations .zulipLocalizations;
2096+ tester.widget (
2097+ find.descendant (
2098+ matchRoot: true ,
20602099 of: find.byWidget (snackbar.content),
2061- matching: find.text (zulipLocalizations.successMessageTextCopied)));
2062- });
2100+ matching: find.text (zulipLocalizations.successMessageTextCopied),
2101+ ),
2102+ );
2103+ });
2104+
20632105
20642106 testWidgets ('request has an error' , (tester) async {
20652107 final message = eg.streamMessage ();
@@ -2283,7 +2325,7 @@ void main() {
22832325 // See comment in setupToMessageActionSheet about warnIfMissed: false
22842326 await tester.longPress (find.byType (MessageContent ), warnIfMissed: false );
22852327 // sheet appears onscreen; default duration of bottom-sheet enter animation
2286- await tester. pump ( const Duration (milliseconds : 250 ) );
2328+ await transitionDurationObserver. pumpPastTransition (tester );
22872329 check (find.byType (BottomSheet )).findsOne ();
22882330 checkButtonIsPresent (expected);
22892331
0 commit comments