Skip to content

Conversation

@justinmc
Copy link
Contributor

@justinmc justinmc commented Jun 24, 2025

We need a robust way to get the duration of a route transition in tests, so that tests can remain independent of the type of route transition and its duration.

With this PR, this will be the canonical way to pump until a page transition has finished:

testWidgets('example', (WidgetTester tester) async {
  final TransitionDurationObserver observer = TransitionDurationObserver();

  await tester.pumpWidget(
    MaterialApp(
      navigatorObservers: <NavigatorObserver>[observer],
      onGenerateRoute: (RouteSettings settings) { ... },
    ),
  );

  expect(find.text('Page 1'), findsOneWidget);
  expect(find.text('Page 2'), findsNothing);

  // Pump through the whole transition.
  await tester.tap(find.text('Next'));
  await observer.pumpPastTransition(tester);

  expect(find.text('Page 1'), findsNothing);
  expect(find.text('Page 2'), findsOneWidget);

  // Or, pump through part of a transition with the duration.
  await tester.tap(find.text('Back'));
  await tester.pump(observer.transitionDuration ~/ 2);

  expect(find.text('Page 1'), findsOneWidget);
  expect(find.text('Page 2'), findsOneWidget);
});

This was spun out of #165832, where updating the default route transition and its duration broke tests in the framework, in customer tests, and in Google tests.

FYI @chrisbobbe

justinmc added 4 commits June 24, 2025 13:23
E.g. when popping, the duration of the incoming route is used. In
general, it uses the same duration forwards and backwards.
@justinmc justinmc requested review from dkwingsmt and gnprice June 24, 2025 20:30
@justinmc justinmc self-assigned this Jun 24, 2025
@github-actions github-actions bot added a: tests "flutter test", flutter_test, or one of our tests framework flutter/packages/flutter repository. See also f: labels. f: material design flutter/packages/flutter/material repository. d: api docs Issues with https://api.flutter.dev/ d: examples Sample code and demos f: routes Navigator, Router, and related APIs. labels Jun 24, 2025
@gnprice
Copy link
Member

gnprice commented Jun 25, 2025

Great! That API looks quite clean, except for the somewhat mysterious need for the extra millisecond — do you understand why that's necessary?

I believe that need isn't new, but it sticks out more after this change — previously we'd just fudge what constant to put there, like 300ms when the transition duration itself is 250ms.

(I'm at Fluttercon now, so may not be able to give this a more detailed look until I'm back next week.)

@dkwingsmt
Copy link
Contributor

I agree with @gnprice. If the 1ms is needed and will be used often, maybe we can define a special getter for it, such as:

  Duration get transitionDurationWithPadding {
    return transitionDuration + const Duration(milliseconds: 1);
  }

And therefore the extra duration can be explained in a centralized doc.

@github-actions github-actions bot removed the f: material design flutter/packages/flutter/material repository. label Jul 11, 2025
@justinmc
Copy link
Contributor Author

@gnprice @dkwingsmt I added pumpPastTransition and documented why exactly that's needed. Let me know what you guys think.

Copy link
Contributor

@dkwingsmt dkwingsmt left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM. Love the name!

@justinmc justinmc added the autosubmit Merge PR when tree becomes green via auto submit App label Jul 14, 2025
@auto-submit auto-submit bot added this pull request to the merge queue Jul 14, 2025
Merged via the queue into flutter:master with commit 9b93519 Jul 14, 2025
72 of 73 checks passed
@flutter-dashboard flutter-dashboard bot removed the autosubmit Merge PR when tree becomes green via auto submit App label Jul 14, 2025
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Jul 15, 2025
@justinmc justinmc deleted the transition-duration-observer branch July 15, 2025 16:54
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Jul 15, 2025
auto-submit bot pushed a commit to flutter/packages that referenced this pull request Jul 15, 2025
flutter/flutter@a930ec1...cc3110c

2025-07-15 [email protected] feat: Tag Fuchsia artifacts by content hash (flutter/flutter#172132)
2025-07-15 [email protected] Marks Linux_android_emu native_assets_android to be unflaky (flutter/flutter#171145)
2025-07-15 [email protected] [ Tool ] Fix `flutter upgrade` stating that an upgrade is available on `main` when up to date (flutter/flutter#172141)
2025-07-15 [email protected] Reland "Add feature flags to the framework" (flutter/flutter#171545)
2025-07-14 [email protected] chore: unskip tests cases (flutter/flutter#172031)
2025-07-14 [email protected] Route transition duration (flutter/flutter#171109)
2025-07-14 [email protected] [Impeller] libImpeller: Correctly release mappings created using the C++ API wrapper. (flutter/flutter#172136)
2025-07-14 [email protected] Roll Skia from 5f7adef2ac25 to 2f4ad5d83704 (3 revisions) (flutter/flutter#172134)
2025-07-14 [email protected] Migrate to arm based firebase test devices for api 26 and 27 (flutter/flutter#172128)
2025-07-14 [email protected] [web] Cleanup unnecessary dart defines and renderer in web tests (flutter/flutter#172130)
2025-07-14 [email protected] Use granular skparagraph targets (flutter/flutter#161676)
2025-07-14 [email protected] [ Widget Preview ] Initial work to support reacting to IDE events (flutter/flutter#172040)
2025-07-14 [email protected] Roll Skia from e95c92d867b5 to 5f7adef2ac25 (8 revisions) (flutter/flutter#172123)
2025-07-14 [email protected] [skia] Set GN flags explicitly for fuchsia build (flutter/flutter#172104)
2025-07-14 [email protected] fix: documentation around led launch broken (flutter/flutter#171983)
2025-07-14 [email protected] [ Tool ] Downgrade and pin DDS to 5.0.3 (flutter/flutter#172120)
2025-07-14 [email protected] Apply superellipse clipping to iOS platform views using an approximated round rect (flutter/flutter#172033)
2025-07-14 [email protected] [Impeller] Fix broken image links in documentation. (flutter/flutter#171465)
2025-07-14 [email protected] remove `x86` in CI  builder linux_android_emulator (flutter/flutter#170964)
2025-07-14 [email protected] remove `x86` in flutter_gdb (flutter/flutter#170966)
2025-07-14 [email protected] fix android studio lint about lambda function (flutter/flutter#172063)
2025-07-14 [email protected] Roll Fuchsia Linux SDK from qw0YTtPhosk3-rr4h... to tQAtsLtpc0oBIqRwC... (flutter/flutter#172116)
2025-07-14 [email protected] Roll Skia from 92354f64e37f to e95c92d867b5 (1 revision) (flutter/flutter#172111)
2025-07-14 [email protected] [web] Delete unused files in the engine (flutter/flutter#172035)

If this roll has caused a breakage, revert this CL and stop the roller
using the controls here:
https://autoroll.skia.org/r/flutter-packages
Please CC [email protected],[email protected] on the revert to ensure that a human
is aware of the problem.

To file a bug in Packages: https://github.com/flutter/flutter/issues/new/choose

To report a problem with the AutoRoller itself, please file a bug:
https://issues.skia.org/issues/new?component=1389291&template=1850622

Documentation for the AutoRoller is here:
https://skia.googlesource.com/buildbot/+doc/main/autoroll/README.md
azatech pushed a commit to azatech/flutter that referenced this pull request Jul 28, 2025
We need a robust way to get the duration of a route transition in tests,
so that tests can remain independent of the type of route transition and
its duration.

With this PR, this will be the canonical way to pump until a page
transition has finished:

```dart
testWidgets('example', (WidgetTester tester) async {
  final TransitionDurationObserver observer = TransitionDurationObserver();

  await tester.pumpWidget(
    MaterialApp(
      navigatorObservers: <NavigatorObserver>[observer],
      onGenerateRoute: (RouteSettings settings) { ... },
    ),
  );

  expect(find.text('Page 1'), findsOneWidget);
  expect(find.text('Page 2'), findsNothing);

  // Pump through the whole transition.
  await tester.tap(find.text('Next'));
  await observer.pumpPastTransition(tester);

  expect(find.text('Page 1'), findsNothing);
  expect(find.text('Page 2'), findsOneWidget);

  // Or, pump through part of a transition with the duration.
  await tester.tap(find.text('Back'));
  await tester.pump(observer.transitionDuration ~/ 2);

  expect(find.text('Page 1'), findsOneWidget);
  expect(find.text('Page 2'), findsOneWidget);
});
```

This was spun out of flutter#165832,
where updating the default route transition and its duration broke tests
in the framework, in customer tests, and in Google tests.

FYI @chrisbobbe

---------

Co-authored-by: Jing Shao <[email protected]>
gnprice added a commit to gnprice/zulip-flutter that referenced this pull request Jul 28, 2025
And update Flutter's supporting libraries to match.

In particular this gets us TransitionDurationObserver:
  flutter/flutter#171109

We stop just before a certain Dart SDK roll:
  flutter/flutter@fa80cbcbdbdd
because that commit breaks completion in the IDE, which would be
pretty annoying for doing development.  Thanks to Sayed for
spotting that breakage and bisecting it to that commit:
  zulip#1755 (comment)
  https://chat.zulip.org/#narrow/channel/516-mobile-dev-help/topic/New.20Flutter.20upgrade.20degrades.20code.20autocompletion/near/2230721
gnprice added a commit to gnprice/zulip-flutter that referenced this pull request Jul 28, 2025
And update Flutter's supporting libraries to match.

In particular this gets us TransitionDurationObserver:
  flutter/flutter#171109

We stop just before a certain Dart SDK roll:
  flutter/flutter@fa80cbcbdbdd
because that commit breaks completion in the IDE, which would be
pretty annoying for doing development.  Thanks to Sayed for
spotting that breakage and bisecting it to that commit:
  zulip#1755 (comment)
  https://chat.zulip.org/#narrow/channel/516-mobile-dev-help/topic/New.20Flutter.20upgrade.20degrades.20code.20autocompletion/near/2230721
chrisbobbe pushed a commit to chrisbobbe/zulip-flutter that referenced this pull request Jul 29, 2025
And update Flutter's supporting libraries to match.

In particular this gets us TransitionDurationObserver:
  flutter/flutter#171109

We stop just before a certain Dart SDK roll:
  flutter/flutter@fa80cbcbdbdd
because that commit breaks completion in the IDE, which would be
pretty annoying for doing development.  Thanks to Sayed for
spotting that breakage and bisecting it to that commit:
  zulip#1755 (comment)
  https://chat.zulip.org/#narrow/channel/516-mobile-dev-help/topic/New.20Flutter.20upgrade.20degrades.20code.20autocompletion/near/2230721
gnprice added a commit to gnprice/zulip-flutter that referenced this pull request Jul 29, 2025
And update Flutter's supporting libraries to match.

In particular this gets us TransitionDurationObserver:
  flutter/flutter#171109

We stop just before a certain Dart SDK roll:
  flutter/flutter@fa80cbcbdbdd
because that commit breaks completion in the IDE, which would be
pretty annoying for doing development.  Thanks to Sayed for
spotting that breakage and bisecting it to that commit:
  zulip#1755 (comment)
  https://chat.zulip.org/#narrow/channel/516-mobile-dev-help/topic/New.20Flutter.20upgrade.20degrades.20code.20autocompletion/near/2230721
gnprice added a commit to gnprice/zulip-flutter that referenced this pull request Jul 29, 2025
And update Flutter's supporting libraries to match.

In particular this gets us TransitionDurationObserver:
  flutter/flutter#171109

We stop just before a certain Dart SDK roll:
  flutter/flutter@fa80cbcbdbdd
because that commit breaks completion in the IDE, which would be
pretty annoying for doing development.  Thanks to Sayed for
spotting that breakage and bisecting it to that commit:
  zulip#1755 (comment)
  https://chat.zulip.org/#narrow/channel/516-mobile-dev-help/topic/New.20Flutter.20upgrade.20degrades.20code.20autocompletion/near/2230721
vashworth pushed a commit to vashworth/packages that referenced this pull request Jul 30, 2025
…r#9631)

flutter/flutter@a930ec1...cc3110c

2025-07-15 [email protected] feat: Tag Fuchsia artifacts by content hash (flutter/flutter#172132)
2025-07-15 [email protected] Marks Linux_android_emu native_assets_android to be unflaky (flutter/flutter#171145)
2025-07-15 [email protected] [ Tool ] Fix `flutter upgrade` stating that an upgrade is available on `main` when up to date (flutter/flutter#172141)
2025-07-15 [email protected] Reland "Add feature flags to the framework" (flutter/flutter#171545)
2025-07-14 [email protected] chore: unskip tests cases (flutter/flutter#172031)
2025-07-14 [email protected] Route transition duration (flutter/flutter#171109)
2025-07-14 [email protected] [Impeller] libImpeller: Correctly release mappings created using the C++ API wrapper. (flutter/flutter#172136)
2025-07-14 [email protected] Roll Skia from 5f7adef2ac25 to 2f4ad5d83704 (3 revisions) (flutter/flutter#172134)
2025-07-14 [email protected] Migrate to arm based firebase test devices for api 26 and 27 (flutter/flutter#172128)
2025-07-14 [email protected] [web] Cleanup unnecessary dart defines and renderer in web tests (flutter/flutter#172130)
2025-07-14 [email protected] Use granular skparagraph targets (flutter/flutter#161676)
2025-07-14 [email protected] [ Widget Preview ] Initial work to support reacting to IDE events (flutter/flutter#172040)
2025-07-14 [email protected] Roll Skia from e95c92d867b5 to 5f7adef2ac25 (8 revisions) (flutter/flutter#172123)
2025-07-14 [email protected] [skia] Set GN flags explicitly for fuchsia build (flutter/flutter#172104)
2025-07-14 [email protected] fix: documentation around led launch broken (flutter/flutter#171983)
2025-07-14 [email protected] [ Tool ] Downgrade and pin DDS to 5.0.3 (flutter/flutter#172120)
2025-07-14 [email protected] Apply superellipse clipping to iOS platform views using an approximated round rect (flutter/flutter#172033)
2025-07-14 [email protected] [Impeller] Fix broken image links in documentation. (flutter/flutter#171465)
2025-07-14 [email protected] remove `x86` in CI  builder linux_android_emulator (flutter/flutter#170964)
2025-07-14 [email protected] remove `x86` in flutter_gdb (flutter/flutter#170966)
2025-07-14 [email protected] fix android studio lint about lambda function (flutter/flutter#172063)
2025-07-14 [email protected] Roll Fuchsia Linux SDK from qw0YTtPhosk3-rr4h... to tQAtsLtpc0oBIqRwC... (flutter/flutter#172116)
2025-07-14 [email protected] Roll Skia from 92354f64e37f to e95c92d867b5 (1 revision) (flutter/flutter#172111)
2025-07-14 [email protected] [web] Delete unused files in the engine (flutter/flutter#172035)

If this roll has caused a breakage, revert this CL and stop the roller
using the controls here:
https://autoroll.skia.org/r/flutter-packages
Please CC [email protected],[email protected] on the revert to ensure that a human
is aware of the problem.

To file a bug in Packages: https://github.com/flutter/flutter/issues/new/choose

To report a problem with the AutoRoller itself, please file a bug:
https://issues.skia.org/issues/new?component=1389291&template=1850622

Documentation for the AutoRoller is here:
https://skia.googlesource.com/buildbot/+doc/main/autoroll/README.md
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Aug 14, 2025
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Aug 14, 2025
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Aug 15, 2025
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Aug 15, 2025
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Aug 16, 2025
ksokolovskyi pushed a commit to ksokolovskyi/flutter that referenced this pull request Aug 19, 2025
We need a robust way to get the duration of a route transition in tests,
so that tests can remain independent of the type of route transition and
its duration.

With this PR, this will be the canonical way to pump until a page
transition has finished:

```dart
testWidgets('example', (WidgetTester tester) async {
  final TransitionDurationObserver observer = TransitionDurationObserver();

  await tester.pumpWidget(
    MaterialApp(
      navigatorObservers: <NavigatorObserver>[observer],
      onGenerateRoute: (RouteSettings settings) { ... },
    ),
  );

  expect(find.text('Page 1'), findsOneWidget);
  expect(find.text('Page 2'), findsNothing);

  // Pump through the whole transition.
  await tester.tap(find.text('Next'));
  await observer.pumpPastTransition(tester);

  expect(find.text('Page 1'), findsNothing);
  expect(find.text('Page 2'), findsOneWidget);

  // Or, pump through part of a transition with the duration.
  await tester.tap(find.text('Back'));
  await tester.pump(observer.transitionDuration ~/ 2);

  expect(find.text('Page 1'), findsOneWidget);
  expect(find.text('Page 2'), findsOneWidget);
});
```

This was spun out of flutter#165832,
where updating the default route transition and its duration broke tests
in the framework, in customer tests, and in Google tests.

FYI @chrisbobbe

---------

Co-authored-by: Jing Shao <[email protected]>
mboetger pushed a commit to mboetger/flutter that referenced this pull request Sep 18, 2025
We need a robust way to get the duration of a route transition in tests,
so that tests can remain independent of the type of route transition and
its duration.

With this PR, this will be the canonical way to pump until a page
transition has finished:

```dart
testWidgets('example', (WidgetTester tester) async {
  final TransitionDurationObserver observer = TransitionDurationObserver();

  await tester.pumpWidget(
    MaterialApp(
      navigatorObservers: <NavigatorObserver>[observer],
      onGenerateRoute: (RouteSettings settings) { ... },
    ),
  );

  expect(find.text('Page 1'), findsOneWidget);
  expect(find.text('Page 2'), findsNothing);

  // Pump through the whole transition.
  await tester.tap(find.text('Next'));
  await observer.pumpPastTransition(tester);

  expect(find.text('Page 1'), findsNothing);
  expect(find.text('Page 2'), findsOneWidget);

  // Or, pump through part of a transition with the duration.
  await tester.tap(find.text('Back'));
  await tester.pump(observer.transitionDuration ~/ 2);

  expect(find.text('Page 1'), findsOneWidget);
  expect(find.text('Page 2'), findsOneWidget);
});
```

This was spun out of flutter#165832,
where updating the default route transition and its duration broke tests
in the framework, in customer tests, and in Google tests.

FYI @chrisbobbe

---------

Co-authored-by: Jing Shao <[email protected]>
lucaantonelli pushed a commit to lucaantonelli/flutter that referenced this pull request Nov 21, 2025
We need a robust way to get the duration of a route transition in tests,
so that tests can remain independent of the type of route transition and
its duration.

With this PR, this will be the canonical way to pump until a page
transition has finished:

```dart
testWidgets('example', (WidgetTester tester) async {
  final TransitionDurationObserver observer = TransitionDurationObserver();

  await tester.pumpWidget(
    MaterialApp(
      navigatorObservers: <NavigatorObserver>[observer],
      onGenerateRoute: (RouteSettings settings) { ... },
    ),
  );

  expect(find.text('Page 1'), findsOneWidget);
  expect(find.text('Page 2'), findsNothing);

  // Pump through the whole transition.
  await tester.tap(find.text('Next'));
  await observer.pumpPastTransition(tester);

  expect(find.text('Page 1'), findsNothing);
  expect(find.text('Page 2'), findsOneWidget);

  // Or, pump through part of a transition with the duration.
  await tester.tap(find.text('Back'));
  await tester.pump(observer.transitionDuration ~/ 2);

  expect(find.text('Page 1'), findsOneWidget);
  expect(find.text('Page 2'), findsOneWidget);
});
```

This was spun out of flutter#165832,
where updating the default route transition and its duration broke tests
in the framework, in customer tests, and in Google tests.

FYI @chrisbobbe

---------

Co-authored-by: Jing Shao <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

a: tests "flutter test", flutter_test, or one of our tests d: api docs Issues with https://api.flutter.dev/ d: examples Sample code and demos f: routes Navigator, Router, and related APIs. framework flutter/packages/flutter repository. See also f: labels.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants