Skip to content

Commit 2ea25f6

Browse files
Get route-transition duration robustly
1 parent 3d3b1c1 commit 2ea25f6

File tree

3 files changed

+188
-110
lines changed

3 files changed

+188
-110
lines changed

test/widgets/action_sheet_test.dart

Lines changed: 69 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -139,8 +139,8 @@ Future<void> setupToMessageActionSheet(WidgetTester tester, {
139139
// the long-press might land where no child hit-tests as true,
140140
// like if it's in padding around a Paragraph.
141141
await tester.longPress(find.byType(MessageContent), warnIfMissed: false);
142-
// sheet appears onscreen; default duration of bottom-sheet enter animation
143-
await tester.pump(const Duration(milliseconds: 250));
142+
await transitionDurationObserver.pumpPastTransition(tester);
143+
144144
// Check the action sheet did in fact open, so we don't defeat any tests that
145145
// use simple `find.byIcon`-style checks to test presence/absence of a button.
146146
check(find.byType(BottomSheet)).findsOne();
@@ -199,19 +199,22 @@ void main() {
199199
check(find.byType(InboxPageBody)).findsOne();
200200

201201
await tester.longPress(find.text(someChannel.name).hitTestable());
202-
await tester.pump(const Duration(milliseconds: 250));
202+
await transitionDurationObserver.pumpPastTransition(tester);
203203
}
204204

205205
Future<void> showFromSubscriptionList(WidgetTester tester) async {
206+
final transitionDurationObserver = TransitionDurationObserver();
207+
206208
await tester.pumpWidget(TestZulipApp(accountId: eg.selfAccount.id,
209+
navigatorObservers: [transitionDurationObserver],
207210
child: const HomePage()));
208211
await tester.pump();
209212
await tester.tap(find.byIcon(ZulipIcons.hash_italic));
210213
await tester.pump();
211214
check(find.byType(SubscriptionListPageBody)).findsOne();
212215

213216
await tester.longPress(find.text(someChannel.name).hitTestable());
214-
await tester.pump(const Duration(milliseconds: 250));
217+
await transitionDurationObserver.pumpPastTransition(tester);
215218
}
216219

217220
Future<void> showFromMsglistAppBar(WidgetTester tester, {
@@ -220,6 +223,8 @@ void main() {
220223
}) async {
221224
channel ??= someChannel;
222225

226+
final transitionDurationObserver = TransitionDurationObserver();
227+
223228
connection.prepare(json: eg.newestGetMessagesResult(
224229
foundOldest: true, messages: []).toJson());
225230
if (narrow case ChannelNarrow()) {
@@ -229,31 +234,35 @@ void main() {
229234
}
230235
await tester.pumpWidget(TestZulipApp(
231236
accountId: eg.selfAccount.id,
237+
navigatorObservers: [transitionDurationObserver],
232238
child: MessageListPage(
233239
initNarrow: narrow)));
234240
await tester.pumpAndSettle();
235241

236242
await tester.longPress(find.descendant(
237243
of: find.byType(ZulipAppBar),
238244
matching: find.text(channel.name)));
239-
await tester.pump(const Duration(milliseconds: 250));
245+
await transitionDurationObserver.pumpPastTransition(tester);
240246
}
241247

242248
Future<void> showFromRecipientHeader(WidgetTester tester, {
243249
StreamMessage? message,
244250
}) async {
245251
message ??= someMessage;
246252

253+
final transitionDurationObserver = TransitionDurationObserver();
254+
247255
connection.prepare(json: eg.newestGetMessagesResult(
248256
foundOldest: true, messages: [message]).toJson());
249257
await tester.pumpWidget(TestZulipApp(accountId: eg.selfAccount.id,
258+
navigatorObservers: [transitionDurationObserver],
250259
child: const MessageListPage(initNarrow: CombinedFeedNarrow())));
251260
await tester.pumpAndSettle();
252261

253262
await tester.longPress(find.descendant(
254263
of: find.byType(RecipientHeader),
255264
matching: find.text(message.displayRecipient ?? '')));
256-
await tester.pump(const Duration(milliseconds: 250));
265+
await transitionDurationObserver.pumpPastTransition(tester);
257266
}
258267

259268
Future<void> showFromTopicListAppBar(WidgetTester tester, {int? streamId}) async {
@@ -739,7 +748,7 @@ void main() {
739748

740749
await tester.longPress(find.text(topic));
741750
// sheet appears onscreen; default duration of bottom-sheet enter animation
742-
await tester.pump(const Duration(milliseconds: 250));
751+
await transitionDurationObserver.pumpPastTransition(tester);
743752
}
744753

745754
Future<void> showFromAppBar(WidgetTester tester, {
@@ -766,8 +775,7 @@ void main() {
766775
effectiveTopic.displayName ?? eg.defaultRealmEmptyTopicDisplayName));
767776
await tester.longPress(topicRow);
768777
// sheet appears onscreen; default duration of bottom-sheet enter animation
769-
await tester.pump(const Duration(milliseconds: 250));
770-
}
778+
await transitionDurationObserver.pumpPastTransition(tester); }
771779

772780
Future<void> showFromRecipientHeader(WidgetTester tester, {
773781
StreamMessage? message,
@@ -785,7 +793,7 @@ void main() {
785793
of: find.byType(RecipientHeader),
786794
matching: find.text(effectiveMessage.topic.displayName!)));
787795
// sheet appears onscreen; default duration of bottom-sheet enter animation
788-
await tester.pump(const Duration(milliseconds: 250));
796+
await transitionDurationObserver.pumpPastTransition(tester);
789797
}
790798

791799
final actionSheetFinder = find.byType(BottomSheet);
@@ -2037,29 +2045,62 @@ void main() {
20372045
check(await Clipboard.getData('text/plain')).isNotNull().text.equals('Hello world');
20382046
});
20392047

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-
2048+
testWidgets('success', (tester) async {
20442049
final message = eg.streamMessage();
20452050
await setupToMessageActionSheet(tester, message: message, narrow: TopicNarrow.ofMessage(message));
20462051

2047-
// Make the request take a bit of time to complete…
2048-
prepareRawContentResponseSuccess(message: message, rawContent: 'Hello world',
2049-
delay: const Duration(milliseconds: 500));
2052+
prepareRawContentResponseSuccess(message: message, rawContent: 'Hello world');
20502053
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));
2054+
await tester.pump(Duration.zero);
2055+
check(await Clipboard.getData('text/plain')).isNotNull().text.equals('Hello world');
2056+
});
20552057

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,
2058+
testWidgets('can show snackbar on success', (WidgetTester tester) async {
2059+
// Regression test for: https://github.com/zulip/zulip-flutter/issues/732
2060+
final TransitionDurationObserver observer = TransitionDurationObserver();
2061+
await tester.pumpWidget(
2062+
MaterialApp(
2063+
navigatorObservers: <NavigatorObserver>[observer],
2064+
home: Scaffold(
2065+
body: Builder(
2066+
builder: (context) {
2067+
testBinding.deviceInfoResult = const IosDeviceInfo(systemVersion: '16.0');
2068+
final message = eg.streamMessage();
2069+
setupToMessageActionSheet(
2070+
tester,
2071+
message: message,
2072+
narrow: TopicNarrow.ofMessage(message),
2073+
);
2074+
return const SizedBox.shrink();
2075+
},
2076+
),
2077+
),
2078+
),
2079+
);
2080+
final message = eg.streamMessage();
2081+
// Make the request take a bit of time to complete
2082+
prepareRawContentResponseSuccess(
2083+
message: message,
2084+
rawContent: 'Hello world',
2085+
delay: const Duration(milliseconds: 500),
2086+
);
2087+
await tapCopyMessageTextButton(tester);
2088+
await observer.pumpPastTransition(tester); // for the NavigationState.pop animation
2089+
await observer.pumpPastTransition(tester); // for the second animation / repro timing
2090+
2091+
final snackbar = tester.widget<SnackBar>(find.byType(SnackBar));
2092+
check(snackbar.behavior).equals(SnackBarBehavior.floating);
2093+
2094+
final zulipLocalizations = GlobalLocalizations.zulipLocalizations;
2095+
tester.widget(
2096+
find.descendant(
2097+
matchRoot: true,
20602098
of: find.byWidget(snackbar.content),
2061-
matching: find.text(zulipLocalizations.successMessageTextCopied)));
2062-
});
2099+
matching: find.text(zulipLocalizations.successMessageTextCopied),
2100+
),
2101+
);
2102+
});
2103+
20632104

20642105
testWidgets('request has an error', (tester) async {
20652106
final message = eg.streamMessage();
@@ -2283,8 +2324,7 @@ void main() {
22832324
// See comment in setupToMessageActionSheet about warnIfMissed: false
22842325
await tester.longPress(find.byType(MessageContent), warnIfMissed: false);
22852326
// sheet appears onscreen; default duration of bottom-sheet enter animation
2286-
await tester.pump(const Duration(milliseconds: 250));
2287-
check(find.byType(BottomSheet)).findsOne();
2327+
await transitionDurationObserver.pumpPastTransition(tester); check(find.byType(BottomSheet)).findsOne();
22882328
checkButtonIsPresent(expected);
22892329

22902330
await tester.pump(Duration(milliseconds: 500)); // flush timers

0 commit comments

Comments
 (0)