Skip to content

Commit 0de6501

Browse files
Get route-transition duration robustly
1 parent 3d3b1c1 commit 0de6501

File tree

3 files changed

+172
-97
lines changed

3 files changed

+172
-97
lines changed

test/widgets/action_sheet_test.dart

Lines changed: 69 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)