-
Notifications
You must be signed in to change notification settings - Fork 373
test: Get route-transition duration robustly,instead of hard-coding #1920
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
2ea25f6 to
0de6501
Compare
|
Thanks. Some of these changes look good, but there are other places where a lot more code is getting changed and it's not obvious what the reasons for those changes are. That makes it considerably more work for someone to review, because they have to read through all those changes and reverse-engineer what your intent is. Please take a look at our guide to writing a clean commit history:
|
bfa6bb4 to
7d9283f
Compare
|
@gnprice I guess it's fine now. |
|
This is improved, but there are still some places like this:
For example: - testWidgets('can show snackbar on success', (tester) async {
- // Regression test for: https://github.com/zulip/zulip-flutter/issues/732
- testBinding.deviceInfoResult = const IosDeviceInfo(systemVersion: '16.0');
-
- final message = eg.streamMessage();
- await setupToMessageActionSheet(tester, message: message, narrow: TopicNarrow.ofMessage(messa
ge));
+ testWidgets('can show snackbar on success', (WidgetTester tester) async {
+ // Regression test for: https://github.com/zulip/zulip-flutter/issues/732
+ final TransitionDurationObserver transitionDurationObserver = TransitionDurationObserver();
+ await tester.pumpWidget(
+ MaterialApp(
+ navigatorObservers: <NavigatorObserver>[transitionDurationObserver],
+ home: Scaffold(
+ body: Builder(
+ builder: (context) {
+ testBinding.deviceInfoResult = const IosDeviceInfo(systemVersion: '16.0');
+ final message = eg.streamMessage();
+ setupToMessageActionSheet(tester,message: message,narrow: TopicNarrow.ofMessage(messa
ge));
+ return const SizedBox.shrink();}
+ ))));
+ final message = eg.streamMessage();
+ // Make the request take a bit of time to complete
+ prepareRawContentResponseSuccess(message: message,rawContent: 'Hello world',delay: const Durati
on(milliseconds: 500),
+ );
+ await tapCopyMessageTextButton(tester);
+ // … and pump a frame to finish the NavigationState.pop animation…
+ await transitionDurationObserver.pumpPastTransition(tester);
+ // … before the request finishes. This is the repro condition for #732.
+ await transitionDurationObserver.pumpPastTransition(tester);
- // Make the request take a bit of time to complete…
- prepareRawContentResponseSuccess(message: message, rawContent: 'Hello world',
- 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));
- // … before the request finishes. This is the repro condition for #732.
- await tester.pump(const Duration(milliseconds: 250));
+ final snackbar = tester.widget<SnackBar>(find.byType(SnackBar));
+ check(snackbar.behavior).equals(SnackBarBehavior.floating);
- final snackbar = tester.widget<SnackBar>(find.byType(SnackBar));
- check(snackbar.behavior).equals(SnackBarBehavior.floating);
- final zulipLocalizations = GlobalLocalizations.zulipLocalizations;
- tester.widget(find.descendant(matchRoot: true,
+ final zulipLocalizations = GlobalLocalizations.zulipLocalizations;
+ tester.widget(find.descendant(matchRoot: true,
of: find.byWidget(snackbar.content),
- matching: find.text(zulipLocalizations.successMessageTextCopied)));
- });
+ matching: find.text(zulipLocalizations.successMessageTextCopied),
+ ));
+ });
+Take a look again at the changes in your PR. Use
|
|
@gnprice done. Followed this flutter/flutter#171109 coding convention as suggested here #1668, otherwise the tests kept failing. fixed indentation mismatch related diffs(mostly). |
7c59555 to
af69cbf
Compare
|
This revision is somewhat improved again, but there are still some irrelevant changes, and still some places where more code is getting changed and it's not clear exactly why. If you need help in doing this:
then the #git-help channel on chat.zulip.org is a good place to ask.
Why mostly and not entirely?
I don't understand this comment. #1668 is the issue this PR is meant to fix, so in general these changes should be in the direction called for by that issue. If you're encountering test failures that you don't understand the cause of, then the #mobile-dev-help channel is the best venue to ask about them. |
3ade4ff to
8d848b1
Compare
|
@gnprice cleaned up the pr. added await transitionDurationObserver.pumpPastTransition(tester);
// … before the request finishes. This is the repro condition for #732.
await transitionDurationObserver.pumpPastTransition(tester);
// …pump for snackbar to show
await tester.pumpAndSettle();though Also, in Future<void> showFromInbox(WidgetTester tester) async {
transitionDurationObserver = TransitionDurationObserver();
await tester.pumpWidget(TestZulipApp(accountId: eg.selfAccount.id,
navigatorObservers: [transitionDurationObserver],
child: const HomePage()));
await tester.pump();
check(find.byType(InboxPageBody)).findsOne();
await tester.longPress(find.text(someChannel.name).hitTestable());
await transitionDurationObserver.pumpPastTransition(tester);
}but in Future<void> showFromTopicListAppBar(WidgetTester tester, {int? streamId}) async {
streamId ??= someChannel.streamId;
final transitionDurationObserver = TransitionDurationObserver();
connection.prepare(json: GetStreamTopicsResult(topics: []).toJson());
await tester.pumpWidget(TestZulipApp(
navigatorObservers: [transitionDurationObserver],
accountId: eg.selfAccount.id,
child: TopicListPage(streamId: streamId)));
await tester.pump();
.......both works but I followed |
|
@gnprice have a look. |
|
Cool, this version seems clear enough for a review. Please edit the commit message and PR description so it doesn't say it fixes #1668 yet, though. This covers some of the places that need to change but not all of them. (But let's not try to put more of them into this first PR — we can save them for a subsequent PR after you've gotten feedback on this one.) |
|
@gnprice done. |
chrisbobbe
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks! Comments below.
Some of the commit-message bodies are a bit messy, as though you did some quick copy-and-paste without checking for space after punctuation, etc., and without wrapping to 68 columns. Please clean those up. 🙂
| // sheet appears onscreen; default duration of bottom-sheet enter animation | ||
| await tester.pump(const Duration(milliseconds: 250)); | ||
| await transitionDurationObserver.pumpPastTransition(tester); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In the code comment, the part after the semicolon ";" doesn't refer to anything; remove it. (Here and in similar comments on code touched in this PR.)
test/widgets/action_sheet_test.dart
Outdated
| await tester.pump(const Duration(milliseconds: 250)); | ||
| await transitionDurationObserver.pumpPastTransition(tester); | ||
| // …pump for snackbar to show | ||
| await tester.pumpAndSettle(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How long is the snackbar entrance animation? Ideally we would pump with exactly that duration, rather than using pumpAndSettle.
Replaces hardcoded transition delays with dynamic duration handling via transitionDurationObserver.pumpPastTransition(tester).
chrisbobbe
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks! One comment below.
test/widgets/action_sheet_test.dart
Outdated
| await tester.pump(const Duration(milliseconds: 250)); | ||
| await transitionDurationObserver.pumpPastTransition(tester); | ||
| // … pump for snackbar to show | ||
| await transitionDurationObserver.pumpPastTransition(tester); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah: looking at the story of this test, I think the last two of these pumpPastTransition calls aren't actually desired.
The first 250ms pump was a route transition, as its comment says:
// … and pump a frame to finish the NavigationState.pop animation…
await tester.pump(const Duration(milliseconds: 250));So we do want to convert that to use pumpPastTransition.
But the second 250ms pump is about pumping through the remainder of a 500ms API-request delay prepared above:
// Make the request take a bit of time to complete…
prepareRawContentResponseSuccess(message: message, rawContent: 'Hello world',
delay: const Duration(milliseconds: 500));So that's not about a route transition, and we shouldn't use pumpPastTransition there.
And from a quick check of the snackbar code, its appearance isn't implemented as a route transition, so we don't want pumpPastTransition for that either. It looks like the snackbar animation duration is 250ms by default, but that value isn't part of the snackbar code's public API; it's in a private variable, along with the default display duration:
const Duration _snackBarTransitionDuration = Duration(milliseconds: 250);
const Duration _snackBarDisplayDuration = Duration(milliseconds: 4000);The goal of the test is to check on the snackbar at some point while it's on the screen, right; how about the following:
// Make the request take a bit of time to complete…
prepareRawContentResponseSuccess(message: message, rawContent: 'Hello world',
delay: const Duration(milliseconds: 500));
await tapCopyMessageTextButton(tester);
// … and pump a frame to finish the NavigationState.pop animation…
await transitionDurationObserver.pumpPastTransition(tester);
// … before the request finishes and the snackbar shows.
// This is the repro condition for #732.
await tester.pump(Duration(milliseconds: 500));
// (Default duration of the snackbar entrance animation)
await tester.pump(Duration(milliseconds: 250));There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done. Thanks for the explanation.
Replaces hardcoded transition delays with dynamic duration handling via transitionDurationObserver.pumpPastTransition(tester). Attaches TransitionDurationObserver through navigatorObservers in test widgets to dynamically track transition durations.
Adds TransitionDurationObserver initialization inside the prepareComposeBox setup. Every test that calls prepareComposeBox now automatically attaches an observer to the widget tree. Replaces hardcoded transition delays with dynamic duration handling via transitionDurationObserver.pumpPastTransition(tester).
|
Thanks! LGTM, marking for Greg's review. |
| Future<void> showFromSubscriptionList(WidgetTester tester) async { | ||
| transitionDurationObserver = TransitionDurationObserver(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm — it seems awfully messy for there to be so many different functions that are setting this shared variable. When does it need to get set? How did you confirm for yourself that you've set it in all of the places it needs to get set in?
In short, this setup seems likely to cause bugs.
| // sheet appears onscreen; default duration of bottom-sheet enter animation | ||
| await tester.pump(const Duration(milliseconds: 250)); | ||
| // sheet appears onscreen | ||
| await transitionDurationObserver.pumpPastTransition(tester); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In this instance, we're using transitionDurationObserver and it appears to work, even though a few lines above here there was a pumpWidget(TestZulipApp(… and it didn't pass navigatorObservers.
Does that mean we don't need to set navigatorObservers after all in the other "showFoo" functions where this PR adds it? Or, conversely, is it a bug that we're not setting it here?
| // … before the request finishes. This is the repro condition for #732. | ||
| await tester.pump(const Duration(milliseconds: 250)); | ||
| await tester.pump(Duration(milliseconds: 500)); | ||
| // … pump for snackbar to show; default duration of snackbar enter animation | ||
| await tester.pump(Duration(milliseconds: 250)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What's this change about? (And what does the comment mean? It doesn't seem to make any sense syntactically — this new comment line starts with a "…" as if it's continuing something, but the previous comment ends with a "." and the end of a sentence.)
Work towards #1668