// Copyright 2014 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// @dart = 2.8

import 'dart:ui';

import 'package:flutter/foundation.dart';
import 'package:flutter/scheduler.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:flutter/material.dart';

import 'observer_tester.dart';
import 'semantics_tester.dart';

class FirstWidget extends StatelessWidget {
  const FirstWidget({ Key key }) : super(key: key);
  @override
  Widget build(BuildContext context) {
    return GestureDetector(
      onTap: () {
        Navigator.pushNamed(context, '/second');
      },
      child: Container(
        color: const Color(0xFFFFFF00),
        child: const Text('X'),
      ),
    );
  }
}

class SecondWidget extends StatefulWidget {
  const SecondWidget({ Key key }) : super(key: key);
  @override
  SecondWidgetState createState() => SecondWidgetState();
}

class SecondWidgetState extends State<SecondWidget> {
  @override
  Widget build(BuildContext context) {
    return GestureDetector(
      onTap: () => Navigator.pop(context),
      child: Container(
        color: const Color(0xFFFF00FF),
        child: const Text('Y'),
      ),
    );
  }
}

typedef ExceptionCallback = void Function(dynamic exception);

class ThirdWidget extends StatelessWidget {
  const ThirdWidget({ Key key, this.targetKey, this.onException }) : super(key: key);

  final Key targetKey;
  final ExceptionCallback onException;

  @override
  Widget build(BuildContext context) {
    return GestureDetector(
      key: targetKey,
      onTap: () {
        try {
          Navigator.of(context);
        } catch (e) {
          onException(e);
        }
      },
      behavior: HitTestBehavior.opaque,
    );
  }
}

class OnTapPage extends StatelessWidget {
  const OnTapPage({ Key key, this.id, this.onTap }) : super(key: key);

  final String id;
  final VoidCallback onTap;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('Page $id')),
      body: GestureDetector(
        onTap: onTap,
        behavior: HitTestBehavior.opaque,
        child: Container(
          child: Center(
            child: Text(id, style: Theme.of(context).textTheme.headline3),
          ),
        ),
      ),
    );
  }
}

class SlideInOutPageRoute<T> extends PageRouteBuilder<T> {
  SlideInOutPageRoute({WidgetBuilder bodyBuilder, RouteSettings settings}) : super(
    settings: settings,
    pageBuilder: (BuildContext context, Animation<double> animation, Animation<double> secondaryAnimation) => bodyBuilder(context),
    transitionsBuilder: (BuildContext context, Animation<double> animation, Animation<double> secondaryAnimation, Widget child) {
        return SlideTransition(
          position: Tween<Offset>(
            begin: const Offset(1.0, 0),
            end: Offset.zero,
          ).animate(animation),
          child: SlideTransition(
            position: Tween<Offset>(
              begin: Offset.zero,
              end: const Offset(-1.0, 0),
            ).animate(secondaryAnimation),
            child: child,
          ),
        );
      },
  );

  @override
  AnimationController get controller => super.controller;
}

void main() {
  testWidgets('Can navigator navigate to and from a stateful widget', (WidgetTester tester) async {
    final Map<String, WidgetBuilder> routes = <String, WidgetBuilder>{
      '/': (BuildContext context) => const FirstWidget(), // X
      '/second': (BuildContext context) => const SecondWidget(), // Y
    };

    await tester.pumpWidget(MaterialApp(routes: routes));
    expect(find.text('X'), findsOneWidget);
    expect(find.text('Y', skipOffstage: false), findsNothing);

    await tester.tap(find.text('X'));
    await tester.pump();
    expect(find.text('X'), findsOneWidget);
    expect(find.text('Y', skipOffstage: false), isOffstage);

    await tester.pump(const Duration(milliseconds: 10));
    expect(find.text('X'), findsOneWidget);
    expect(find.text('Y'), findsOneWidget);

    await tester.pump(const Duration(milliseconds: 10));
    expect(find.text('X'), findsOneWidget);
    expect(find.text('Y'), findsOneWidget);

    await tester.pump(const Duration(milliseconds: 10));
    expect(find.text('X'), findsOneWidget);
    expect(find.text('Y'), findsOneWidget);

    await tester.pump(const Duration(seconds: 1));
    expect(find.text('X'), findsNothing);
    expect(find.text('X', skipOffstage: false), findsOneWidget);
    expect(find.text('Y'), findsOneWidget);

    await tester.tap(find.text('Y'));
    expect(find.text('X'), findsNothing);
    expect(find.text('Y'), findsOneWidget);

    await tester.pump();
    await tester.pump();
    expect(find.text('X'), findsOneWidget);
    expect(find.text('Y'), findsOneWidget);

    await tester.pump(const Duration(milliseconds: 10));
    expect(find.text('X'), findsOneWidget);
    expect(find.text('Y'), findsOneWidget);

    await tester.pump(const Duration(seconds: 1));
    expect(find.text('X'), findsOneWidget);
    expect(find.text('Y', skipOffstage: false), findsNothing);
  });

  testWidgets('Navigator.of fails gracefully when not found in context', (WidgetTester tester) async {
    const Key targetKey = Key('foo');
    dynamic exception;
    final Widget widget = ThirdWidget(
      targetKey: targetKey,
      onException: (dynamic e) {
        exception = e;
      },
    );
    await tester.pumpWidget(widget);
    await tester.tap(find.byKey(targetKey));
    expect(exception, isFlutterError);
    expect('$exception', startsWith('Navigator operation requested with a context'));
  });

  testWidgets('Navigator.of rootNavigator finds root Navigator', (WidgetTester tester) async {
    await tester.pumpWidget(MaterialApp(
      home: Material(
        child: Column(
          children: <Widget>[
            const SizedBox(
              height: 300.0,
              child: Text('Root page'),
            ),
            SizedBox(
              height: 300.0,
              child: Navigator(
                onGenerateRoute: (RouteSettings settings) {
                  if (settings.name == '/') {
                    return MaterialPageRoute<void>(
                      builder: (BuildContext context) {
                        return ElevatedButton(
                          child: const Text('Next'),
                          onPressed: () {
                            Navigator.of(context).push(
                              MaterialPageRoute<void>(
                                builder: (BuildContext context) {
                                  return ElevatedButton(
                                    child: const Text('Inner page'),
                                    onPressed: () {
                                      Navigator.of(context, rootNavigator: true).push(
                                        MaterialPageRoute<void>(
                                          builder: (BuildContext context) {
                                            return const Text('Dialog');
                                          }
                                        ),
                                      );
                                    },
                                  );
                                }
                              ),
                            );
                          },
                        );
                      },
                    );
                  }
                  return null;
                },
              ),
            ),
          ],
        ),
      ),
    ));

    await tester.tap(find.text('Next'));
    await tester.pump();
    await tester.pump(const Duration(milliseconds: 300));

    // Both elements are on screen.
    expect(tester.getTopLeft(find.text('Root page')).dy, 0.0);
    expect(tester.getTopLeft(find.text('Inner page')).dy, greaterThan(300.0));

    await tester.tap(find.text('Inner page'));
    await tester.pump();
    await tester.pump(const Duration(milliseconds: 300));

    // Dialog is pushed to the whole page and is at the top of the screen, not
    // inside the inner page.
    expect(tester.getTopLeft(find.text('Dialog')).dy, 0.0);
  });

  testWidgets('Gestures between push and build are ignored', (WidgetTester tester) async {
    final List<String> log = <String>[];
    final Map<String, WidgetBuilder> routes = <String, WidgetBuilder>{
      '/': (BuildContext context) {
        return Row(
          children: <Widget>[
            GestureDetector(
              onTap: () {
                log.add('left');
                Navigator.pushNamed(context, '/second');
              },
              child: const Text('left'),
            ),
            GestureDetector(
              onTap: () { log.add('right'); },
              child: const Text('right'),
            ),
          ],
        );
      },
      '/second': (BuildContext context) => Container(),
    };
    await tester.pumpWidget(MaterialApp(routes: routes));
    expect(log, isEmpty);
    await tester.tap(find.text('left'));
    expect(log, equals(<String>['left']));
    await tester.tap(find.text('right'));
    expect(log, equals(<String>['left']));
  });

   testWidgets('Pending gestures are rejected', (WidgetTester tester) async {
     final List<String> log = <String>[];
     final Map<String, WidgetBuilder> routes = <String, WidgetBuilder>{
       '/': (BuildContext context) {
         return Row(
           children: <Widget>[
             GestureDetector(
               onTap: () {
                 log.add('left');
                 Navigator.pushNamed(context, '/second');
               },
               child: const Text('left')
             ),
             GestureDetector(
               onTap: () { log.add('right'); },
               child: const Text('right'),
             ),
           ]
         );
       },
       '/second': (BuildContext context) => Container(),
     };
     await tester.pumpWidget(MaterialApp(routes: routes));
     final TestGesture gesture = await tester.startGesture(tester.getCenter(find.text('right')), pointer: 23);
     expect(log, isEmpty);
     await tester.tap(find.text('left'));
     expect(log, equals(<String>['left']));
     await gesture.up();
     expect(log, equals(<String>['left']));
   }, skip: true); // https://github.com/flutter/flutter/issues/4771

  testWidgets('popAndPushNamed', (WidgetTester tester) async {
    final Map<String, WidgetBuilder> routes = <String, WidgetBuilder>{
      '/' : (BuildContext context) => OnTapPage(id: '/', onTap: () { Navigator.pushNamed(context, '/A'); }),
      '/A': (BuildContext context) => OnTapPage(id: 'A', onTap: () { Navigator.popAndPushNamed(context, '/B'); }),
      '/B': (BuildContext context) => OnTapPage(id: 'B', onTap: () { Navigator.pop(context); }),
    };

    await tester.pumpWidget(MaterialApp(routes: routes));
    expect(find.text('/'), findsOneWidget);
    expect(find.text('A', skipOffstage: false), findsNothing);
    expect(find.text('B', skipOffstage: false), findsNothing);

    await tester.tap(find.text('/'));
    await tester.pump();
    await tester.pump(const Duration(seconds: 1));
    expect(find.text('/'), findsNothing);
    expect(find.text('A'), findsOneWidget);
    expect(find.text('B'), findsNothing);

    await tester.tap(find.text('A'));
    await tester.pump();
    await tester.pump(const Duration(seconds: 1));
    expect(find.text('/'), findsNothing);
    expect(find.text('A'), findsNothing);
    expect(find.text('B'), findsOneWidget);
  });

  testWidgets('Push and pop should trigger the observers', (WidgetTester tester) async {
    final Map<String, WidgetBuilder> routes = <String, WidgetBuilder>{
      '/' : (BuildContext context) => OnTapPage(id: '/', onTap: () { Navigator.pushNamed(context, '/A'); }),
      '/A': (BuildContext context) => OnTapPage(id: 'A', onTap: () { Navigator.pop(context); }),
    };
    bool isPushed = false;
    bool isPopped = false;
    final TestObserver observer = TestObserver()
      ..onPushed = (Route<dynamic> route, Route<dynamic> previousRoute) {
        // Pushes the initial route.
        expect(route is PageRoute && route.settings.name == '/', isTrue);
        expect(previousRoute, isNull);
        isPushed = true;
      }
      ..onPopped = (Route<dynamic> route, Route<dynamic> previousRoute) {
        isPopped = true;
      };

    await tester.pumpWidget(MaterialApp(
      routes: routes,
      navigatorObservers: <NavigatorObserver>[observer],
    ));
    expect(find.text('/'), findsOneWidget);
    expect(find.text('A'), findsNothing);
    expect(isPushed, isTrue);
    expect(isPopped, isFalse);

    isPushed = false;
    isPopped = false;
    observer.onPushed = (Route<dynamic> route, Route<dynamic> previousRoute) {
      expect(route is PageRoute && route.settings.name == '/A', isTrue);
      expect(previousRoute is PageRoute && previousRoute.settings.name == '/', isTrue);
      isPushed = true;
    };

    await tester.tap(find.text('/'));
    await tester.pump();
    await tester.pump(const Duration(seconds: 1));
    expect(find.text('/'), findsNothing);
    expect(find.text('A'), findsOneWidget);
    expect(isPushed, isTrue);
    expect(isPopped, isFalse);

    isPushed = false;
    isPopped = false;
    observer.onPopped = (Route<dynamic> route, Route<dynamic> previousRoute) {
      expect(route is PageRoute && route.settings.name == '/A', isTrue);
      expect(previousRoute is PageRoute && previousRoute.settings.name == '/', isTrue);
      isPopped = true;
    };

    await tester.tap(find.text('A'));
    await tester.pump();
    await tester.pump(const Duration(seconds: 1));
    expect(find.text('/'), findsOneWidget);
    expect(find.text('A'), findsNothing);
    expect(isPushed, isFalse);
    expect(isPopped, isTrue);
  });

  testWidgets('Add and remove an observer should work', (WidgetTester tester) async {
    final Map<String, WidgetBuilder> routes = <String, WidgetBuilder>{
      '/' : (BuildContext context) => OnTapPage(id: '/', onTap: () { Navigator.pushNamed(context, '/A'); }),
      '/A': (BuildContext context) => OnTapPage(id: 'A', onTap: () { Navigator.pop(context); }),
    };
    bool isPushed = false;
    bool isPopped = false;
    final TestObserver observer1 = TestObserver();
    final TestObserver observer2 = TestObserver()
      ..onPushed = (Route<dynamic> route, Route<dynamic> previousRoute) {
        isPushed = true;
      }
      ..onPopped = (Route<dynamic> route, Route<dynamic> previousRoute) {
        isPopped = true;
      };

    await tester.pumpWidget(MaterialApp(
      routes: routes,
      navigatorObservers: <NavigatorObserver>[observer1],
    ));
    expect(isPushed, isFalse);
    expect(isPopped, isFalse);

    await tester.pumpWidget(MaterialApp(
      routes: routes,
      navigatorObservers: <NavigatorObserver>[observer1, observer2],
    ));
    await tester.tap(find.text('/'));
    await tester.pump();
    await tester.pump(const Duration(seconds: 1));
    expect(isPushed, isTrue);
    expect(isPopped, isFalse);

    isPushed = false;
    isPopped = false;

    await tester.pumpWidget(MaterialApp(
      routes: routes,
      navigatorObservers: <NavigatorObserver>[observer1],
    ));
    await tester.tap(find.text('A'));
    await tester.pump();
    await tester.pump(const Duration(seconds: 1));
    expect(isPushed, isFalse);
    expect(isPopped, isFalse);
  });

  testWidgets('initial route trigger observer in the right order', (WidgetTester tester) async {
    final Map<String, WidgetBuilder> routes = <String, WidgetBuilder>{
      '/' : (BuildContext context) => const Text('/'),
      '/A': (BuildContext context) => const Text('A'),
      '/A/B': (BuildContext context) => const Text('B'),
    };
    final List<NavigatorObservation> observations = <NavigatorObservation>[];
    final TestObserver observer = TestObserver()
      ..onPushed = (Route<dynamic> route, Route<dynamic> previousRoute) {
        // Pushes the initial route.
        observations.add(
          NavigatorObservation(
            current: route?.settings?.name,
            previous: previousRoute?.settings?.name,
            operation: 'push'
          )
        );
      };

    await tester.pumpWidget(MaterialApp(
      routes: routes,
      initialRoute: '/A/B',
      navigatorObservers: <NavigatorObserver>[observer],
    ));

    expect(observations.length, 3);
    expect(observations[0].operation, 'push');
    expect(observations[0].current, '/');
    expect(observations[0].previous, isNull);

    expect(observations[1].operation, 'push');
    expect(observations[1].current, '/A');
    expect(observations[1].previous, '/');

    expect(observations[2].operation, 'push');
    expect(observations[2].current, '/A/B');
    expect(observations[2].previous, '/A');
  });

  testWidgets('Route didAdd and dispose in same frame work', (WidgetTester tester) async {
    // Regression Test for https://github.com/flutter/flutter/issues/61346.
    Widget buildNavigator() {
      return Navigator(
        pages: <Page<void>>[
          MaterialPage<void>(
            builder: (BuildContext context) => const Placeholder(),
          )
        ],
        onPopPage: (Route<dynamic> route, dynamic result) => false,
      );
    }
    final TabController controller = TabController(length: 3, vsync: tester);
    await tester.pumpWidget(
      Directionality(
        textDirection: TextDirection.ltr,
        child: TabBarView(
          controller: controller,
          children: <Widget>[
            buildNavigator(),
            buildNavigator(),
            buildNavigator(),
          ],
        )
      ),
    );

    // This test should finish without crashing.
    controller.index = 2;
    await tester.pumpAndSettle();
  });

  testWidgets('replaceNamed replaces', (WidgetTester tester) async {
    final Map<String, WidgetBuilder> routes = <String, WidgetBuilder>{
      '/' : (BuildContext context) => OnTapPage(id: '/', onTap: () { Navigator.pushReplacementNamed(context, '/A'); }),
      '/A': (BuildContext context) => OnTapPage(id: 'A', onTap: () { Navigator.pushReplacementNamed(context, '/B'); }),
      '/B': (BuildContext context) => const OnTapPage(id: 'B'),
    };

    await tester.pumpWidget(MaterialApp(routes: routes));
    await tester.tap(find.text('/')); // replaceNamed('/A')
    await tester.pump();
    await tester.pump(const Duration(seconds: 1));
    expect(find.text('/'), findsNothing);
    expect(find.text('A'), findsOneWidget);

    await tester.tap(find.text('A')); // replaceNamed('/B')
    await tester.pump();
    await tester.pump(const Duration(seconds: 1));
    expect(find.text('/'), findsNothing);
    expect(find.text('A'), findsNothing);
    expect(find.text('B'), findsOneWidget);
  });

  testWidgets('pushReplacement sets secondaryAnimation after transition, with history change during transition', (WidgetTester tester) async {
    final Map<String, SlideInOutPageRoute<dynamic>> routes = <String, SlideInOutPageRoute<dynamic>>{};
    final Map<String, WidgetBuilder> builders = <String, WidgetBuilder>{
      '/' : (BuildContext context) => OnTapPage(
        id: '/',
        onTap: () {
          Navigator.pushNamed(context, '/A');
        }
      ),
      '/A': (BuildContext context) => OnTapPage(
        id: 'A',
        onTap: () {
          Navigator.pushNamed(context, '/B');
        }
      ),
      '/B': (BuildContext context) => OnTapPage(
        id: 'B',
        onTap: () {
          Navigator.pushReplacementNamed(context, '/C');
        },
      ),
      '/C': (BuildContext context) => OnTapPage(
        id: 'C',
        onTap: () {
          Navigator.removeRoute(context, routes['/']);
        },
      ),
    };
    await tester.pumpWidget(MaterialApp(
      onGenerateRoute: (RouteSettings settings) {
        final SlideInOutPageRoute<dynamic> ret = SlideInOutPageRoute<dynamic>(bodyBuilder: builders[settings.name], settings: settings);
        routes[settings.name] = ret;
        return ret;
      }
    ));
    await tester.pumpAndSettle();
    await tester.tap(find.text('/'));
    await tester.pumpAndSettle();
    final double a2 = routes['/A'].secondaryAnimation.value;
    await tester.tap(find.text('A'));
    await tester.pump();
    await tester.pump(const Duration(milliseconds: 16));
    expect(routes['/A'].secondaryAnimation.value, greaterThan(a2));
    await tester.pumpAndSettle();
    await tester.tap(find.text('B'));
    await tester.pump();
    await tester.pump(const Duration(milliseconds: 200));
    expect(routes['/A'].secondaryAnimation.value, equals(1.0));
    await tester.tap(find.text('C'));
    await tester.pumpAndSettle();
    expect(find.text('C'), isOnstage);
    expect(routes['/A'].secondaryAnimation.value, equals(routes['/C'].animation.value));
    final AnimationController controller = routes['/C'].controller;
    controller.value = 1 - controller.value;
    expect(routes['/A'].secondaryAnimation.value, equals(routes['/C'].animation.value));
  });

  testWidgets('new route removed from navigator history during pushReplacement transition', (WidgetTester tester) async {
    final Map<String, SlideInOutPageRoute<dynamic>> routes = <String, SlideInOutPageRoute<dynamic>>{};
    final Map<String, WidgetBuilder> builders = <String, WidgetBuilder>{
      '/' : (BuildContext context) => OnTapPage(
        id: '/',
        onTap: () {
          Navigator.pushNamed(context, '/A');
        }
      ),
      '/A': (BuildContext context) => OnTapPage(
        id: 'A',
        onTap: () {
          Navigator.pushReplacementNamed(context, '/B');
        }
      ),
      '/B': (BuildContext context) => OnTapPage(
        id: 'B',
        onTap: () {
          Navigator.removeRoute(context, routes['/B']);
        },
      ),
    };
    await tester.pumpWidget(MaterialApp(
      onGenerateRoute: (RouteSettings settings) {
        final SlideInOutPageRoute<dynamic> ret = SlideInOutPageRoute<dynamic>(bodyBuilder: builders[settings.name], settings: settings);
        routes[settings.name] = ret;
        return ret;
      }
    ));
    await tester.pumpAndSettle();
    await tester.tap(find.text('/'));
    await tester.pumpAndSettle();
    await tester.tap(find.text('A'));
    await tester.pump();
    await tester.pump(const Duration(milliseconds: 200));
    expect(find.text('A'), isOnstage);
    expect(find.text('B'), isOnstage);
    await tester.tap(find.text('B'));
    await tester.pumpAndSettle();
    expect(find.text('/'), isOnstage);
    expect(find.text('B'), findsNothing);
    expect(find.text('A'), findsNothing);
    expect(routes['/'].secondaryAnimation.value, equals(0.0));
    expect(routes['/'].animation.value, equals(1.0));
  });

  testWidgets('pushReplacement triggers secondaryAnimation', (WidgetTester tester) async {
    final Map<String, WidgetBuilder> routes = <String, WidgetBuilder>{
      '/' : (BuildContext context) => OnTapPage(
        id: '/',
        onTap: () {
          Navigator.pushReplacementNamed(context, '/A');
        }
      ),
      '/A': (BuildContext context) => OnTapPage(
        id: 'A',
        onTap: () {
          Navigator.pushReplacementNamed(context, '/B');
        }
      ),
      '/B': (BuildContext context) => const OnTapPage(id: 'B'),
    };

    await tester.pumpWidget(MaterialApp(
      onGenerateRoute: (RouteSettings settings) {
        return SlideInOutPageRoute<dynamic>(bodyBuilder: routes[settings.name]);
      }
    ));
    await tester.pumpAndSettle();
    final Offset rootOffsetOriginal = tester.getTopLeft(find.text('/'));
    await tester.tap(find.text('/'));
    await tester.pump();
    await tester.pump(const Duration(milliseconds: 16));
    expect(find.text('/'), isOnstage);
    expect(find.text('A'), isOnstage);
    expect(find.text('B'), findsNothing);
    final Offset rootOffset = tester.getTopLeft(find.text('/'));
    expect(rootOffset.dx, lessThan(rootOffsetOriginal.dx));

    Offset aOffsetOriginal = tester.getTopLeft(find.text('A'));
    await tester.pumpAndSettle();
    Offset aOffset = tester.getTopLeft(find.text('A'));
    expect(aOffset.dx, lessThan(aOffsetOriginal.dx));

    aOffsetOriginal = aOffset;
    await tester.tap(find.text('A'));
    await tester.pump();
    await tester.pump(const Duration(milliseconds: 16));
    expect(find.text('/'), findsNothing);
    expect(find.text('A'), isOnstage);
    expect(find.text('B'), isOnstage);
    aOffset = tester.getTopLeft(find.text('A'));
    expect(aOffset.dx, lessThan(aOffsetOriginal.dx));
  });

  testWidgets('pushReplacement correctly reports didReplace to the observer', (WidgetTester tester) async {
    // Regression test for  https://github.com/flutter/flutter/issues/56892.
    final Map<String, WidgetBuilder> routes = <String, WidgetBuilder>{
      '/' : (BuildContext context) => const OnTapPage(
        id: '/',
      ),
      '/A': (BuildContext context) => const OnTapPage(
        id: 'A',
      ),
      '/A/B': (BuildContext context) => OnTapPage(
        id: 'B',
        onTap: (){
          Navigator.of(context).popUntil((Route<dynamic> route) => route.isFirst);
          Navigator.of(context).pushReplacementNamed('/C');
        },
      ),
      '/C': (BuildContext context) => const OnTapPage(id: 'C',
      ),
    };
    final List<NavigatorObservation> observations = <NavigatorObservation>[];
    final TestObserver observer = TestObserver()
      ..onPopped = (Route<dynamic> route, Route<dynamic> previousRoute) {
        observations.add(
          NavigatorObservation(
            current: route.settings.name,
            previous: previousRoute.settings.name,
            operation: 'didPop'
          )
        );
      }
      ..onReplaced = (Route<dynamic> route, Route<dynamic> previousRoute) {
        observations.add(
          NavigatorObservation(
            current: route.settings.name,
            previous: previousRoute.settings.name,
            operation: 'didReplace'
          )
        );
      };
    await tester.pumpWidget(
      MaterialApp(
        routes: routes,
        navigatorObservers: <NavigatorObserver>[observer],
        initialRoute: '/A/B',
      )
    );
    await tester.pumpAndSettle();
    expect(find.text('B'), isOnstage);

    await tester.tap(find.text('B'));
    await tester.pump();
    await tester.pump(const Duration(milliseconds: 16));
    expect(observations.length, 3);
    expect(observations[0].current, '/A/B');
    expect(observations[0].previous, '/A');
    expect(observations[0].operation, 'didPop');
    expect(observations[1].current, '/A');
    expect(observations[1].previous, '/');
    expect(observations[1].operation, 'didPop');

    expect(observations[2].current, '/C');
    expect(observations[2].previous, '/');
    expect(observations[2].operation, 'didReplace');

    await tester.pumpAndSettle();
    expect(find.text('C'), isOnstage);
  });

  testWidgets('Able to pop all routes', (WidgetTester tester) async {
    final Map<String, WidgetBuilder> routes = <String, WidgetBuilder>{
      '/' : (BuildContext context) => const OnTapPage(
        id: '/',
      ),
      '/A': (BuildContext context) => const OnTapPage(
        id: 'A',
      ),
      '/A/B': (BuildContext context) => OnTapPage(
        id: 'B',
        onTap: (){
          // Pops all routes with bad predicate.
          Navigator.of(context).popUntil((Route<dynamic> route) => false);
        },
      ),
    };
    await tester.pumpWidget(
      MaterialApp(
        routes: routes,
        initialRoute: '/A/B',
      )
    );
    await tester.tap(find.text('B'));
    await tester.pumpAndSettle();
    expect(tester.takeException(), isNull);
  });

  testWidgets('pushAndRemoveUntil triggers secondaryAnimation', (WidgetTester tester) async {
    final Map<String, WidgetBuilder> routes = <String, WidgetBuilder>{
      '/' : (BuildContext context) => OnTapPage(
        id: '/',
        onTap: () {
          Navigator.pushNamed(context, '/A');
        }
      ),
      '/A': (BuildContext context) => OnTapPage(
        id: 'A',
        onTap: () {
          Navigator.pushNamedAndRemoveUntil(context, '/B', (Route<dynamic> route) => false);
        }
      ),
      '/B': (BuildContext context) => const OnTapPage(id: 'B'),
    };

    await tester.pumpWidget(MaterialApp(
      onGenerateRoute: (RouteSettings settings) {
        return SlideInOutPageRoute<dynamic>(bodyBuilder: routes[settings.name]);
      }
    ));
    await tester.pumpAndSettle();
    final Offset rootOffsetOriginal = tester.getTopLeft(find.text('/'));
    await tester.tap(find.text('/'));
    await tester.pump();
    await tester.pump(const Duration(milliseconds: 16));
    expect(find.text('/'), isOnstage);
    expect(find.text('A'), isOnstage);
    expect(find.text('B'), findsNothing);
    final Offset rootOffset = tester.getTopLeft(find.text('/'));
    expect(rootOffset.dx, lessThan(rootOffsetOriginal.dx));

    Offset aOffsetOriginal = tester.getTopLeft(find.text('A'));
    await tester.pumpAndSettle();
    Offset aOffset = tester.getTopLeft(find.text('A'));
    expect(aOffset.dx, lessThan(aOffsetOriginal.dx));

    aOffsetOriginal = aOffset;
    await tester.tap(find.text('A'));
    await tester.pump();
    await tester.pump(const Duration(milliseconds: 16));
    expect(find.text('/'), findsNothing);
    expect(find.text('A'), isOnstage);
    expect(find.text('B'), isOnstage);
    aOffset = tester.getTopLeft(find.text('A'));
    expect(aOffset.dx, lessThan(aOffsetOriginal.dx));

    await tester.pumpAndSettle();
    expect(find.text('/'), findsNothing);
    expect(find.text('A'), findsNothing);
    expect(find.text('B'), isOnstage);
  });

  testWidgets('pushAndRemoveUntil does not remove routes below the first route that pass the predicate', (WidgetTester tester) async {
    // Regression https://github.com/flutter/flutter/issues/56688
    final GlobalKey<NavigatorState> navigator = GlobalKey<NavigatorState>();
    final Map<String, WidgetBuilder> routes = <String, WidgetBuilder>{
      '/': (BuildContext context) => const Text('home'),
      '/A': (BuildContext context) => const Text('page A'),
      '/A/B': (BuildContext context) => OnTapPage(
        id: 'B',
        onTap: () {
          Navigator.of(context).pushNamedAndRemoveUntil('/D', ModalRoute.withName('/A'));
        },
      ),
      '/D': (BuildContext context) => const Text('page D'),
    };

    await tester.pumpWidget(
      MaterialApp(
        navigatorKey: navigator,
        routes: routes,
        initialRoute: '/A/B',
      )
    );
    await tester.pumpAndSettle();
    await tester.tap(find.text('B'));
    await tester.pumpAndSettle();
    expect(find.text('page D'), isOnstage);

    navigator.currentState.pop();
    await tester.pumpAndSettle();
    expect(find.text('page A'), isOnstage);

    navigator.currentState.pop();
    await tester.pumpAndSettle();
    expect(find.text('home'), isOnstage);
  });

  testWidgets('replaceNamed returned value', (WidgetTester tester) async {
    Future<String> value;

    final Map<String, WidgetBuilder> routes = <String, WidgetBuilder>{
      '/' : (BuildContext context) => OnTapPage(id: '/', onTap: () { Navigator.pushNamed(context, '/A'); }),
      '/A': (BuildContext context) => OnTapPage(id: 'A', onTap: () { value = Navigator.pushReplacementNamed(context, '/B', result: 'B'); }),
      '/B': (BuildContext context) => OnTapPage(id: 'B', onTap: () { Navigator.pop(context, 'B'); }),
    };

    await tester.pumpWidget(MaterialApp(
      onGenerateRoute: (RouteSettings settings) {
        return PageRouteBuilder<String>(
          settings: settings,
          pageBuilder: (BuildContext context, Animation<double> _, Animation<double> __) {
            return routes[settings.name](context);
          },
        );
      }
    ));

    expect(find.text('/'), findsOneWidget);
    expect(find.text('A', skipOffstage: false), findsNothing);
    expect(find.text('B', skipOffstage: false), findsNothing);

    await tester.tap(find.text('/')); // pushNamed('/A'), stack becomes /, /A
    await tester.pump();
    await tester.pump(const Duration(seconds: 1));
    expect(find.text('/'), findsNothing);
    expect(find.text('A'), findsOneWidget);
    expect(find.text('B'), findsNothing);

    await tester.tap(find.text('A')); // replaceNamed('/B'), stack becomes /, /B
    await tester.pump();
    await tester.pump(const Duration(seconds: 1));
    expect(find.text('/'), findsNothing);
    expect(find.text('A'), findsNothing);
    expect(find.text('B'), findsOneWidget);

    await tester.tap(find.text('B')); // pop, stack becomes /
    await tester.pump();
    await tester.pump(const Duration(seconds: 1));
    expect(find.text('/'), findsOneWidget);
    expect(find.text('A'), findsNothing);
    expect(find.text('B'), findsNothing);

    final String replaceNamedValue = await value; // replaceNamed result was 'B'
    expect(replaceNamedValue, 'B');
  });

  testWidgets('removeRoute', (WidgetTester tester) async {
    final Map<String, WidgetBuilder> pageBuilders = <String, WidgetBuilder>{
      '/' : (BuildContext context) => OnTapPage(id: '/', onTap: () { Navigator.pushNamed(context, '/A'); }),
      '/A': (BuildContext context) => OnTapPage(id: 'A', onTap: () { Navigator.pushNamed(context, '/B'); }),
      '/B': (BuildContext context) => const OnTapPage(id: 'B'),
    };
    final Map<String, Route<String>> routes = <String, Route<String>>{};

    Route<String> removedRoute;
    Route<String> previousRoute;

    final TestObserver observer = TestObserver()
      ..onRemoved = (Route<dynamic> route, Route<dynamic> previous) {
        removedRoute = route as Route<String>;
        previousRoute = previous as Route<String>;
      };

    await tester.pumpWidget(MaterialApp(
      navigatorObservers: <NavigatorObserver>[observer],
      onGenerateRoute: (RouteSettings settings) {
        routes[settings.name] = PageRouteBuilder<String>(
          settings: settings,
          pageBuilder: (BuildContext context, Animation<double> _, Animation<double> __) {
            return pageBuilders[settings.name](context);
          },
        );
        return routes[settings.name];
      },
    ));

    expect(find.text('/'), findsOneWidget);
    expect(find.text('A'), findsNothing);
    expect(find.text('B'), findsNothing);

    await tester.tap(find.text('/')); // pushNamed('/A'), stack becomes /, /A
    await tester.pumpAndSettle();
    expect(find.text('/'), findsNothing);
    expect(find.text('A'), findsOneWidget);
    expect(find.text('B'), findsNothing);

    await tester.tap(find.text('A')); // pushNamed('/B'), stack becomes /, /A, /B
    await tester.pumpAndSettle();
    expect(find.text('/'), findsNothing);
    expect(find.text('A'), findsNothing);
    expect(find.text('B'), findsOneWidget);

    // Verify that the navigator's stack is ordered as expected.
    expect(routes['/'].isActive, true);
    expect(routes['/A'].isActive, true);
    expect(routes['/B'].isActive, true);
    expect(routes['/'].isFirst, true);
    expect(routes['/B'].isCurrent, true);

    final NavigatorState navigator = tester.state<NavigatorState>(find.byType(Navigator));
    navigator.removeRoute(routes['/B']); // stack becomes /, /A
    await tester.pump();
    expect(find.text('/'), findsNothing);
    expect(find.text('A'), findsOneWidget);
    expect(find.text('B'), findsNothing);

    // Verify that the navigator's stack no longer includes /B
    expect(routes['/'].isActive, true);
    expect(routes['/A'].isActive, true);
    expect(routes['/B'].isActive, false);
    expect(routes['/'].isFirst, true);
    expect(routes['/A'].isCurrent, true);

    expect(removedRoute, routes['/B']);
    expect(previousRoute, routes['/A']);

    navigator.removeRoute(routes['/A']); // stack becomes just /
    await tester.pump();
    expect(find.text('/'), findsOneWidget);
    expect(find.text('A'), findsNothing);
    expect(find.text('B'), findsNothing);

    // Verify that the navigator's stack no longer includes /A
    expect(routes['/'].isActive, true);
    expect(routes['/A'].isActive, false);
    expect(routes['/B'].isActive, false);
    expect(routes['/'].isFirst, true);
    expect(routes['/'].isCurrent, true);
    expect(removedRoute, routes['/A']);
    expect(previousRoute, routes['/']);
  });

  testWidgets('remove a route whose value is awaited', (WidgetTester tester) async {
    Future<String> pageValue;
    final Map<String, WidgetBuilder> pageBuilders = <String, WidgetBuilder>{
      '/':  (BuildContext context) => OnTapPage(id: '/', onTap: () { pageValue = Navigator.pushNamed(context, '/A'); }),
      '/A': (BuildContext context) => OnTapPage(id: 'A', onTap: () { Navigator.pop(context, 'A'); }),
    };
    final Map<String, Route<String>> routes = <String, Route<String>>{};

    await tester.pumpWidget(MaterialApp(
      onGenerateRoute: (RouteSettings settings) {
        routes[settings.name] = PageRouteBuilder<String>(
          settings: settings,
          pageBuilder: (BuildContext context, Animation<double> _, Animation<double> __) {
            return pageBuilders[settings.name](context);
          },
        );
        return routes[settings.name];
      }
    ));

    await tester.tap(find.text('/')); // pushNamed('/A'), stack becomes /, /A
    await tester.pumpAndSettle();
    pageValue.then((String value) { assert(false); });

    final NavigatorState navigator = tester.state<NavigatorState>(find.byType(Navigator));
    navigator.removeRoute(routes['/A']); // stack becomes /, pageValue will not complete
  });

  testWidgets('replacing route can be observed', (WidgetTester tester) async {
    final GlobalKey<NavigatorState> key = GlobalKey<NavigatorState>();
    final List<String> log = <String>[];
    final TestObserver observer = TestObserver()
      ..onPushed = (Route<dynamic> route, Route<dynamic> previousRoute) {
        log.add('pushed ${route.settings.name} (previous is ${previousRoute == null ? "<none>" : previousRoute.settings.name})');
      }
      ..onPopped = (Route<dynamic> route, Route<dynamic> previousRoute) {
        log.add('popped ${route.settings.name} (previous is ${previousRoute == null ? "<none>" : previousRoute.settings.name})');
      }
      ..onRemoved = (Route<dynamic> route, Route<dynamic> previousRoute) {
        log.add('removed ${route.settings.name} (previous is ${previousRoute == null ? "<none>" : previousRoute.settings.name})');
      }
      ..onReplaced = (Route<dynamic> newRoute, Route<dynamic> oldRoute) {
        log.add('replaced ${oldRoute.settings.name} with ${newRoute.settings.name}');
      };
    Route<void> routeB;
    await tester.pumpWidget(MaterialApp(
      navigatorKey: key,
      navigatorObservers: <NavigatorObserver>[observer],
      home: TextButton(
        child: const Text('A'),
        onPressed: () {
          key.currentState.push<void>(routeB = MaterialPageRoute<void>(
            settings: const RouteSettings(name: 'B'),
            builder: (BuildContext context) {
              return TextButton(
                child: const Text('B'),
                onPressed: () {
                  key.currentState.push<void>(MaterialPageRoute<int>(
                    settings: const RouteSettings(name: 'C'),
                    builder: (BuildContext context) {
                      return TextButton(
                        child: const Text('C'),
                        onPressed: () {
                          key.currentState.replace(
                            oldRoute: routeB,
                            newRoute: MaterialPageRoute<int>(
                              settings: const RouteSettings(name: 'D'),
                              builder: (BuildContext context) {
                                return const Text('D');
                              },
                            ),
                          );
                        },
                      );
                    },
                  ));
                },
              );
            },
          ));
        },
      ),
    ));
    expect(log, <String>['pushed / (previous is <none>)']);
    await tester.tap(find.text('A'));
    await tester.pump();
    await tester.pump(const Duration(seconds: 1));
    expect(log, <String>['pushed / (previous is <none>)', 'pushed B (previous is /)']);
    await tester.tap(find.text('B'));
    await tester.pump();
    await tester.pump(const Duration(seconds: 1));
    expect(log, <String>['pushed / (previous is <none>)', 'pushed B (previous is /)', 'pushed C (previous is B)']);
    await tester.tap(find.text('C'));
    await tester.pump();
    await tester.pump(const Duration(seconds: 1));
    expect(log, <String>['pushed / (previous is <none>)', 'pushed B (previous is /)', 'pushed C (previous is B)', 'replaced B with D']);
  });

  testWidgets('didStartUserGesture observable', (WidgetTester tester) async {
    final Map<String, WidgetBuilder> routes = <String, WidgetBuilder>{
      '/' : (BuildContext context) => OnTapPage(id: '/', onTap: () { Navigator.pushNamed(context, '/A'); }),
      '/A': (BuildContext context) => OnTapPage(id: 'A', onTap: () { Navigator.pop(context); }),
    };

    Route<dynamic> observedRoute;
    Route<dynamic> observedPreviousRoute;
    final TestObserver observer = TestObserver()
      ..onStartUserGesture = (Route<dynamic> route, Route<dynamic> previousRoute) {
        observedRoute = route;
        observedPreviousRoute = previousRoute;
      };

    await tester.pumpWidget(MaterialApp(
      routes: routes,
      navigatorObservers: <NavigatorObserver>[observer],
    ));

    await tester.tap(find.text('/'));
    await tester.pump();
    await tester.pump(const Duration(seconds: 1));
    expect(find.text('/'), findsNothing);
    expect(find.text('A'), findsOneWidget);

    tester.state<NavigatorState>(find.byType(Navigator)).didStartUserGesture();

    expect(observedRoute.settings.name, '/A');
    expect(observedPreviousRoute.settings.name, '/');
  });

  testWidgets('ModalRoute.of sets up a route to rebuild if its state changes', (WidgetTester tester) async {
    final GlobalKey<NavigatorState> key = GlobalKey<NavigatorState>();
    final List<String> log = <String>[];
    Route<void> routeB;
    await tester.pumpWidget(MaterialApp(
      navigatorKey: key,
      theme: ThemeData(
        pageTransitionsTheme: const PageTransitionsTheme(
          builders: <TargetPlatform, PageTransitionsBuilder>{
            TargetPlatform.android: FadeUpwardsPageTransitionsBuilder(),
          },
        ),
      ),
      home: TextButton(
        child: const Text('A'),
        onPressed: () {
          key.currentState.push<void>(routeB = MaterialPageRoute<void>(
            settings: const RouteSettings(name: 'B'),
            builder: (BuildContext context) {
              log.add('building B');
              return TextButton(
                child: const Text('B'),
                onPressed: () {
                  key.currentState.push<void>(MaterialPageRoute<int>(
                    settings: const RouteSettings(name: 'C'),
                    builder: (BuildContext context) {
                      log.add('building C');
                      log.add('found ${ModalRoute.of(context).settings.name}');
                      return TextButton(
                        child: const Text('C'),
                        onPressed: () {
                          key.currentState.replace(
                            oldRoute: routeB,
                            newRoute: MaterialPageRoute<int>(
                              settings: const RouteSettings(name: 'D'),
                              builder: (BuildContext context) {
                                log.add('building D');
                                return const Text('D');
                              },
                            ),
                          );
                        },
                      );
                    },
                  ));
                },
              );
            },
          ));
        },
      ),
    ));
    expect(log, <String>[]);
    await tester.tap(find.text('A'));
    await tester.pumpAndSettle(const Duration(milliseconds: 10));
    expect(log, <String>['building B']);
    await tester.tap(find.text('B'));
    await tester.pumpAndSettle(const Duration(milliseconds: 10));
    expect(log, <String>['building B', 'building C', 'found C']);
    await tester.tap(find.text('C'));
    await tester.pumpAndSettle(const Duration(milliseconds: 10));
    expect(log, <String>['building B', 'building C', 'found C', 'building D']);
    key.currentState.pop<void>();
    await tester.pumpAndSettle(const Duration(milliseconds: 10));
    expect(log, <String>['building B', 'building C', 'found C', 'building D']);
  });

  testWidgets('Routes don\'t rebuild just because their animations ended', (WidgetTester tester) async {
    final GlobalKey<NavigatorState> key = GlobalKey<NavigatorState>();
    final List<String> log = <String>[];
    Route<dynamic> nextRoute = PageRouteBuilder<int>(
      pageBuilder: (BuildContext context, Animation<double> animation, Animation<double> secondaryAnimation) {
        log.add('building page 1 - ${ModalRoute.of(context).canPop}');
        return const Placeholder();
      },
    );
    await tester.pumpWidget(MaterialApp(
      navigatorKey: key,
      onGenerateRoute: (RouteSettings settings) {
        assert(nextRoute != null);
        final Route<dynamic> result = nextRoute;
        nextRoute = null;
        return result;
      },
    ));
    expect(log, <String>['building page 1 - false']);
    key.currentState.pushReplacement(PageRouteBuilder<int>(
      pageBuilder: (BuildContext context, Animation<double> animation, Animation<double> secondaryAnimation) {
        log.add('building page 2 - ${ModalRoute.of(context).canPop}');
        return const Placeholder();
      },
    ));
    expect(log, <String>['building page 1 - false']);
    await tester.pump();
    expect(log, <String>['building page 1 - false', 'building page 2 - false']);
    await tester.pump(const Duration(milliseconds: 150));
    expect(log, <String>['building page 1 - false', 'building page 2 - false']);
    key.currentState.pushReplacement(PageRouteBuilder<int>(
      pageBuilder: (BuildContext context, Animation<double> animation, Animation<double> secondaryAnimation) {
        log.add('building page 3 - ${ModalRoute.of(context).canPop}');
        return const Placeholder();
      },
    ));
    expect(log, <String>['building page 1 - false', 'building page 2 - false']);
    await tester.pump();
    expect(log, <String>['building page 1 - false', 'building page 2 - false', 'building page 3 - false']);
    await tester.pump(const Duration(milliseconds: 200));
    expect(log, <String>['building page 1 - false', 'building page 2 - false', 'building page 3 - false']);
  });

  testWidgets('route semantics', (WidgetTester tester) async {
    final SemanticsTester semantics = SemanticsTester(tester);
    final Map<String, WidgetBuilder> routes = <String, WidgetBuilder>{
      '/': (BuildContext context) => OnTapPage(id: '1', onTap: () { Navigator.pushNamed(context, '/A'); }),
      '/A': (BuildContext context) => OnTapPage(id: '2', onTap: () { Navigator.pushNamed(context, '/B/C'); }),
      '/B/C': (BuildContext context) => const OnTapPage(id: '3'),
    };

    await tester.pumpWidget(MaterialApp(routes: routes));

    expect(semantics, includesNodeWith(
      flags: <SemanticsFlag>[SemanticsFlag.scopesRoute],
    ));
    expect(semantics, includesNodeWith(
      label: 'Page 1',
      flags: <SemanticsFlag>[
        SemanticsFlag.namesRoute,
        SemanticsFlag.isHeader,
      ],
    ));

    await tester.tap(find.text('1')); // pushNamed('/A')
    await tester.pump();
    await tester.pump(const Duration(seconds: 1));

    expect(semantics, includesNodeWith(
      flags: <SemanticsFlag>[SemanticsFlag.scopesRoute],
    ));
    expect(semantics, includesNodeWith(
      label: 'Page 2',
      flags: <SemanticsFlag>[
        SemanticsFlag.namesRoute,
        SemanticsFlag.isHeader,
      ],
    ));

    await tester.tap(find.text('2')); // pushNamed('/B/C')
    await tester.pump();
    await tester.pump(const Duration(seconds: 1));

    expect(semantics, includesNodeWith(
      flags: <SemanticsFlag>[
        SemanticsFlag.scopesRoute,
      ],
    ));
    expect(semantics, includesNodeWith(
      label: 'Page 3',
      flags: <SemanticsFlag>[
        SemanticsFlag.namesRoute,
        SemanticsFlag.isHeader,
      ],
    ));


    semantics.dispose();
  });

  testWidgets('arguments for named routes on Navigator', (WidgetTester tester) async {
    GlobalKey currentRouteKey;
    final List<Object> arguments = <Object>[];

    await tester.pumpWidget(MaterialApp(
      onGenerateRoute: (RouteSettings settings) {
        arguments.add(settings.arguments);
        return MaterialPageRoute<void>(
          settings: settings,
          builder: (BuildContext context) => Center(key: currentRouteKey = GlobalKey(), child: Text(settings.name)),
        );
      },
    ));

    expect(find.text('/'), findsOneWidget);
    expect(arguments.single, isNull);
    arguments.clear();

    Navigator.pushNamed(
      currentRouteKey.currentContext,
      '/A',
      arguments: 'pushNamed',
    );
    await tester.pumpAndSettle();

    expect(find.text('/'), findsNothing);
    expect(find.text('/A'), findsOneWidget);
    expect(arguments.single, 'pushNamed');
    arguments.clear();

    Navigator.popAndPushNamed(
      currentRouteKey.currentContext,
      '/B',
      arguments: 'popAndPushNamed',
    );
    await tester.pumpAndSettle();

    expect(find.text('/'), findsNothing);
    expect(find.text('/A'), findsNothing);
    expect(find.text('/B'), findsOneWidget);
    expect(arguments.single, 'popAndPushNamed');
    arguments.clear();

    Navigator.pushNamedAndRemoveUntil(
      currentRouteKey.currentContext,
      '/C',
      (Route<dynamic> route) => route.isFirst,
      arguments: 'pushNamedAndRemoveUntil',
    );
    await tester.pumpAndSettle();

    expect(find.text('/'), findsNothing);
    expect(find.text('/A'), findsNothing);
    expect(find.text('/B'), findsNothing);
    expect(find.text('/C'), findsOneWidget);
    expect(arguments.single, 'pushNamedAndRemoveUntil');
    arguments.clear();

    Navigator.pushReplacementNamed(
      currentRouteKey.currentContext,
      '/D',
      arguments: 'pushReplacementNamed',
    );
    await tester.pumpAndSettle();

    expect(find.text('/'), findsNothing);
    expect(find.text('/A'), findsNothing);
    expect(find.text('/B'), findsNothing);
    expect(find.text('/C'), findsNothing);
    expect(find.text('/D'), findsOneWidget);
    expect(arguments.single, 'pushReplacementNamed');
    arguments.clear();
  });

  testWidgets('arguments for named routes on NavigatorState', (WidgetTester tester) async {
    final GlobalKey<NavigatorState> navigatorKey = GlobalKey<NavigatorState>();
    final List<Object> arguments = <Object>[];

    await tester.pumpWidget(MaterialApp(
      navigatorKey: navigatorKey,
      onGenerateRoute: (RouteSettings settings) {
        arguments.add(settings.arguments);
        return MaterialPageRoute<void>(
          settings: settings,
          builder: (BuildContext context) => Center(child: Text(settings.name)),
        );
      },
    ));

    expect(find.text('/'), findsOneWidget);
    expect(arguments.single, isNull);
    arguments.clear();

    navigatorKey.currentState.pushNamed(
      '/A',
      arguments:'pushNamed',
    );
    await tester.pumpAndSettle();

    expect(find.text('/'), findsNothing);
    expect(find.text('/A'), findsOneWidget);
    expect(arguments.single, 'pushNamed');
    arguments.clear();

    navigatorKey.currentState.popAndPushNamed(
      '/B',
      arguments: 'popAndPushNamed',
    );
    await tester.pumpAndSettle();

    expect(find.text('/'), findsNothing);
    expect(find.text('/A'), findsNothing);
    expect(find.text('/B'), findsOneWidget);
    expect(arguments.single, 'popAndPushNamed');
    arguments.clear();

    navigatorKey.currentState.pushNamedAndRemoveUntil(
      '/C',
      (Route<dynamic> route) => route.isFirst,
      arguments: 'pushNamedAndRemoveUntil',
    );
    await tester.pumpAndSettle();

    expect(find.text('/'), findsNothing);
    expect(find.text('/A'), findsNothing);
    expect(find.text('/B'), findsNothing);
    expect(find.text('/C'), findsOneWidget);
    expect(arguments.single, 'pushNamedAndRemoveUntil');
    arguments.clear();

    navigatorKey.currentState.pushReplacementNamed(
      '/D',
      arguments: 'pushReplacementNamed',
    );
    await tester.pumpAndSettle();

    expect(find.text('/'), findsNothing);
    expect(find.text('/A'), findsNothing);
    expect(find.text('/B'), findsNothing);
    expect(find.text('/C'), findsNothing);
    expect(find.text('/D'), findsOneWidget);
    expect(arguments.single, 'pushReplacementNamed');
    arguments.clear();
  });

  testWidgets('Initial route can have gaps', (WidgetTester tester) async {
    final GlobalKey<NavigatorState> keyNav = GlobalKey<NavigatorState>();
    const Key keyRoot = Key('Root');
    const Key keyA = Key('A');
    const Key keyABC = Key('ABC');

    await tester.pumpWidget(
      MaterialApp(
        navigatorKey: keyNav,
        initialRoute: '/A/B/C',
        routes: <String, WidgetBuilder>{
          '/': (BuildContext context) => Container(key: keyRoot),
          '/A': (BuildContext context) => Container(key: keyA),
          // The route /A/B is intentionally left out.
          '/A/B/C': (BuildContext context) => Container(key: keyABC),
        },
      ),
    );

    // The initial route /A/B/C should've been pushed successfully.
    expect(find.byKey(keyRoot, skipOffstage: false), findsOneWidget);
    expect(find.byKey(keyA, skipOffstage: false), findsOneWidget);
    expect(find.byKey(keyABC), findsOneWidget);

    keyNav.currentState.pop();
    await tester.pumpAndSettle();
    expect(find.byKey(keyRoot, skipOffstage: false), findsOneWidget);
    expect(find.byKey(keyA), findsOneWidget);
    expect(find.byKey(keyABC, skipOffstage: false), findsNothing);
  });

  testWidgets('The full initial route has to be matched', (WidgetTester tester) async {
    final GlobalKey<NavigatorState> keyNav = GlobalKey<NavigatorState>();
    const Key keyRoot = Key('Root');
    const Key keyA = Key('A');
    const Key keyAB = Key('AB');

    await tester.pumpWidget(
      MaterialApp(
        navigatorKey: keyNav,
        initialRoute: '/A/B/C',
        routes: <String, WidgetBuilder>{
          '/': (BuildContext context) => Container(key: keyRoot),
          '/A': (BuildContext context) => Container(key: keyA),
          '/A/B': (BuildContext context) => Container(key: keyAB),
          // The route /A/B/C is intentionally left out.
        },
      ),
    );

    final dynamic exception = tester.takeException();
    expect(exception, isA<String>());
    expect(exception.startsWith('Could not navigate to initial route.'), isTrue);

    // Only the root route should've been pushed.
    expect(find.byKey(keyRoot), findsOneWidget);
    expect(find.byKey(keyA), findsNothing);
    expect(find.byKey(keyAB), findsNothing);
  });

  testWidgets("Popping immediately after pushing doesn't crash", (WidgetTester tester) async {
    // Added this test to protect against regression of https://github.com/flutter/flutter/issues/45539
    final Map<String, WidgetBuilder> routes = <String, WidgetBuilder>{
      '/' : (BuildContext context) => OnTapPage(id: '/', onTap: () {
        Navigator.pushNamed(context, '/A');
        Navigator.of(context).pop();
      }),
      '/A': (BuildContext context) => OnTapPage(id: 'A', onTap: () { Navigator.pop(context); }),
    };
    bool isPushed = false;
    bool isPopped = false;
    final TestObserver observer = TestObserver()
      ..onPushed = (Route<dynamic> route, Route<dynamic> previousRoute) {
        // Pushes the initial route.
        expect(route is PageRoute && route.settings.name == '/', isTrue);
        expect(previousRoute, isNull);
        isPushed = true;
      }
      ..onPopped = (Route<dynamic> route, Route<dynamic> previousRoute) {
        isPopped = true;
      };

    await tester.pumpWidget(MaterialApp(
      routes: routes,
      navigatorObservers: <NavigatorObserver>[observer],
    ));
    expect(find.text('/'), findsOneWidget);
    expect(find.text('A'), findsNothing);
    expect(isPushed, isTrue);
    expect(isPopped, isFalse);

    isPushed = false;
    isPopped = false;
    observer.onPushed = (Route<dynamic> route, Route<dynamic> previousRoute) {
      expect(route is PageRoute && route.settings.name == '/A', isTrue);
      expect(previousRoute is PageRoute && previousRoute.settings.name == '/', isTrue);
      isPushed = true;
    };

    await tester.tap(find.text('/'));
    await tester.pump();
    await tester.pump(const Duration(seconds: 1));
    expect(find.text('/'), findsOneWidget);
    expect(find.text('A'), findsNothing);
    expect(isPushed, isTrue);
    expect(isPopped, isTrue);
  });

  group('error control test', () {
    testWidgets('onUnknownRoute null and onGenerateRoute returns null', (WidgetTester tester) async {
      final GlobalKey<NavigatorState> navigatorKey = GlobalKey<NavigatorState>();
      await tester.pumpWidget(Navigator(
        key: navigatorKey,
        onGenerateRoute: (_) => null,
      ));
      final dynamic exception = tester.takeException();
      expect(exception, isNotNull);
      expect(exception, isFlutterError);
      final FlutterError error = exception as FlutterError;
      expect(error, isNotNull);
      expect(error.diagnostics.last, isA<DiagnosticsProperty<NavigatorState>>());
      expect(
        error.toStringDeep(),
        equalsIgnoringHashCodes(
          'FlutterError\n'
          '   Navigator.onGenerateRoute returned null when requested to build\n'
          '   route "/".\n'
          '   The onGenerateRoute callback must never return null, unless an\n'
          '   onUnknownRoute callback is provided as well.\n'
          '   The Navigator was:\n'
          '     NavigatorState#4d6bf(lifecycle state: created)\n',
        ),
      );
    });

    testWidgets('onUnknownRoute null and onGenerateRoute returns null', (WidgetTester tester) async {
      final GlobalKey<NavigatorState> navigatorKey = GlobalKey<NavigatorState>();
      await tester.pumpWidget(Navigator(
        key: navigatorKey,
        onGenerateRoute: (_) => null,
        onUnknownRoute: (_) => null,
      ));
      final dynamic exception = tester.takeException();
      expect(exception, isNotNull);
      expect(exception, isFlutterError);
      final FlutterError error = exception as FlutterError;
      expect(error, isNotNull);
      expect(error.diagnostics.last, isA<DiagnosticsProperty<NavigatorState>>());
      expect(
        error.toStringDeep(),
        equalsIgnoringHashCodes(
          'FlutterError\n'
          '   Navigator.onUnknownRoute returned null when requested to build\n'
          '   route "/".\n'
          '   The onUnknownRoute callback must never return null.\n'
          '   The Navigator was:\n'
          '     NavigatorState#38036(lifecycle state: created)\n',
        ),
      );
    });
  });

  testWidgets('OverlayEntry of topmost initial route is marked as opaque', (WidgetTester tester) async {
    // Regression test for https://github.com/flutter/flutter/issues/38038.

    final Key root = UniqueKey();
    final Key intermediate = UniqueKey();
    final GlobalKey topmost = GlobalKey();
    await tester.pumpWidget(
      MaterialApp(
        initialRoute: '/A/B',
        routes: <String, WidgetBuilder>{
          '/': (BuildContext context) => Container(key: root),
          '/A': (BuildContext context) => Container(key: intermediate),
          '/A/B': (BuildContext context) => Container(key: topmost),
        },
      ),
    );

    expect(ModalRoute.of(topmost.currentContext).overlayEntries.first.opaque, isTrue);

    expect(find.byKey(root), findsNothing);  // hidden by opaque Route
    expect(find.byKey(intermediate), findsNothing);  // hidden by opaque Route
    expect(find.byKey(topmost), findsOneWidget);
  });

  testWidgets('OverlayEntry of topmost route is set to opaque after Push', (WidgetTester tester) async {
    // Regression test for https://github.com/flutter/flutter/issues/38038.

    final GlobalKey<NavigatorState> navigator = GlobalKey<NavigatorState>();
    await tester.pumpWidget(
      MaterialApp(
        navigatorKey: navigator,
        initialRoute: '/',
        onGenerateRoute: (RouteSettings settings) {
          return NoAnimationPageRoute(
            pageBuilder: (_) => Container(key: ValueKey<String>(settings.name)),
          );
        },
      ),
    );
    expect(find.byKey(const ValueKey<String>('/')), findsOneWidget);

    navigator.currentState.pushNamed('/A');
    await tester.pump();

    final BuildContext topMostContext = tester.element(find.byKey(const ValueKey<String>('/A')));
    expect(ModalRoute.of(topMostContext).overlayEntries.first.opaque, isTrue);

    expect(find.byKey(const ValueKey<String>('/')), findsNothing);  // hidden by /A
    expect(find.byKey(const ValueKey<String>('/A')), findsOneWidget);
  });

  testWidgets('OverlayEntry of topmost route is set to opaque after Replace', (WidgetTester tester) async {
    // Regression test for https://github.com/flutter/flutter/issues/38038.

    final GlobalKey<NavigatorState> navigator = GlobalKey<NavigatorState>();
    await tester.pumpWidget(
      MaterialApp(
        navigatorKey: navigator,
        initialRoute: '/A/B',
        onGenerateRoute: (RouteSettings settings) {
          return NoAnimationPageRoute(
            pageBuilder: (_) => Container(key: ValueKey<String>(settings.name)),
          );
        },
      ),
    );
    expect(find.byKey(const ValueKey<String>('/')), findsNothing);
    expect(find.byKey(const ValueKey<String>('/A')), findsNothing);
    expect(find.byKey(const ValueKey<String>('/A/B')), findsOneWidget);

    final Route<dynamic> oldRoute = ModalRoute.of(
      tester.element(find.byKey(const ValueKey<String>('/A'), skipOffstage: false)),
    );
    final Route<void> newRoute = NoAnimationPageRoute(
      pageBuilder: (_) => Container(key: const ValueKey<String>('/C')),
    );

    navigator.currentState.replace<void>(oldRoute: oldRoute, newRoute: newRoute);
    await tester.pump();

    expect(newRoute.overlayEntries.first.opaque, isTrue);

    expect(find.byKey(const ValueKey<String>('/')), findsNothing);  // hidden by /A/B
    expect(find.byKey(const ValueKey<String>('/A')), findsNothing);  // replaced
    expect(find.byKey(const ValueKey<String>('/C')), findsNothing);  // hidden by /A/B
    expect(find.byKey(const ValueKey<String>('/A/B')), findsOneWidget);

    navigator.currentState.pop();
    await tester.pumpAndSettle();

    expect(find.byKey(const ValueKey<String>('/')), findsNothing);  // hidden by /C
    expect(find.byKey(const ValueKey<String>('/A')), findsNothing);  // replaced
    expect(find.byKey(const ValueKey<String>('/A/B')), findsNothing); // popped
    expect(find.byKey(const ValueKey<String>('/C')), findsOneWidget);
  });

  testWidgets('Pushing opaque Route does not rebuild routes below', (WidgetTester tester) async {
    // Regression test for https://github.com/flutter/flutter/issues/45797.

    final GlobalKey<NavigatorState> navigator = GlobalKey<NavigatorState>();
    final Key bottomRoute = UniqueKey();
    final Key topRoute = UniqueKey();
    await tester.pumpWidget(
      MaterialApp(
        theme: ThemeData(
          pageTransitionsTheme: const PageTransitionsTheme(
            builders: <TargetPlatform, PageTransitionsBuilder>{
              TargetPlatform.android: FadeUpwardsPageTransitionsBuilder(),
            },
          ),
        ),
        navigatorKey: navigator,
        routes: <String, WidgetBuilder>{
          '/' : (BuildContext context) => StatefulTestWidget(key: bottomRoute),
          '/a': (BuildContext context) => StatefulTestWidget(key: topRoute),
        },
      ),
    );
    expect(tester.state<StatefulTestState>(find.byKey(bottomRoute)).rebuildCount, 1);

    navigator.currentState.pushNamed('/a');
    await tester.pumpAndSettle();

    // Bottom route is offstage and did not rebuild.
    expect(find.byKey(bottomRoute), findsNothing);
    expect(tester.state<StatefulTestState>(find.byKey(bottomRoute, skipOffstage: false)).rebuildCount, 1);

    expect(tester.state<StatefulTestState>(find.byKey(topRoute)).rebuildCount, 1);
  });

  testWidgets('initial routes below opaque route are offstage', (WidgetTester tester) async {
    final GlobalKey<NavigatorState> g = GlobalKey<NavigatorState>();
    await tester.pumpWidget(
      Directionality(
        textDirection: TextDirection.ltr,
        child: Navigator(
          key: g,
          initialRoute: '/a/b',
          onGenerateRoute: (RouteSettings s) {
            return MaterialPageRoute<void>(
              builder: (BuildContext c) {
                return Text('+${s.name}+');
              },
              settings: s,
            );
          },
        ),
      ),
    );

    expect(find.text('+/+'), findsNothing);
    expect(find.text('+/+', skipOffstage: false), findsOneWidget);
    expect(find.text('+/a+'), findsNothing);
    expect(find.text('+/a+', skipOffstage: false), findsOneWidget);
    expect(find.text('+/a/b+'), findsOneWidget);

    g.currentState.pop();
    await tester.pumpAndSettle();

    expect(find.text('+/+'), findsNothing);
    expect(find.text('+/+', skipOffstage: false), findsOneWidget);
    expect(find.text('+/a+'), findsOneWidget);
    expect(find.text('+/a/b+'), findsNothing);

    g.currentState.pop();
    await tester.pumpAndSettle();

    expect(find.text('+/+'), findsOneWidget);
    expect(find.text('+/a+'), findsNothing);
    expect(find.text('+/a/b+'), findsNothing);
  });

  testWidgets('Can provide custom onGenerateInitialRoutes', (WidgetTester tester) async {
    bool onGenerateInitialRoutesCalled = false;
    final GlobalKey<NavigatorState> g = GlobalKey<NavigatorState>();
    await tester.pumpWidget(
      Directionality(
        textDirection: TextDirection.ltr,
        child: Navigator(
          key: g,
          initialRoute: 'Hello World',
          onGenerateInitialRoutes: (NavigatorState navigator, String initialRoute) {
            onGenerateInitialRoutesCalled = true;
            final List<Route<void>> result = <Route<void>>[];
            for (final String route in initialRoute.split(' ')) {
              result.add(MaterialPageRoute<void>(builder: (BuildContext context) {
                return Text(route);
              }));
            }
            return result;
          },
        ),
      ),
    );

    expect(onGenerateInitialRoutesCalled, true);
    expect(find.text('Hello'), findsNothing);
    expect(find.text('World'), findsOneWidget);

    g.currentState.pop();
    await tester.pumpAndSettle();

    expect(find.text('Hello'), findsOneWidget);
    expect(find.text('World'), findsNothing);
  });

  testWidgets('Navigator.of able to handle input context is a navigator context', (WidgetTester tester) async {
    final GlobalKey<NavigatorState> g = GlobalKey<NavigatorState>();
    await tester.pumpWidget(
      MaterialApp(
        navigatorKey: g,
        home: const Text('home'),
      )
    );

    final NavigatorState state = Navigator.of(g.currentContext);
    expect(state, g.currentState);
  });

  testWidgets('Navigator.of able to handle input context is a navigator context - root navigator', (WidgetTester tester) async {
    final GlobalKey<NavigatorState> root = GlobalKey<NavigatorState>();
    final GlobalKey<NavigatorState> sub = GlobalKey<NavigatorState>();
    await tester.pumpWidget(
      MaterialApp(
        navigatorKey: root,
        home: Navigator(
          key: sub,
          onGenerateRoute: (RouteSettings settings) {
            return MaterialPageRoute<void>(
              settings: settings,
              builder: (BuildContext context) => const Text('dummy'),
            );
          },
        ),
      )
    );

    final NavigatorState state = Navigator.of(sub.currentContext, rootNavigator: true);
    expect(state, root.currentState);
  });

  testWidgets('pushAndRemove until animates the push', (WidgetTester tester) async {
    // Regression test for https://github.com/flutter/flutter/issues/25080.

    const Duration kFourTenthsOfTheTransitionDuration = Duration(milliseconds: 120);
    final GlobalKey<NavigatorState> navigator = GlobalKey<NavigatorState>();
    final Map<String, MaterialPageRoute<dynamic>> routeNameToContext = <String, MaterialPageRoute<dynamic>>{};

    await tester.pumpWidget(
      Directionality(
        textDirection: TextDirection.ltr,
        child: Navigator(
          key: navigator,
          initialRoute: 'root',
          onGenerateRoute: (RouteSettings settings) {
            return MaterialPageRoute<void>(
              settings: settings,
              builder: (BuildContext context) {
                routeNameToContext[settings.name] = ModalRoute.of(context) as MaterialPageRoute<dynamic>;
                return Text('Route: ${settings.name}');
              },
            );
          },
        ),
      ),
    );

    expect(find.text('Route: root'), findsOneWidget);

    navigator.currentState.pushNamed('1');
    await tester.pumpAndSettle();

    expect(find.text('Route: 1'), findsOneWidget);

    navigator.currentState.pushNamed('2');
    await tester.pumpAndSettle();

    expect(find.text('Route: 2'), findsOneWidget);

    navigator.currentState.pushNamed('3');
    await tester.pumpAndSettle();

    expect(find.text('Route: 3'), findsOneWidget);
    expect(find.text('Route: 2', skipOffstage: false), findsOneWidget);
    expect(find.text('Route: 1', skipOffstage: false), findsOneWidget);
    expect(find.text('Route: root', skipOffstage: false), findsOneWidget);

    navigator.currentState.pushNamedAndRemoveUntil('4', (Route<dynamic> route) => route.isFirst);
    await tester.pump();

    expect(find.text('Route: 3'), findsOneWidget);
    expect(find.text('Route: 4'), findsOneWidget);
    final Animation<double> route4Entry = routeNameToContext['4'].animation;
    expect(route4Entry.value, 0.0); // Entry animation has not started.

    await tester.pump(kFourTenthsOfTheTransitionDuration);
    expect(find.text('Route: 3'), findsOneWidget);
    expect(find.text('Route: 4'), findsOneWidget);
    expect(route4Entry.value, 0.4);

    await tester.pump(kFourTenthsOfTheTransitionDuration);
    expect(find.text('Route: 3'), findsOneWidget);
    expect(find.text('Route: 4'), findsOneWidget);
    expect(route4Entry.value, 0.8);
    expect(find.text('Route: 2', skipOffstage: false), findsOneWidget);
    expect(find.text('Route: 1', skipOffstage: false), findsOneWidget);
    expect(find.text('Route: root', skipOffstage: false), findsOneWidget);

    // When we hit 1.0 all but root and current have been removed.
    await tester.pump(kFourTenthsOfTheTransitionDuration);
    expect(find.text('Route: 3', skipOffstage: false), findsNothing);
    expect(find.text('Route: 4'), findsOneWidget);
    expect(route4Entry.value, 1.0);
    expect(find.text('Route: 2', skipOffstage: false), findsNothing);
    expect(find.text('Route: 1', skipOffstage: false), findsNothing);
    expect(find.text('Route: root', skipOffstage: false), findsOneWidget);

    navigator.currentState.pop();
    await tester.pumpAndSettle();

    expect(find.text('Route: root'), findsOneWidget);
    expect(find.text('Route: 4', skipOffstage: false), findsNothing);
  });

  testWidgets('Wrapping TickerMode can turn off ticking in routes', (WidgetTester tester) async {
    int tickCount = 0;
    Widget widgetUnderTest({bool enabled}) {
      return TickerMode(
        enabled: enabled,
        child: Directionality(
          textDirection: TextDirection.ltr,
          child: Navigator(
            initialRoute: 'root',
            onGenerateRoute: (RouteSettings settings) {
              return MaterialPageRoute<void>(
                settings: settings,
                builder: (BuildContext context) {
                  return _TickingWidget(
                    onTick: () {
                      tickCount++;
                    },
                  );
                },
              );
            },
          ),
        ),
      );
    }

    await tester.pumpWidget(widgetUnderTest(enabled: false));
    expect(tickCount, 0);
    await tester.pump(const Duration(seconds: 1));
    await tester.pump(const Duration(seconds: 1));
    await tester.pump(const Duration(seconds: 1));
    await tester.pump(const Duration(seconds: 1));
    expect(tickCount, 0);

    await tester.pumpWidget(widgetUnderTest(enabled: true));
    expect(tickCount, 0);
    await tester.pump(const Duration(seconds: 1));
    await tester.pump(const Duration(seconds: 1));
    await tester.pump(const Duration(seconds: 1));
    await tester.pump(const Duration(seconds: 1));
    expect(tickCount, 4);
  });

  testWidgets('Route announce correctly for first route and last route', (WidgetTester tester) async {
    // Regression test for https://github.com/flutter/flutter/issues/57133.
    Route<void> previousOfFirst = NotAnnounced();
    Route<void> nextOfFirst = NotAnnounced();
    Route<void> popNextOfFirst = NotAnnounced();
    Route<void> firstRoute;

    Route<void> previousOfSecond = NotAnnounced();
    Route<void> nextOfSecond = NotAnnounced();
    Route<void> popNextOfSecond = NotAnnounced();
    Route<void> secondRoute;

    final GlobalKey<NavigatorState> navigator = GlobalKey<NavigatorState>();
    await tester.pumpWidget(
      MaterialApp(
        navigatorKey: navigator,
        initialRoute: '/second',
        onGenerateRoute: (RouteSettings settings) {
          if (settings.name == '/') {
            firstRoute = RouteAnnouncementSpy(
              onDidChangeNext: (Route<void> next) => nextOfFirst = next,
              onDidChangePrevious: (Route<void> previous) => previousOfFirst = previous,
              onDidPopNext: (Route<void> next) => popNextOfFirst = next,
              settings: settings,
            );
            return firstRoute;
          }
          secondRoute = RouteAnnouncementSpy(
            onDidChangeNext: (Route<void> next) => nextOfSecond = next,
            onDidChangePrevious: (Route<void> previous) => previousOfSecond = previous,
            onDidPopNext: (Route<void> next) => popNextOfSecond = next,
            settings: settings,
          );
          return secondRoute;
        },
      ),
    );
    await tester.pumpAndSettle();

    expect(previousOfFirst, isNull);
    expect(nextOfFirst, secondRoute);
    expect(popNextOfFirst, isA<NotAnnounced>());

    expect(previousOfSecond, firstRoute);
    expect(nextOfSecond, isNull);
    expect(popNextOfSecond, isA<NotAnnounced>());

    navigator.currentState.pop();
    expect(popNextOfFirst, secondRoute);
  });

  testWidgets('hero controller scope works', (WidgetTester tester) async {
    final GlobalKey<NavigatorState> top = GlobalKey<NavigatorState>();
    final GlobalKey<NavigatorState> sub = GlobalKey<NavigatorState>();

    final List<NavigatorObservation> observations = <NavigatorObservation>[];
    final HeroControllerSpy spy = HeroControllerSpy()
      ..onPushed = (Route<dynamic> route, Route<dynamic> previousRoute) {
        observations.add(
          NavigatorObservation(
            current: route?.settings?.name,
            previous: previousRoute?.settings?.name,
            operation: 'didPush'
          )
        );
      };
    await tester.pumpWidget(
      HeroControllerScope(
        controller: spy,
        child: Directionality(
          textDirection: TextDirection.ltr,
          child: Navigator(
            key: top,
            initialRoute: 'top1',
            onGenerateRoute: (RouteSettings s) {
              return MaterialPageRoute<void>(
                builder: (BuildContext c) {
                  return Navigator(
                    key: sub,
                    initialRoute: 'sub1',
                    onGenerateRoute: (RouteSettings s) {
                      return MaterialPageRoute<void>(
                        builder: (BuildContext c) {
                          return const Placeholder();
                        },
                        settings: s,
                      );
                    },
                  );
                },
                settings: s,
              );
            },
          ),
        )
      )
    );
    // It should only observe the top navigator.
    expect(observations.length, 1);
    expect(observations[0].current, 'top1');
    expect(observations[0].previous, isNull);

    sub.currentState.push(MaterialPageRoute<void>(
      settings: const RouteSettings(name:'sub2'),
      builder: (BuildContext context) => const Text('sub2')
    ));
    await tester.pumpAndSettle();

    expect(find.text('sub2'), findsOneWidget);
    // It should not record sub navigator.
    expect(observations.length, 1);

    top.currentState.push(MaterialPageRoute<void>(
      settings: const RouteSettings(name:'top2'),
      builder: (BuildContext context) => const Text('top2')
    ));
    await tester.pumpAndSettle();
    expect(observations.length, 2);
    expect(observations[1].current, 'top2');
    expect(observations[1].previous, 'top1');
  });

  testWidgets('hero controller can correctly transfer subscription - replacing navigator', (WidgetTester tester) async {
    final GlobalKey<NavigatorState> key1 = GlobalKey<NavigatorState>();
    final GlobalKey<NavigatorState> key2 = GlobalKey<NavigatorState>();

    final List<NavigatorObservation> observations = <NavigatorObservation>[];
    final HeroControllerSpy spy = HeroControllerSpy()
      ..onPushed = (Route<dynamic> route, Route<dynamic> previousRoute) {
        observations.add(
          NavigatorObservation(
            current: route?.settings?.name,
            previous: previousRoute?.settings?.name,
            operation: 'didPush'
          )
        );
      };
    await tester.pumpWidget(
      HeroControllerScope(
        controller: spy,
        child: Directionality(
          textDirection: TextDirection.ltr,
          child: Navigator(
            key: key1,
            initialRoute: 'navigator1',
            onGenerateRoute: (RouteSettings s) {
              return MaterialPageRoute<void>(
                builder: (BuildContext c) {
                  return const Placeholder();
                },
                settings: s,
              );
            },
          ),
        )
      )
    );
    // Transfer the subscription to another navigator
    await tester.pumpWidget(
      HeroControllerScope(
        controller: spy,
        child: Directionality(
          textDirection: TextDirection.ltr,
          child: Navigator(
            key: key2,
            initialRoute: 'navigator2',
            onGenerateRoute: (RouteSettings s) {
              return MaterialPageRoute<void>(
                builder: (BuildContext c) {
                  return const Placeholder();
                },
                settings: s,
              );
            },
          ),
        )
      )
    );
    observations.clear();

    key2.currentState.push(MaterialPageRoute<void>(
      settings: const RouteSettings(name:'new route'),
      builder: (BuildContext context) => const Text('new route')
    ));
    await tester.pumpAndSettle();

    expect(find.text('new route'), findsOneWidget);
    // It should record from the new navigator.
    expect(observations.length, 1);
    expect(observations[0].current, 'new route');
    expect(observations[0].previous, 'navigator2');
  });

  testWidgets('hero controller can correctly transfer subscription - swapping navigator', (WidgetTester tester) async {
    final GlobalKey<NavigatorState> key1 = GlobalKey<NavigatorState>();
    final GlobalKey<NavigatorState> key2 = GlobalKey<NavigatorState>();

    final List<NavigatorObservation> observations1 = <NavigatorObservation>[];
    final HeroControllerSpy spy1 = HeroControllerSpy()
      ..onPushed = (Route<dynamic> route, Route<dynamic> previousRoute) {
        observations1.add(
          NavigatorObservation(
            current: route?.settings?.name,
            previous: previousRoute?.settings?.name,
            operation: 'didPush'
          )
        );
      };
    final List<NavigatorObservation> observations2 = <NavigatorObservation>[];
    final HeroControllerSpy spy2 = HeroControllerSpy()
      ..onPushed = (Route<dynamic> route, Route<dynamic> previousRoute) {
        observations2.add(
          NavigatorObservation(
            current: route?.settings?.name,
            previous: previousRoute?.settings?.name,
            operation: 'didPush'
          )
        );
      };
    await tester.pumpWidget(
      Directionality(
        textDirection: TextDirection.ltr,
        child: Stack(
          children: <Widget>[
            HeroControllerScope(
              controller: spy1,
              child: Navigator(
                key: key1,
                initialRoute: 'navigator1',
                onGenerateRoute: (RouteSettings s) {
                  return MaterialPageRoute<void>(
                    builder: (BuildContext c) {
                      return const Placeholder();
                    },
                    settings: s,
                  );
                },
              )
            ),
            HeroControllerScope(
              controller: spy2,
              child: Navigator(
                key: key2,
                initialRoute: 'navigator2',
                onGenerateRoute: (RouteSettings s) {
                  return MaterialPageRoute<void>(
                    builder: (BuildContext c) {
                      return const Placeholder();
                    },
                    settings: s,
                  );
                },
              )
            ),
          ],
        ),
      ),
    );
    expect(observations1.length, 1);
    expect(observations1[0].current, 'navigator1');
    expect(observations1[0].previous, isNull);
    expect(observations2.length, 1);
    expect(observations2[0].current, 'navigator2');
    expect(observations2[0].previous, isNull);

    // Swaps the spies.
    await tester.pumpWidget(
      Directionality(
        textDirection: TextDirection.ltr,
        child: Stack(
          children: <Widget>[
            HeroControllerScope(
              controller: spy2,
              child: Navigator(
                key: key1,
                initialRoute: 'navigator1',
                onGenerateRoute: (RouteSettings s) {
                  return MaterialPageRoute<void>(
                    builder: (BuildContext c) {
                      return const Placeholder();
                    },
                    settings: s,
                  );
                },
              )
            ),
            HeroControllerScope(
              controller: spy1,
              child: Navigator(
                key: key2,
                initialRoute: 'navigator2',
                onGenerateRoute: (RouteSettings s) {
                  return MaterialPageRoute<void>(
                    builder: (BuildContext c) {
                      return const Placeholder();
                    },
                    settings: s,
                  );
                },
              )
            ),
          ],
        ),
      ),
    );

    // Pushes a route to navigator2.
    key2.currentState.push(MaterialPageRoute<void>(
      settings: const RouteSettings(name:'new route2'),
      builder: (BuildContext context) => const Text('new route2')
    ));
    await tester.pumpAndSettle();
    expect(find.text('new route2'), findsOneWidget);
    // The spy1 should record the push in navigator2.
    expect(observations1.length, 2);
    expect(observations1[1].current, 'new route2');
    expect(observations1[1].previous, 'navigator2');
    // The spy2 should not record anything.
    expect(observations2.length, 1);

    // Pushes a route to navigator1
    key1.currentState.push(MaterialPageRoute<void>(
      settings: const RouteSettings(name:'new route1'),
      builder: (BuildContext context) => const Text('new route1')
    ));
    await tester.pumpAndSettle();
    expect(find.text('new route1'), findsOneWidget);
    // The spy1 should not record anything.
    expect(observations1.length, 2);
    // The spy2 should record the push in navigator1.
    expect(observations2.length, 2);
    expect(observations2[1].current, 'new route1');
    expect(observations2[1].previous, 'navigator1');
  });

  testWidgets('hero controller subscribes to multiple navigators does throw', (WidgetTester tester) async {
    final HeroControllerSpy spy = HeroControllerSpy();
    await tester.pumpWidget(
      HeroControllerScope(
        controller: spy,
        child: Directionality(
          textDirection: TextDirection.ltr,
          child: Stack(
            children: <Widget>[
              Navigator(
                initialRoute: 'navigator1',
                onGenerateRoute: (RouteSettings s) {
                  return MaterialPageRoute<void>(
                    builder: (BuildContext c) {
                      return const Placeholder();
                    },
                    settings: s,
                  );
                },
              ),
              Navigator(
                initialRoute: 'navigator2',
                onGenerateRoute: (RouteSettings s) {
                  return MaterialPageRoute<void>(
                    builder: (BuildContext c) {
                      return const Placeholder();
                    },
                    settings: s,
                  );
                },
              ),
            ],
          ),
        ),
      ),
    );
    expect(tester.takeException(), isAssertionError);
  });

  group('Page api', (){
    Widget buildNavigator({
      List<Page<dynamic>> pages,
      PopPageCallback onPopPage,
      GlobalKey<NavigatorState> key,
      TransitionDelegate<dynamic> transitionDelegate,
      List<NavigatorObserver> observers = const <NavigatorObserver>[],
    }) {
      return MediaQuery(
        data: MediaQueryData.fromWindow(WidgetsBinding.instance.window),
        child: Localizations(
          locale: const Locale('en', 'US'),
          delegates: const <LocalizationsDelegate<dynamic>>[
            DefaultMaterialLocalizations.delegate,
            DefaultWidgetsLocalizations.delegate
          ],
          child: Directionality(
            textDirection: TextDirection.ltr,
            child: Navigator(
              key: key,
              pages: pages,
              onPopPage: onPopPage,
              observers: observers,
              transitionDelegate: transitionDelegate ?? const DefaultTransitionDelegate<dynamic>(),
            ),
          ),
        ),
      );
    }

    testWidgets('can initialize with pages list', (WidgetTester tester) async {
      final GlobalKey<NavigatorState> navigator = GlobalKey<NavigatorState>();
      final List<TestPage> myPages = <TestPage>[
        const TestPage(key: ValueKey<String>('1'), name:'initial'),
        const TestPage(key: ValueKey<String>('2'), name:'second'),
        const TestPage(key: ValueKey<String>('3'), name:'third'),
      ];

      bool onPopPage(Route<dynamic> route, dynamic result) {
        myPages.removeWhere((Page<dynamic> page) => route.settings == page);
        return route.didPop(result);
      }

      await tester.pumpWidget(
        buildNavigator(pages: myPages, onPopPage: onPopPage, key: navigator)
      );
      expect(find.text('third'), findsOneWidget);
      expect(find.text('second'), findsNothing);
      expect(find.text('initial'), findsNothing);

      navigator.currentState.pop();
      await tester.pumpAndSettle();
      expect(find.text('third'), findsNothing);
      expect(find.text('second'), findsOneWidget);
      expect(find.text('initial'), findsNothing);

      navigator.currentState.pop();
      await tester.pumpAndSettle();
      expect(find.text('third'), findsNothing);
      expect(find.text('second'), findsNothing);
      expect(find.text('initial'), findsOneWidget);
    });

    testWidgets('can push and pop pages using page api', (WidgetTester tester) async {
      Animation<double> secondaryAnimationOfRouteOne;
      Animation<double> primaryAnimationOfRouteOne;
      Animation<double> secondaryAnimationOfRouteTwo;
      Animation<double> primaryAnimationOfRouteTwo;
      Animation<double> secondaryAnimationOfRouteThree;
      Animation<double> primaryAnimationOfRouteThree;
      final GlobalKey<NavigatorState> navigator = GlobalKey<NavigatorState>();
      List<Page<dynamic>> myPages = <Page<dynamic>>[
        CustomBuilderPage<void>(
          key: const ValueKey<String>('1'),
          name:'initial',
          routeBuilder: (BuildContext context, RouteSettings settings) {
            return PageRouteBuilder<void>(
              settings: settings,
              pageBuilder: (_, Animation<double> animation, Animation<double> secondaryAnimation) {
                secondaryAnimationOfRouteOne = secondaryAnimation;
                primaryAnimationOfRouteOne = animation;
                return const Text('initial');
              },
            );
          },
        ),
      ];

      bool onPopPage(Route<dynamic> route, dynamic result) {
        myPages.removeWhere((Page<dynamic> page) => route.settings == page);
        return route.didPop(result);
      }

      await tester.pumpWidget(
        buildNavigator(pages: myPages, onPopPage: onPopPage, key: navigator)
      );
      expect(find.text('initial'), findsOneWidget);

      myPages = <Page<dynamic>>[
        CustomBuilderPage<void>(
          key: const ValueKey<String>('1'),
          name:'initial',
          routeBuilder: (BuildContext context, RouteSettings settings) {
            return PageRouteBuilder<void>(
              settings: settings,
              pageBuilder: (_, Animation<double> animation, Animation<double> secondaryAnimation) {
                secondaryAnimationOfRouteOne = secondaryAnimation;
                primaryAnimationOfRouteOne = animation;
                return const Text('initial');
              },
            );
          },
        ),
        CustomBuilderPage<void>(
          key: const ValueKey<String>('2'),
          name:'second',
          routeBuilder: (BuildContext context, RouteSettings settings) {
            return PageRouteBuilder<void>(
              settings: settings,
              pageBuilder: (_, Animation<double> animation, Animation<double> secondaryAnimation) {
                secondaryAnimationOfRouteTwo = secondaryAnimation;
                primaryAnimationOfRouteTwo = animation;
                return const Text('second');
              },
            );
          },
        ),
        CustomBuilderPage<void>(
          key: const ValueKey<String>('3'),
          name:'third',
          routeBuilder: (BuildContext context, RouteSettings settings) {
            return PageRouteBuilder<void>(
              settings: settings,
              pageBuilder: (_, Animation<double> animation, Animation<double> secondaryAnimation) {
                secondaryAnimationOfRouteThree = secondaryAnimation;
                primaryAnimationOfRouteThree = animation;
                return const Text('third');
              },
            );
          },
        )
      ];

      await tester.pumpWidget(
        buildNavigator(pages: myPages, onPopPage: onPopPage, key: navigator)
      );
      // The third page is transitioning, and the secondary animation of first
      // page should chain with the third page. The animation of second page
      // won't start until the third page finishes transition.
      expect(secondaryAnimationOfRouteOne.value, primaryAnimationOfRouteThree.value);
      expect(primaryAnimationOfRouteOne.status, AnimationStatus.completed);
      expect(secondaryAnimationOfRouteTwo.status, AnimationStatus.dismissed);
      expect(primaryAnimationOfRouteTwo.status, AnimationStatus.dismissed);
      expect(secondaryAnimationOfRouteThree.status, AnimationStatus.dismissed);
      expect(primaryAnimationOfRouteThree.status, AnimationStatus.forward);

      await tester.pump(const Duration(milliseconds: 30));
      expect(secondaryAnimationOfRouteOne.value, primaryAnimationOfRouteThree.value);
      expect(primaryAnimationOfRouteOne.status, AnimationStatus.completed);
      expect(secondaryAnimationOfRouteTwo.status, AnimationStatus.dismissed);
      expect(primaryAnimationOfRouteTwo.status, AnimationStatus.dismissed);
      expect(secondaryAnimationOfRouteThree.status, AnimationStatus.dismissed);
      expect(primaryAnimationOfRouteThree.value, 0.1);
      await tester.pumpAndSettle();
      // After transition finishes, the routes' animations are correctly chained.
      expect(secondaryAnimationOfRouteOne.value, primaryAnimationOfRouteTwo.value);
      expect(primaryAnimationOfRouteOne.status, AnimationStatus.completed);
      expect(secondaryAnimationOfRouteTwo.value, primaryAnimationOfRouteThree.value);
      expect(primaryAnimationOfRouteTwo.status, AnimationStatus.completed);
      expect(secondaryAnimationOfRouteThree.status, AnimationStatus.dismissed);
      expect(primaryAnimationOfRouteThree.status, AnimationStatus.completed);
      expect(find.text('third'), findsOneWidget);
      expect(find.text('second'), findsNothing);
      expect(find.text('initial'), findsNothing);
      // Starts pops the pages using page api and verify the animations chain
      // correctly.

      myPages = <Page<dynamic>>[
        CustomBuilderPage<void>(
          key: const ValueKey<String>('1'),
          name:'initial',
          routeBuilder: (BuildContext context, RouteSettings settings) {
            return PageRouteBuilder<void>(
              settings: settings,
              pageBuilder: (_, Animation<double> animation, Animation<double> secondaryAnimation) {
                secondaryAnimationOfRouteOne = secondaryAnimation;
                primaryAnimationOfRouteOne = animation;
                return const Text('initial');
              },
            );
          },
        ),
        CustomBuilderPage<void>(
          key: const ValueKey<String>('2'),
          name:'second',
          routeBuilder: (BuildContext context, RouteSettings settings) {
            return PageRouteBuilder<void>(
              settings: settings,
              pageBuilder: (_, Animation<double> animation, Animation<double> secondaryAnimation) {
                secondaryAnimationOfRouteTwo = secondaryAnimation;
                primaryAnimationOfRouteTwo = animation;
                return const Text('second');
              },
            );
          },
        ),
      ];

      await tester.pumpWidget(
        buildNavigator(pages: myPages, onPopPage: onPopPage, key: navigator)
      );
      await tester.pump(const Duration(milliseconds: 30));
      expect(secondaryAnimationOfRouteOne.value, primaryAnimationOfRouteTwo.value);
      expect(primaryAnimationOfRouteOne.status, AnimationStatus.completed);
      expect(secondaryAnimationOfRouteTwo.value, primaryAnimationOfRouteThree.value);
      expect(primaryAnimationOfRouteTwo.status, AnimationStatus.completed);
      expect(secondaryAnimationOfRouteThree.status, AnimationStatus.dismissed);
      expect(primaryAnimationOfRouteThree.value, 0.9);
      await tester.pumpAndSettle();
      expect(secondaryAnimationOfRouteOne.value, primaryAnimationOfRouteTwo.value);
      expect(primaryAnimationOfRouteOne.status, AnimationStatus.completed);
      expect(secondaryAnimationOfRouteTwo.value, primaryAnimationOfRouteThree.value);
      expect(primaryAnimationOfRouteTwo.status, AnimationStatus.completed);
      expect(secondaryAnimationOfRouteThree.status, AnimationStatus.dismissed);
      expect(primaryAnimationOfRouteThree.status, AnimationStatus.dismissed);
    });

    testWidgets('can modify routes history and secondary animation still works', (WidgetTester tester) async {
      final GlobalKey<NavigatorState> navigator = GlobalKey<NavigatorState>();
      Animation<double> secondaryAnimationOfRouteOne;
      Animation<double> primaryAnimationOfRouteOne;
      Animation<double> secondaryAnimationOfRouteTwo;
      Animation<double> primaryAnimationOfRouteTwo;
      Animation<double> secondaryAnimationOfRouteThree;
      Animation<double> primaryAnimationOfRouteThree;
      List<Page<dynamic>> myPages = <CustomBuilderPage<void>>[
        CustomBuilderPage<void>(
          key: const ValueKey<String>('1'),
          name:'initial',
          routeBuilder: (BuildContext context, RouteSettings settings) {
            return PageRouteBuilder<void>(
              settings: settings,
              pageBuilder: (_, Animation<double> animation, Animation<double> secondaryAnimation) {
                secondaryAnimationOfRouteOne = secondaryAnimation;
                primaryAnimationOfRouteOne = animation;
                return const Text('initial');
              },
            );
          },
        ),
        CustomBuilderPage<void>(
          key: const ValueKey<String>('2'),
          name:'second',
          routeBuilder: (BuildContext context, RouteSettings settings) {
            return PageRouteBuilder<void>(
              settings: settings,
              pageBuilder: (_, Animation<double> animation, Animation<double> secondaryAnimation) {
                secondaryAnimationOfRouteTwo = secondaryAnimation;
                primaryAnimationOfRouteTwo = animation;
                return const Text('second');
              },
            );
          },
        ),
        CustomBuilderPage<void>(
          key: const ValueKey<String>('3'),
          name:'third',
          routeBuilder: (BuildContext context, RouteSettings settings) {
            return PageRouteBuilder<void>(
              settings: settings,
              pageBuilder: (_, Animation<double> animation, Animation<double> secondaryAnimation) {
                secondaryAnimationOfRouteThree = secondaryAnimation;
                primaryAnimationOfRouteThree = animation;
                return const Text('third');
              },
            );
          },
        ),
      ];
      bool onPopPage(Route<dynamic> route, dynamic result) {
        myPages.removeWhere((Page<dynamic> page) => route.settings == page);
        return route.didPop(result);
      }
      await tester.pumpWidget(
        buildNavigator(pages: myPages, onPopPage: onPopPage, key: navigator)
      );
      expect(find.text('third'), findsOneWidget);
      expect(find.text('second'), findsNothing);
      expect(find.text('initial'), findsNothing);
      expect(secondaryAnimationOfRouteOne.value, primaryAnimationOfRouteTwo.value);
      expect(primaryAnimationOfRouteOne.status, AnimationStatus.completed);
      expect(secondaryAnimationOfRouteTwo.value, primaryAnimationOfRouteThree.value);
      expect(primaryAnimationOfRouteTwo.status, AnimationStatus.completed);
      expect(secondaryAnimationOfRouteThree.status, AnimationStatus.dismissed);
      expect(primaryAnimationOfRouteThree.status, AnimationStatus.completed);

      myPages = myPages.reversed.toList();
      await tester.pumpWidget(
        buildNavigator(pages: myPages, onPopPage: onPopPage, key: navigator)
      );
      // Reversed routes are still chained up correctly.
      expect(secondaryAnimationOfRouteThree.value, primaryAnimationOfRouteTwo.value);
      expect(primaryAnimationOfRouteThree.status, AnimationStatus.completed);
      expect(secondaryAnimationOfRouteTwo.value, primaryAnimationOfRouteOne.value);
      expect(primaryAnimationOfRouteTwo.status, AnimationStatus.completed);
      expect(secondaryAnimationOfRouteOne.status, AnimationStatus.dismissed);
      expect(primaryAnimationOfRouteOne.status, AnimationStatus.completed);

      navigator.currentState.pop();
      await tester.pump();
      await tester.pump(const Duration(milliseconds: 30));
      expect(secondaryAnimationOfRouteThree.value, primaryAnimationOfRouteTwo.value);
      expect(primaryAnimationOfRouteThree.status, AnimationStatus.completed);
      expect(secondaryAnimationOfRouteTwo.value, primaryAnimationOfRouteOne.value);
      expect(primaryAnimationOfRouteTwo.status, AnimationStatus.completed);
      expect(secondaryAnimationOfRouteOne.status, AnimationStatus.dismissed);
      expect(primaryAnimationOfRouteOne.value, 0.9);
      await tester.pumpAndSettle();
      expect(secondaryAnimationOfRouteThree.value, primaryAnimationOfRouteTwo.value);
      expect(primaryAnimationOfRouteThree.status, AnimationStatus.completed);
      expect(secondaryAnimationOfRouteTwo.value, primaryAnimationOfRouteOne.value);
      expect(primaryAnimationOfRouteTwo.status, AnimationStatus.completed);
      expect(secondaryAnimationOfRouteOne.status, AnimationStatus.dismissed);
      expect(primaryAnimationOfRouteOne.status, AnimationStatus.dismissed);

      navigator.currentState.pop();
      await tester.pump();
      await tester.pump(const Duration(milliseconds: 30));
      expect(secondaryAnimationOfRouteThree.value, primaryAnimationOfRouteTwo.value);
      expect(primaryAnimationOfRouteThree.status, AnimationStatus.completed);
      expect(secondaryAnimationOfRouteTwo.value, primaryAnimationOfRouteOne.value);
      expect(primaryAnimationOfRouteTwo.value, 0.9);
      expect(secondaryAnimationOfRouteOne.status, AnimationStatus.dismissed);
      expect(primaryAnimationOfRouteOne.status, AnimationStatus.dismissed);
      await tester.pumpAndSettle();
      expect(secondaryAnimationOfRouteThree.value, primaryAnimationOfRouteTwo.value);
      expect(primaryAnimationOfRouteThree.status, AnimationStatus.completed);
      expect(secondaryAnimationOfRouteTwo.value, primaryAnimationOfRouteOne.value);
      expect(primaryAnimationOfRouteTwo.status, AnimationStatus.dismissed);
      expect(secondaryAnimationOfRouteOne.status, AnimationStatus.dismissed);
      expect(primaryAnimationOfRouteOne.status, AnimationStatus.dismissed);
    });

    testWidgets('can work with pageless route', (WidgetTester tester) async {
      final GlobalKey<NavigatorState> navigator = GlobalKey<NavigatorState>();
      List<TestPage> myPages = <TestPage>[
        const TestPage(key: ValueKey<String>('1'), name:'initial'),
        const TestPage(key: ValueKey<String>('2'), name:'second'),
      ];

      bool onPopPage(Route<dynamic> route, dynamic result) {
        myPages.removeWhere((Page<dynamic> page) => route.settings == page);
        return route.didPop(result);
      }

      await tester.pumpWidget(
        buildNavigator(pages: myPages, onPopPage: onPopPage, key: navigator)
      );
      expect(find.text('second'), findsOneWidget);
      expect(find.text('initial'), findsNothing);
      // Pushes two pageless routes to second page route
      navigator.currentState.push(
        MaterialPageRoute<void>(
          builder: (BuildContext context) => const Text('second-pageless1'),
          settings: null,
        )
      );
      navigator.currentState.push(
        MaterialPageRoute<void>(
          builder: (BuildContext context) => const Text('second-pageless2'),
          settings: null,
        )
      );
      await tester.pumpAndSettle();
      // Now the history should look like
      // [initial, second, second-pageless1, second-pageless2].
      expect(find.text('initial'), findsNothing);
      expect(find.text('second'), findsNothing);
      expect(find.text('second-pageless1'), findsNothing);
      expect(find.text('second-pageless2'), findsOneWidget);

      myPages = <TestPage>[
        const TestPage(key: ValueKey<String>('1'), name:'initial'),
        const TestPage(key: ValueKey<String>('2'), name:'second'),
        const TestPage(key: ValueKey<String>('3'), name:'third'),
      ];
      await tester.pumpWidget(
        buildNavigator(pages: myPages, onPopPage: onPopPage, key: navigator)
      );
      await tester.pumpAndSettle();
      expect(find.text('initial'), findsNothing);
      expect(find.text('second'), findsNothing);
      expect(find.text('second-pageless1'), findsNothing);
      expect(find.text('second-pageless2'), findsNothing);
      expect(find.text('third'), findsOneWidget);

      // Pushes one pageless routes to third page route
      navigator.currentState.push(
        MaterialPageRoute<void>(
          builder: (BuildContext context) => const Text('third-pageless1'),
          settings: null,
        )
      );
      await tester.pumpAndSettle();
      // Now the history should look like
      // [initial, second, second-pageless1, second-pageless2, third, third-pageless1].
      expect(find.text('initial'), findsNothing);
      expect(find.text('second'), findsNothing);
      expect(find.text('second-pageless1'), findsNothing);
      expect(find.text('second-pageless2'), findsNothing);
      expect(find.text('third'), findsNothing);
      expect(find.text('third-pageless1'), findsOneWidget);

      myPages = <TestPage>[
        const TestPage(key: ValueKey<String>('1'), name:'initial'),
        const TestPage(key: ValueKey<String>('3'), name:'third'),
        const TestPage(key: ValueKey<String>('2'), name:'second'),
      ];
      await tester.pumpWidget(
        buildNavigator(pages: myPages, onPopPage: onPopPage, key: navigator)
      );
      // Swaps the order without any adding or removing should not trigger any
      // transition. The routes should update without a pumpAndSettle
      // Now the history should look like
      // [initial, third, third-pageless1, second, second-pageless1, second-pageless2].
      expect(find.text('initial'), findsNothing);
      expect(find.text('third'), findsNothing);
      expect(find.text('third-pageless1'), findsNothing);
      expect(find.text('second'), findsNothing);
      expect(find.text('second-pageless1'), findsNothing);
      expect(find.text('second-pageless2'), findsOneWidget);
      // Pops the route one by one to make sure the order is correct.
      navigator.currentState.pop();
      await tester.pumpAndSettle();
      expect(find.text('initial'), findsNothing);
      expect(find.text('third'), findsNothing);
      expect(find.text('third-pageless1'), findsNothing);
      expect(find.text('second'), findsNothing);
      expect(find.text('second-pageless1'), findsOneWidget);
      expect(find.text('second-pageless2'), findsNothing);
      expect(myPages.length, 3);
      navigator.currentState.pop();
      await tester.pumpAndSettle();
      expect(find.text('initial'), findsNothing);
      expect(find.text('third'), findsNothing);
      expect(find.text('third-pageless1'), findsNothing);
      expect(find.text('second'), findsOneWidget);
      expect(find.text('second-pageless1'), findsNothing);
      expect(find.text('second-pageless2'), findsNothing);
      expect(myPages.length, 3);
      navigator.currentState.pop();
      await tester.pumpAndSettle();
      expect(find.text('initial'), findsNothing);
      expect(find.text('third'), findsNothing);
      expect(find.text('third-pageless1'), findsOneWidget);
      expect(find.text('second'), findsNothing);
      expect(find.text('second-pageless1'), findsNothing);
      expect(find.text('second-pageless2'), findsNothing);
      expect(myPages.length, 2);
      navigator.currentState.pop();
      await tester.pumpAndSettle();
      expect(find.text('initial'), findsNothing);
      expect(find.text('third'), findsOneWidget);
      expect(find.text('third-pageless1'), findsNothing);
      expect(find.text('second'), findsNothing);
      expect(find.text('second-pageless1'), findsNothing);
      expect(find.text('second-pageless2'), findsNothing);
      expect(myPages.length, 2);
      navigator.currentState.pop();
      await tester.pumpAndSettle();
      expect(find.text('initial'), findsOneWidget);
      expect(find.text('third'), findsNothing);
      expect(find.text('third-pageless1'), findsNothing);
      expect(find.text('second'), findsNothing);
      expect(find.text('second-pageless1'), findsNothing);
      expect(find.text('second-pageless2'), findsNothing);
      expect(myPages.length, 1);
    });

    testWidgets('complex case 1', (WidgetTester tester) async {
      final GlobalKey<NavigatorState> navigator = GlobalKey<NavigatorState>();
      List<TestPage> myPages = <TestPage>[
        const TestPage(key: ValueKey<String>('1'), name: 'initial'),
      ];
      bool onPopPage(Route<dynamic> route, dynamic result) {
        myPages.removeWhere((Page<dynamic> page) => route.settings == page);
        return route.didPop(result);
      }

      // Add initial page route with one pageless route.
      await tester.pumpWidget(
        buildNavigator(pages: myPages, onPopPage: onPopPage, key: navigator)
      );
      bool initialPageless1Completed = false;
      navigator.currentState.push(
        MaterialPageRoute<void>(
          builder: (BuildContext context) => const Text('initial-pageless1'),
          settings: null,
        )
      ).then((_) => initialPageless1Completed = true);
      await tester.pumpAndSettle();

      // Pushes second page route with two pageless routes.
      myPages = <TestPage>[
        const TestPage(key: ValueKey<String>('1'), name: 'initial'),
        const TestPage(key: ValueKey<String>('2'), name: 'second'),
      ];
      await tester.pumpWidget(
        buildNavigator(pages: myPages, onPopPage: onPopPage, key: navigator)
      );
      await tester.pumpAndSettle();
      bool secondPageless1Completed = false;
      navigator.currentState.push(
        MaterialPageRoute<void>(
          builder: (BuildContext context) => const Text('second-pageless1'),
          settings: null,
        )
      ).then((_) => secondPageless1Completed = true);
      await tester.pumpAndSettle();
      bool secondPageless2Completed = false;
      navigator.currentState.push(
        MaterialPageRoute<void>(
          builder: (BuildContext context) => const Text('second-pageless2'),
          settings: null,
        )
      ).then((_) => secondPageless2Completed = true);
      await tester.pumpAndSettle();

      // Pushes third page route with one pageless route.
      myPages = <TestPage>[
        const TestPage(key: ValueKey<String>('1'), name: 'initial'),
        const TestPage(key: ValueKey<String>('2'), name: 'second'),
        const TestPage(key: ValueKey<String>('3'), name: 'third'),
      ];
      await tester.pumpWidget(
        buildNavigator(pages: myPages, onPopPage: onPopPage, key: navigator)
      );
      await tester.pumpAndSettle();
      bool thirdPageless1Completed = false;
      navigator.currentState.push(
        MaterialPageRoute<void>(
          builder: (BuildContext context) => const Text('third-pageless1'),
          settings: null,
        )
      ).then((_) => thirdPageless1Completed = true);
      await tester.pumpAndSettle();

      // Nothing has been popped.
      expect(initialPageless1Completed, false);
      expect(secondPageless1Completed, false);
      expect(secondPageless2Completed, false);
      expect(thirdPageless1Completed, false);

      // Switches order and removes the initial page route.
      myPages = <TestPage>[
        const TestPage(key: ValueKey<String>('3'), name: 'third'),
        const TestPage(key: ValueKey<String>('2'), name: 'second'),
      ];
      await tester.pumpWidget(
        buildNavigator(pages: myPages, onPopPage: onPopPage, key: navigator)
      );
      // The pageless route of initial page route should be completed.
      expect(initialPageless1Completed, true);
      expect(secondPageless1Completed, false);
      expect(secondPageless2Completed, false);
      expect(thirdPageless1Completed, false);

      myPages = <TestPage>[
        const TestPage(key: ValueKey<String>('3'), name: 'third'),
      ];
      await tester.pumpWidget(
        buildNavigator(pages: myPages, onPopPage: onPopPage, key: navigator)
      );
      await tester.pumpAndSettle();
      expect(secondPageless1Completed, true);
      expect(secondPageless2Completed, true);
      expect(thirdPageless1Completed, false);

      myPages = <TestPage>[
        const TestPage(key: ValueKey<String>('4'), name: 'forth'),
      ];
      await tester.pumpWidget(
        buildNavigator(pages: myPages, onPopPage: onPopPage, key: navigator)
      );
      expect(thirdPageless1Completed, true);
      await tester.pumpAndSettle();
      expect(find.text('forth'), findsOneWidget);
    });

    testWidgets('complex case 1 - with always remove transition delegate', (WidgetTester tester) async {
      final GlobalKey<NavigatorState> navigator = GlobalKey<NavigatorState>();
      final AlwaysRemoveTransitionDelegate transitionDelegate = AlwaysRemoveTransitionDelegate();
      List<TestPage> myPages = <TestPage>[
        const TestPage(key: ValueKey<String>('1'), name: 'initial'),
      ];
      bool onPopPage(Route<dynamic> route, dynamic result) {
        myPages.removeWhere((Page<dynamic> page) => route.settings == page);
        return route.didPop(result);
      }

      // Add initial page route with one pageless route.
      await tester.pumpWidget(
        buildNavigator(
          pages: myPages,
          onPopPage: onPopPage,
          key: navigator,
          transitionDelegate: transitionDelegate
        )
      );
      bool initialPageless1Completed = false;
      navigator.currentState.push(
        MaterialPageRoute<void>(
          builder: (BuildContext context) => const Text('initial-pageless1'),
          settings: null,
        )
      ).then((_) => initialPageless1Completed = true);
      await tester.pumpAndSettle();

      // Pushes second page route with two pageless routes.
      myPages = <TestPage>[
        const TestPage(key: ValueKey<String>('1'), name: 'initial'),
        const TestPage(key: ValueKey<String>('2'), name: 'second'),
      ];
      await tester.pumpWidget(
        buildNavigator(
          pages: myPages,
          onPopPage: onPopPage,
          key: navigator,
          transitionDelegate: transitionDelegate
        )
      );
      bool secondPageless1Completed = false;
      navigator.currentState.push(
        MaterialPageRoute<void>(
          builder: (BuildContext context) => const Text('second-pageless1'),
          settings: null,
        )
      ).then((_) => secondPageless1Completed = true);
      await tester.pumpAndSettle();
      bool secondPageless2Completed = false;
      navigator.currentState.push(
        MaterialPageRoute<void>(
          builder: (BuildContext context) => const Text('second-pageless2'),
          settings: null,
        )
      ).then((_) => secondPageless2Completed = true);
      await tester.pumpAndSettle();

      // Pushes third page route with one pageless route.
      myPages = <TestPage>[
        const TestPage(key: ValueKey<String>('1'), name: 'initial'),
        const TestPage(key: ValueKey<String>('2'), name: 'second'),
        const TestPage(key: ValueKey<String>('3'), name: 'third'),
      ];
      await tester.pumpWidget(
        buildNavigator(
          pages: myPages,
          onPopPage: onPopPage,
          key: navigator,
          transitionDelegate: transitionDelegate
        )
      );
      bool thirdPageless1Completed = false;
      navigator.currentState.push(
        MaterialPageRoute<void>(
          builder: (BuildContext context) => const Text('third-pageless1'),
          settings: null,
        )
      ).then((_) => thirdPageless1Completed = true);
      await tester.pumpAndSettle();

      // Nothing has been popped.
      expect(initialPageless1Completed, false);
      expect(secondPageless1Completed, false);
      expect(secondPageless2Completed, false);
      expect(thirdPageless1Completed, false);

      // Switches order and removes the initial page route.
      myPages = <TestPage>[
        const TestPage(key: ValueKey<String>('3'), name: 'third'),
        const TestPage(key: ValueKey<String>('2'), name: 'second'),
      ];
      await tester.pumpWidget(
        buildNavigator(
          pages: myPages,
          onPopPage: onPopPage,
          key: navigator,
          transitionDelegate: transitionDelegate
        )
      );
      // The pageless route of initial page route should be removed without complete.
      expect(initialPageless1Completed, false);
      expect(secondPageless1Completed, false);
      expect(secondPageless2Completed, false);
      expect(thirdPageless1Completed, false);

      myPages = <TestPage>[
        const TestPage(key: ValueKey<String>('3'), name: 'third'),
      ];
      await tester.pumpWidget(
        buildNavigator(
          pages: myPages,
          onPopPage: onPopPage,
          key: navigator,
          transitionDelegate: transitionDelegate
        )
      );
      await tester.pumpAndSettle();
      expect(initialPageless1Completed, false);
      expect(secondPageless1Completed, false);
      expect(secondPageless2Completed, false);
      expect(thirdPageless1Completed, false);

      myPages = <TestPage>[
        const TestPage(key: ValueKey<String>('4'), name: 'forth'),
      ];
      await tester.pumpWidget(
        buildNavigator(
          pages: myPages,
          onPopPage: onPopPage,
          key: navigator,
          transitionDelegate: transitionDelegate
        )
      );
      await tester.pump();
      expect(initialPageless1Completed, false);
      expect(secondPageless1Completed, false);
      expect(secondPageless2Completed, false);
      expect(thirdPageless1Completed, false);
      expect(find.text('forth'), findsOneWidget);
    });

    testWidgets('can repush a page that was previously popped before it has finished popping', (WidgetTester tester) async {
      final GlobalKey<NavigatorState> navigator = GlobalKey<NavigatorState>();
      List<Page<dynamic>> myPages = <TestPage>[
        const TestPage(key: ValueKey<String>('1'), name: 'initial'),
        const TestPage(key: ValueKey<String>('2'), name: 'second'),
      ];
      bool onPopPage(Route<dynamic> route, dynamic result) {
        myPages.removeWhere((Page<dynamic> page) => route.settings == page);
        return route.didPop(result);
      }
      await tester.pumpWidget(
        buildNavigator(pages: myPages, onPopPage: onPopPage, key: navigator)
      );

      // Pops the second page route.
      myPages = <TestPage>[
        const TestPage(key: ValueKey<String>('1'), name: 'initial'),
      ];
      await tester.pumpWidget(
        buildNavigator(pages: myPages, onPopPage: onPopPage, key: navigator)
      );

      // Re-push the second page again before it finishes popping.
      myPages = <TestPage>[
        const TestPage(key: ValueKey<String>('1'), name: 'initial'),
        const TestPage(key: ValueKey<String>('2'), name: 'second'),
      ];
      await tester.pumpWidget(
        buildNavigator(pages: myPages, onPopPage: onPopPage, key: navigator)
      );

      // It should not crash the app.
      expect(tester.takeException(), isNull);
      await tester.pumpAndSettle();
      expect(find.text('second'), findsOneWidget);
    });

    testWidgets('can update pages before a route has finished popping', (WidgetTester tester) async {
      final GlobalKey<NavigatorState> navigator = GlobalKey<NavigatorState>();
      List<Page<dynamic>> myPages = <TestPage>[
        const TestPage(key: ValueKey<String>('1'), name: 'initial'),
        const TestPage(key: ValueKey<String>('2'), name: 'second'),
      ];
      bool onPopPage(Route<dynamic> route, dynamic result) {
        myPages.removeWhere((Page<dynamic> page) => route.settings == page);
        return route.didPop(result);
      }
      await tester.pumpWidget(
        buildNavigator(pages: myPages, onPopPage: onPopPage, key: navigator)
      );

      // Pops the second page route.
      myPages = <TestPage>[
        const TestPage(key: ValueKey<String>('1'), name: 'initial'),
      ];
      await tester.pumpWidget(
        buildNavigator(pages: myPages, onPopPage: onPopPage, key: navigator)
      );

      // Updates the pages again before second page finishes popping.
      myPages = <TestPage>[
        const TestPage(key: ValueKey<String>('1'), name: 'initial'),
      ];
      await tester.pumpWidget(
        buildNavigator(pages: myPages, onPopPage: onPopPage, key: navigator)
      );

      // It should not crash the app.
      expect(tester.takeException(), isNull);
      await tester.pumpAndSettle();
      expect(find.text('initial'), findsOneWidget);
    });

    testWidgets('pages remove and add trigger observer in the right order', (WidgetTester tester) async {
      final GlobalKey<NavigatorState> navigator = GlobalKey<NavigatorState>();
      List<TestPage> myPages = <TestPage>[
        const TestPage(key: ValueKey<String>('1'), name:'first'),
        const TestPage(key: ValueKey<String>('2'), name:'second'),
        const TestPage(key: ValueKey<String>('3'), name:'third'),
      ];
      final List<NavigatorObservation> observations = <NavigatorObservation>[];
      final TestObserver observer = TestObserver()
        ..onPushed = (Route<dynamic> route, Route<dynamic> previousRoute) {
          observations.add(
            NavigatorObservation(
              current: route?.settings?.name,
              previous: previousRoute?.settings?.name,
              operation: 'push'
            )
          );
        }
        ..onRemoved = (Route<dynamic> route, Route<dynamic> previousRoute) {
          observations.add(
            NavigatorObservation(
              current: route?.settings?.name,
              previous: previousRoute?.settings?.name,
              operation: 'remove'
            )
          );
        };
      bool onPopPage(Route<dynamic> route, dynamic result) => false;

      await tester.pumpWidget(
        buildNavigator(
          pages: myPages,
          onPopPage: onPopPage,
          key: navigator,
          observers: <NavigatorObserver>[observer],
        )
      );
      myPages = <TestPage>[
        const TestPage(key: ValueKey<String>('4'), name:'forth'),
        const TestPage(key: ValueKey<String>('5'), name:'fifth'),
      ];

      await tester.pumpWidget(
        buildNavigator(
          pages: myPages,
          onPopPage: onPopPage,
          key: navigator,
          observers: <NavigatorObserver>[observer],
        )
      );

      await tester.pumpAndSettle();
      expect(observations.length, 8);
      // Initial routes are pushed.
      expect(observations[0].operation, 'push');
      expect(observations[0].current, 'first');
      expect(observations[0].previous, isNull);

      expect(observations[1].operation, 'push');
      expect(observations[1].current, 'second');
      expect(observations[1].previous, 'first');

      expect(observations[2].operation, 'push');
      expect(observations[2].current, 'third');
      expect(observations[2].previous, 'second');

      // Pages are updated.
      // New routes are pushed before removing the initial routes.
      expect(observations[3].operation, 'push');
      expect(observations[3].current, 'forth');
      expect(observations[3].previous, 'third');

      expect(observations[4].operation, 'push');
      expect(observations[4].current, 'fifth');
      expect(observations[4].previous, 'forth');

      // Initial routes are removed.
      expect(observations[5].operation, 'remove');
      expect(observations[5].current, 'third');
      expect(observations[5].previous, isNull);

      expect(observations[6].operation, 'remove');
      expect(observations[6].current, 'second');
      expect(observations[6].previous, isNull);

      expect(observations[7].operation, 'remove');
      expect(observations[7].current, 'first');
      expect(observations[7].previous, isNull);
    });
  });
}

typedef AnnouncementCallBack = void Function(Route<dynamic>);

class NotAnnounced extends Route<void> {/* A place holder for not announced route*/}

class RouteAnnouncementSpy extends Route<void> {
  RouteAnnouncementSpy({
    this.onDidChangePrevious,
    this.onDidChangeNext,
    this.onDidPopNext,
    RouteSettings settings,
  }) : super(settings: settings);
  final AnnouncementCallBack onDidChangePrevious;
  final AnnouncementCallBack onDidChangeNext;
  final AnnouncementCallBack onDidPopNext;

  @override
  List<OverlayEntry> get overlayEntries => <OverlayEntry>[
    OverlayEntry(
      builder: (BuildContext context) => const Placeholder(),
    )
  ];

  @override
  void didChangeNext(Route<dynamic> nextRoute) {
    super.didChangeNext(nextRoute);
    if (onDidChangeNext != null)
      onDidChangeNext(nextRoute);
  }

  @override
  void didChangePrevious(Route<dynamic> previousRoute) {
    super.didChangePrevious(previousRoute);
    if (onDidChangePrevious != null)
      onDidChangePrevious(previousRoute);
  }

  @override
  void didPopNext(Route<dynamic> nextRoute) {
    super.didPopNext(nextRoute);
    if (onDidPopNext != null)
      onDidPopNext(nextRoute);
  }
}

class _TickingWidget extends StatefulWidget {
  const _TickingWidget({this.onTick});

  final VoidCallback onTick;

  @override
  State<_TickingWidget> createState() => _TickingWidgetState();
}

class _TickingWidgetState extends State<_TickingWidget> with SingleTickerProviderStateMixin {
  Ticker _ticker;

  @override
  void initState() {
    super.initState();
    _ticker = createTicker((Duration _) {
      widget.onTick();
    })..start();
  }

  @override
  Widget build(BuildContext context) {
    return Container();
  }

  @override
  void dispose() {
    _ticker.dispose();
    super.dispose();
  }
}

class AlwaysRemoveTransitionDelegate extends TransitionDelegate<void> {
  @override
  Iterable<RouteTransitionRecord> resolve({
    List<RouteTransitionRecord> newPageRouteHistory,
    Map<RouteTransitionRecord, RouteTransitionRecord> locationToExitingPageRoute,
    Map<RouteTransitionRecord, List<RouteTransitionRecord>> pageRouteToPagelessRoutes,
  }) {
    final List<RouteTransitionRecord> results = <RouteTransitionRecord>[];
    void handleExitingRoute(RouteTransitionRecord location) {
      if (!locationToExitingPageRoute.containsKey(location))
        return;

      final RouteTransitionRecord exitingPageRoute = locationToExitingPageRoute[location];
      if (exitingPageRoute.isWaitingForExitingDecision) {
        final bool hasPagelessRoute = pageRouteToPagelessRoutes.containsKey(exitingPageRoute);
        exitingPageRoute.markForRemove();
        if (hasPagelessRoute) {
          final List<RouteTransitionRecord> pagelessRoutes = pageRouteToPagelessRoutes[exitingPageRoute];
          for (final RouteTransitionRecord pagelessRoute in pagelessRoutes) {
            pagelessRoute.markForRemove();
          }
        }
      }
      results.add(exitingPageRoute);

      handleExitingRoute(exitingPageRoute);
    }
    handleExitingRoute(null);

    for (final RouteTransitionRecord pageRoute in newPageRouteHistory) {
      if (pageRoute.isWaitingForEnteringDecision) {
        pageRoute.markForAdd();
      }
      results.add(pageRoute);
      handleExitingRoute(pageRoute);

    }
    return results;
  }
}

class TestPage extends Page<void> {
  const TestPage({
    LocalKey key,
    String name,
    Object arguments,
  }) : super(key: key, name: name, arguments: arguments);

  @override
  Route<void> createRoute(BuildContext context) {
    return MaterialPageRoute<void>(
      builder: (BuildContext context) => Text(name),
      settings: this,
    );
  }
}

class NoAnimationPageRoute extends PageRouteBuilder<void> {
  NoAnimationPageRoute({WidgetBuilder pageBuilder})
      : super(pageBuilder: (BuildContext context, __, ___) {
          return pageBuilder(context);
        });

  @override
  AnimationController createAnimationController() {
    return super.createAnimationController()..value = 1.0;
  }
}

class StatefulTestWidget extends StatefulWidget {
  const StatefulTestWidget({Key key}) : super(key: key);

  @override
  State<StatefulTestWidget> createState() => StatefulTestState();
}

class StatefulTestState extends State<StatefulTestWidget> {
  int rebuildCount = 0;

  @override
  Widget build(BuildContext context) {
    rebuildCount += 1;
    return Container();
  }
}

class HeroControllerSpy extends HeroController {
  OnObservation onPushed;
  @override
  void didPush(Route<dynamic> route, Route<dynamic> previousRoute) {
    if (onPushed != null) {
      onPushed(route, previousRoute);
    }
  }
}

class NavigatorObservation {
  const NavigatorObservation({this.previous, this.current, this.operation});
  final String previous;
  final String current;
  final String operation;
}
