Skip to content

Commit 7d9283f

Browse files
Get route-transition duration robustly
1 parent 3d3b1c1 commit 7d9283f

File tree

3 files changed

+84
-48
lines changed

3 files changed

+84
-48
lines changed

test/widgets/action_sheet_test.dart

Lines changed: 49 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,7 @@ 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);
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,7 +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));
778+
await transitionDurationObserver.pumpPastTransition(tester);
770779
}
771780

772781
Future<void> showFromRecipientHeader(WidgetTester tester, {
@@ -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,40 @@ 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-
2044-
final message = eg.streamMessage();
2045-
await setupToMessageActionSheet(tester, message: message, narrow: TopicNarrow.ofMessage(message));
2049+
testWidgets('can show snackbar on success', (WidgetTester tester) async {
2050+
// Regression test for: https://github.com/zulip/zulip-flutter/issues/732
2051+
final TransitionDurationObserver transitionDurationObserver = TransitionDurationObserver();
2052+
await tester.pumpWidget(
2053+
MaterialApp(
2054+
navigatorObservers: <NavigatorObserver>[transitionDurationObserver],
2055+
home: Scaffold(
2056+
body: Builder(
2057+
builder: (context) {
2058+
testBinding.deviceInfoResult = const IosDeviceInfo(systemVersion: '16.0');
2059+
final message = eg.streamMessage();
2060+
setupToMessageActionSheet(tester,message: message,narrow: TopicNarrow.ofMessage(message));
2061+
return const SizedBox.shrink();}
2062+
))));
2063+
final message = eg.streamMessage();
2064+
// Make the request take a bit of time to complete
2065+
prepareRawContentResponseSuccess(message: message,rawContent: 'Hello world',delay: const Duration(milliseconds: 500),
2066+
);
2067+
await tapCopyMessageTextButton(tester);
2068+
// … and pump a frame to finish the NavigationState.pop animation…
2069+
await transitionDurationObserver.pumpPastTransition(tester);
2070+
// … before the request finishes. This is the repro condition for #732.
2071+
await transitionDurationObserver.pumpPastTransition(tester);
20462072

2047-
// Make the request take a bit of time to complete…
2048-
prepareRawContentResponseSuccess(message: message, rawContent: 'Hello world',
2049-
delay: const Duration(milliseconds: 500));
2050-
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));
2073+
final snackbar = tester.widget<SnackBar>(find.byType(SnackBar));
2074+
check(snackbar.behavior).equals(SnackBarBehavior.floating);
20552075

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,
2076+
final zulipLocalizations = GlobalLocalizations.zulipLocalizations;
2077+
tester.widget(find.descendant(matchRoot: true,
20602078
of: find.byWidget(snackbar.content),
2061-
matching: find.text(zulipLocalizations.successMessageTextCopied)));
2062-
});
2079+
matching: find.text(zulipLocalizations.successMessageTextCopied),
2080+
));
2081+
});
2082+
20632083

20642084
testWidgets('request has an error', (tester) async {
20652085
final message = eg.streamMessage();
@@ -2283,7 +2303,7 @@ void main() {
22832303
// See comment in setupToMessageActionSheet about warnIfMissed: false
22842304
await tester.longPress(find.byType(MessageContent), warnIfMissed: false);
22852305
// sheet appears onscreen; default duration of bottom-sheet enter animation
2286-
await tester.pump(const Duration(milliseconds: 250));
2306+
await transitionDurationObserver.pumpPastTransition(tester);
22872307
check(find.byType(BottomSheet)).findsOne();
22882308
checkButtonIsPresent(expected);
22892309

test/widgets/compose_box_test.dart

Lines changed: 34 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1719,10 +1719,11 @@ void main() {
17191719
await tester.longPress(find.byWidgetPredicate((widget) =>
17201720
widget is MessageWithPossibleSender && widget.item.message.id == messageId));
17211721
// sheet appears onscreen; default duration of bottom-sheet enter animation
1722-
await tester.pump(const Duration(milliseconds: 250));
1722+
await tester.pumpAndSettle();
17231723
final findEditButton = find.descendant(
17241724
of: find.byType(BottomSheet),
1725-
matching: find.byIcon(ZulipIcons.edit, skipOffstage: false));
1725+
matching: find.byIcon(ZulipIcons.edit, skipOffstage: false),
1726+
);
17261727
await tester.ensureVisible(findEditButton);
17271728
if (fetchShouldSucceed) {
17281729
connection.prepare(delay: delay,
@@ -1862,10 +1863,18 @@ void main() {
18621863
await tester.pump();
18631864
check(state).controller.content.text.equals('composing something');
18641865
});
1865-
1866-
testWidgets('interrupting message edit: proceed through confirmation dialog', (tester) async {
1867-
await prepareMessageNotSent(tester, narrow: topicNarrow);
1868-
1866+
testWidgets('interrupting message edit: proceed through confirmation dialog', (WidgetTester tester) async {
1867+
final TransitionDurationObserver observer = TransitionDurationObserver();
1868+
1869+
await tester.pumpWidget(
1870+
MaterialApp(
1871+
navigatorObservers: <NavigatorObserver>[observer],
1872+
home: Scaffold(
1873+
body: Builder(
1874+
builder: (context) {
1875+
prepareMessageNotSent(tester, narrow: topicNarrow);
1876+
return const SizedBox.shrink();},
1877+
))));
18691878
final messageToEdit = eg.streamMessage(
18701879
sender: eg.selfUser, stream: channel, topic: topic,
18711880
content: 'message to edit');
@@ -1875,38 +1884,46 @@ void main() {
18751884
await startEditInteractionFromActionSheet(tester, messageId: messageToEdit.id,
18761885
originalRawContent: 'message to edit',
18771886
delay: Duration.zero);
1878-
await tester.pump(const Duration(milliseconds: 250)); // bottom-sheet animation
1887+
await observer.pumpPastTransition(tester);// bottom-sheet animation
18791888

18801889
await tester.tap(failedMessageFinder);
18811890
await tester.pump();
18821891
check(state).controller.content.text.equals('message to edit');
18831892

1884-
await expectAndHandleDiscardForMessageNotSentConfirmation(tester,
1885-
shouldContinue: true);
1893+
await expectAndHandleDiscardForMessageNotSentConfirmation(tester, shouldContinue: true);
18861894
await tester.pump();
18871895
check(state).controller.content.text.equals(failedMessageContent);
18881896
});
18891897

1890-
testWidgets('interrupting message edit: cancel confirmation dialog', (tester) async {
1891-
await prepareMessageNotSent(tester, narrow: topicNarrow);
1892-
1898+
testWidgets('interrupting message edit: cancel confirmation dialog', (WidgetTester tester) async {
1899+
final TransitionDurationObserver observer = TransitionDurationObserver();
1900+
1901+
await tester.pumpWidget(
1902+
MaterialApp(
1903+
navigatorObservers: <NavigatorObserver>[observer],
1904+
home: Scaffold(
1905+
body: Builder(
1906+
builder: (context) {
1907+
prepareMessageNotSent(tester, narrow: topicNarrow);
1908+
return const SizedBox.shrink();},
1909+
))));
18931910
final messageToEdit = eg.streamMessage(
1894-
sender: eg.selfUser, stream: channel, topic: topic,
1895-
content: 'message to edit');
1911+
sender: eg.selfUser,stream: channel, topic: topic,
1912+
content: 'message to edit'
1913+
);
18961914
await store.addMessage(messageToEdit);
18971915
await tester.pump();
18981916

18991917
await startEditInteractionFromActionSheet(tester, messageId: messageToEdit.id,
19001918
originalRawContent: 'message to edit',
19011919
delay: Duration.zero);
1902-
await tester.pump(const Duration(milliseconds: 250)); // bottom-sheet animation
1920+
await observer.pumpPastTransition(tester); // bottom-sheet animation
19031921

19041922
await tester.tap(failedMessageFinder);
19051923
await tester.pump();
19061924
check(state).controller.content.text.equals('message to edit');
19071925

1908-
await expectAndHandleDiscardForMessageNotSentConfirmation(tester,
1909-
shouldContinue: false);
1926+
await expectAndHandleDiscardForMessageNotSentConfirmation(tester, shouldContinue: false);
19101927
await tester.pump();
19111928
check(state).controller.content.text.equals('message to edit');
19121929
});

test/widgets/emoji_reaction_test.dart

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -434,8 +434,7 @@ void main() {
434434
// request the message action sheet
435435
await tester.longPress(find.byType(MessageContent));
436436
// sheet appears onscreen; default duration of bottom-sheet enter animation
437-
await tester.pump(const Duration(milliseconds: 250));
438-
437+
await transitionDurationObserver.pumpPastTransition(tester);
439438
await store.handleEvent(RealmEmojiUpdateEvent(id: 1, realmEmoji: {
440439
'1': eg.realmEmojiItem(emojiCode: '1', emojiName: 'buzzing'),
441440
}));

0 commit comments

Comments
 (0)