// 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.

import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter/cupertino.dart' show CupertinoPageRoute;
import 'package:flutter/rendering.dart';
import 'package:flutter_test/flutter_test.dart';

import '../rendering/mock_canvas.dart';

void main() {
  testWidgets('test page transition', (WidgetTester tester) async {
    await tester.pumpWidget(
      MaterialApp(
        home: const Material(child: Text('Page 1')),
        routes: <String, WidgetBuilder>{
          '/next': (BuildContext context) {
            return const Material(child: Text('Page 2'));
          },
        },
      ),
    );

    final Offset widget1TopLeft = tester.getTopLeft(find.text('Page 1'));

    tester.state<NavigatorState>(find.byType(Navigator)).pushNamed('/next');
    await tester.pump();
    await tester.pump(const Duration(milliseconds: 1));

    FadeTransition widget2Opacity =
        tester.element(find.text('Page 2')).findAncestorWidgetOfExactType<FadeTransition>()!;
    Offset widget2TopLeft = tester.getTopLeft(find.text('Page 2'));
    final Size widget2Size = tester.getSize(find.text('Page 2'));

    // Android transition is vertical only.
    expect(widget1TopLeft.dx == widget2TopLeft.dx, true);
    // Page 1 is above page 2 mid-transition.
    expect(widget1TopLeft.dy < widget2TopLeft.dy, true);
    // Animation begins 3/4 of the way up the page.
    expect(widget2TopLeft.dy < widget2Size.height / 4.0, true);
    // Animation starts with page 2 being near transparent.
    expect(widget2Opacity.opacity.value < 0.01, true);

    await tester.pump(const Duration(milliseconds: 300));

    // Page 2 covers page 1.
    expect(find.text('Page 1'), findsNothing);
    expect(find.text('Page 2'), isOnstage);

    tester.state<NavigatorState>(find.byType(Navigator)).pop();
    await tester.pump();
    await tester.pump(const Duration(milliseconds: 1));

    widget2Opacity =
        tester.element(find.text('Page 2')).findAncestorWidgetOfExactType<FadeTransition>()!;
    widget2TopLeft = tester.getTopLeft(find.text('Page 2'));

    // Page 2 starts to move down.
    expect(widget1TopLeft.dy < widget2TopLeft.dy, true);
    // Page 2 starts to lose opacity.
    expect(widget2Opacity.opacity.value < 1.0, true);

    await tester.pump(const Duration(milliseconds: 300));

    expect(find.text('Page 1'), isOnstage);
    expect(find.text('Page 2'), findsNothing);
  }, variant: TargetPlatformVariant.only(TargetPlatform.android));

  testWidgets('test page transition', (WidgetTester tester) async {
    final Key page2Key = UniqueKey();
    await tester.pumpWidget(
      MaterialApp(
        home: const Material(child: Text('Page 1')),
        routes: <String, WidgetBuilder>{
          '/next': (BuildContext context) {
            return Material(
              key: page2Key,
              child: const Text('Page 2'),
            );
          },
        },
      ),
    );

    final Offset widget1InitialTopLeft = tester.getTopLeft(find.text('Page 1'));

    tester.state<NavigatorState>(find.byType(Navigator)).pushNamed('/next');

    await tester.pump();
    await tester.pump(const Duration(milliseconds: 150));

    Offset widget1TransientTopLeft = tester.getTopLeft(find.text('Page 1'));
    Offset widget2TopLeft = tester.getTopLeft(find.text('Page 2'));
    final RenderDecoratedBox box = tester.element(find.byKey(page2Key))
        .findAncestorRenderObjectOfType<RenderDecoratedBox>()!;

    // Page 1 is moving to the left.
    expect(widget1TransientTopLeft.dx < widget1InitialTopLeft.dx, true);
    // Page 1 isn't moving vertically.
    expect(widget1TransientTopLeft.dy == widget1InitialTopLeft.dy, true);
    // iOS transition is horizontal only.
    expect(widget1InitialTopLeft.dy == widget2TopLeft.dy, true);
    // Page 2 is coming in from the right.
    expect(widget2TopLeft.dx > widget1InitialTopLeft.dx, true);
    // The shadow should be drawn to one screen width to the left of where
    // the page 2 box is. `paints` tests relative to the painter's given canvas
    // rather than relative to the screen so assert that it's one screen
    // width to the left of 0 offset box rect and nothing is drawn inside the
    // box's rect.
    expect(box, paints..rect(
      rect: const Rect.fromLTWH(-800.0, 0.0, 800.0, 600.0)
    ));

    await tester.pumpAndSettle();

    // Page 2 covers page 1.
    expect(find.text('Page 1'), findsNothing);
    expect(find.text('Page 2'), isOnstage);

    tester.state<NavigatorState>(find.byType(Navigator)).pop();
    await tester.pump();
    await tester.pump(const Duration(milliseconds: 100));

    widget1TransientTopLeft = tester.getTopLeft(find.text('Page 1'));
    widget2TopLeft = tester.getTopLeft(find.text('Page 2'));

    // Page 1 is coming back from the left.
    expect(widget1TransientTopLeft.dx < widget1InitialTopLeft.dx, true);
    // Page 1 isn't moving vertically.
    expect(widget1TransientTopLeft.dy == widget1InitialTopLeft.dy, true);
    // iOS transition is horizontal only.
    expect(widget1InitialTopLeft.dy == widget2TopLeft.dy, true);
    // Page 2 is leaving towards the right.
    expect(widget2TopLeft.dx > widget1InitialTopLeft.dx, true);

    await tester.pumpAndSettle();

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

    widget1TransientTopLeft = tester.getTopLeft(find.text('Page 1'));

    // Page 1 is back where it started.
    expect(widget1InitialTopLeft == widget1TransientTopLeft, true);
  }, variant: const TargetPlatformVariant(<TargetPlatform>{ TargetPlatform.iOS, TargetPlatform.macOS }));

  testWidgets('test fullscreen dialog transition', (WidgetTester tester) async {
    await tester.pumpWidget(
      const MaterialApp(
        home: Material(child: Text('Page 1')),
      ),
    );

    final Offset widget1InitialTopLeft = tester.getTopLeft(find.text('Page 1'));

    tester.state<NavigatorState>(find.byType(Navigator)).push(MaterialPageRoute<void>(
      builder: (BuildContext context) {
        return const Material(child: Text('Page 2'));
      },
      fullscreenDialog: true,
    ));

    await tester.pump();
    await tester.pump(const Duration(milliseconds: 100));

    Offset widget1TransientTopLeft = tester.getTopLeft(find.text('Page 1'));
    Offset widget2TopLeft = tester.getTopLeft(find.text('Page 2'));

    // Page 1 doesn't move.
    expect(widget1TransientTopLeft == widget1InitialTopLeft, true);
    // Fullscreen dialogs transitions vertically only.
    expect(widget1InitialTopLeft.dx == widget2TopLeft.dx, true);
    // Page 2 is coming in from the bottom.
    expect(widget2TopLeft.dy > widget1InitialTopLeft.dy, true);

    await tester.pumpAndSettle();

    // Page 2 covers page 1.
    expect(find.text('Page 1'), findsNothing);
    expect(find.text('Page 2'), isOnstage);

    tester.state<NavigatorState>(find.byType(Navigator)).pop();
    await tester.pump();
    await tester.pump(const Duration(milliseconds: 100));

    widget1TransientTopLeft = tester.getTopLeft(find.text('Page 1'));
    widget2TopLeft = tester.getTopLeft(find.text('Page 2'));

    // Page 1 doesn't move.
    expect(widget1TransientTopLeft == widget1InitialTopLeft, true);
    // Fullscreen dialogs transitions vertically only.
    expect(widget1InitialTopLeft.dx == widget2TopLeft.dx, true);
    // Page 2 is leaving towards the bottom.
    expect(widget2TopLeft.dy > widget1InitialTopLeft.dy, true);

    await tester.pumpAndSettle();

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

    widget1TransientTopLeft = tester.getTopLeft(find.text('Page 1'));

    // Page 1 is back where it started.
    expect(widget1InitialTopLeft == widget1TransientTopLeft, true);
  }, variant: const TargetPlatformVariant(<TargetPlatform>{ TargetPlatform.iOS, TargetPlatform.macOS }));

  testWidgets('test no back gesture on Android', (WidgetTester tester) async {
    await tester.pumpWidget(
      MaterialApp(
        home: const Scaffold(body: Text('Page 1')),
        routes: <String, WidgetBuilder>{
          '/next': (BuildContext context) {
            return const Scaffold(body: Text('Page 2'));
          },
        },
      ),
    );

    tester.state<NavigatorState>(find.byType(Navigator)).pushNamed('/next');
    await tester.pumpAndSettle();

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

    // Drag from left edge to invoke the gesture.
    final TestGesture gesture = await tester.startGesture(const Offset(5.0, 100.0));
    await gesture.moveBy(const Offset(400.0, 0.0));
    await tester.pump();

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

    // Page 2 didn't move
    expect(tester.getTopLeft(find.text('Page 2')), Offset.zero);
  }, variant: TargetPlatformVariant.only(TargetPlatform.android));

  testWidgets('test back gesture', (WidgetTester tester) async {
    await tester.pumpWidget(
      MaterialApp(
        home: const Scaffold(body: Text('Page 1')),
        routes: <String, WidgetBuilder>{
          '/next': (BuildContext context) {
            return const Scaffold(body: Text('Page 2'));
          },
        },
      ),
    );

    tester.state<NavigatorState>(find.byType(Navigator)).pushNamed('/next');
    await tester.pumpAndSettle();

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

    // Drag from left edge to invoke the gesture.
    final TestGesture gesture = await tester.startGesture(const Offset(5.0, 100.0));
    await gesture.moveBy(const Offset(400.0, 0.0));
    await tester.pump();

    // Page 1 is now visible.
    expect(find.text('Page 1'), isOnstage);
    expect(find.text('Page 2'), isOnstage);

    // The route widget position needs to track the finger position very exactly.
    expect(tester.getTopLeft(find.text('Page 2')), const Offset(400.0, 0.0));

    await gesture.moveBy(const Offset(-200.0, 0.0));
    await tester.pump();

    expect(tester.getTopLeft(find.text('Page 2')), const Offset(200.0, 0.0));

    await gesture.moveBy(const Offset(-100.0, 200.0));
    await tester.pump();

    expect(tester.getTopLeft(find.text('Page 2')), const Offset(100.0, 0.0));
  }, variant: const TargetPlatformVariant(<TargetPlatform>{ TargetPlatform.iOS, TargetPlatform.macOS }));

  testWidgets('back gesture while OS changes', (WidgetTester tester) async {
    final Map<String, WidgetBuilder> routes = <String, WidgetBuilder>{
      '/': (BuildContext context) => Material(
        child: TextButton(
          child: const Text('PUSH'),
          onPressed: () { Navigator.of(context)!.pushNamed('/b'); },
        ),
      ),
      '/b': (BuildContext context) => Container(child: const Text('HELLO')),
    };
    await tester.pumpWidget(
      MaterialApp(
        theme: ThemeData(platform: TargetPlatform.iOS),
        routes: routes,
      ),
    );
    await tester.tap(find.text('PUSH'));
    expect(await tester.pumpAndSettle(const Duration(minutes: 1)), 2);
    expect(find.text('PUSH'), findsNothing);
    expect(find.text('HELLO'), findsOneWidget);
    final Offset helloPosition1 = tester.getCenter(find.text('HELLO'));
    final TestGesture gesture = await tester.startGesture(const Offset(2.5, 300.0));
    await tester.pump(const Duration(milliseconds: 20));
    await gesture.moveBy(const Offset(100.0, 0.0));
    expect(find.text('PUSH'), findsNothing);
    expect(find.text('HELLO'), findsOneWidget);
    await tester.pump(const Duration(milliseconds: 20));
    expect(find.text('PUSH'), findsOneWidget);
    expect(find.text('HELLO'), findsOneWidget);
    final Offset helloPosition2 = tester.getCenter(find.text('HELLO'));
    expect(helloPosition1.dx, lessThan(helloPosition2.dx));
    expect(helloPosition1.dy, helloPosition2.dy);
    expect(Theme.of(tester.element(find.text('HELLO')))!.platform, TargetPlatform.iOS);
    await tester.pumpWidget(
      MaterialApp(
        theme: ThemeData(platform: TargetPlatform.android),
        routes: routes,
      ),
    );
    // Now we have to let the theme animation run through.
    // This takes three frames (including the first one above):
    //  1. Start the Theme animation. It's at t=0 so everything else is identical.
    //  2. Start any animations that are informed by the Theme, for example, the
    //     DefaultTextStyle, on the first frame that the theme is not at t=0. In
    //     this case, it's at t=1.0 of the theme animation, so this is also the
    //     frame in which the theme animation ends.
    //  3. End all the other animations.
    expect(await tester.pumpAndSettle(const Duration(minutes: 1)), 2);
    expect(Theme.of(tester.element(find.text('HELLO')))!.platform, TargetPlatform.android);
    final Offset helloPosition3 = tester.getCenter(find.text('HELLO'));
    expect(helloPosition3, helloPosition2);
    expect(find.text('PUSH'), findsOneWidget);
    expect(find.text('HELLO'), findsOneWidget);
    await gesture.moveBy(const Offset(100.0, 0.0));
    await tester.pump(const Duration(milliseconds: 20));
    expect(find.text('PUSH'), findsOneWidget);
    expect(find.text('HELLO'), findsOneWidget);
    final Offset helloPosition4 = tester.getCenter(find.text('HELLO'));
    expect(helloPosition3.dx, lessThan(helloPosition4.dx));
    expect(helloPosition3.dy, helloPosition4.dy);
    await gesture.moveBy(const Offset(500.0, 0.0));
    await gesture.up();
    expect(await tester.pumpAndSettle(const Duration(minutes: 1)), 3);
    expect(find.text('PUSH'), findsOneWidget);
    expect(find.text('HELLO'), findsNothing);

    await tester.pumpWidget(
      MaterialApp(
        theme: ThemeData(platform: TargetPlatform.macOS),
        routes: routes,
      ),
    );
    await tester.tap(find.text('PUSH'));
    expect(await tester.pumpAndSettle(const Duration(minutes: 1)), 2);
    expect(find.text('PUSH'), findsNothing);
    expect(find.text('HELLO'), findsOneWidget);
    final Offset helloPosition5 = tester.getCenter(find.text('HELLO'));
    await gesture.down(const Offset(2.5, 300.0));
    await tester.pump(const Duration(milliseconds: 20));
    await gesture.moveBy(const Offset(100.0, 0.0));
    expect(find.text('PUSH'), findsNothing);
    expect(find.text('HELLO'), findsOneWidget);
    await tester.pump(const Duration(milliseconds: 20));
    expect(find.text('PUSH'), findsOneWidget);
    expect(find.text('HELLO'), findsOneWidget);
    final Offset helloPosition6 = tester.getCenter(find.text('HELLO'));
    expect(helloPosition5.dx, lessThan(helloPosition6.dx));
    expect(helloPosition5.dy, helloPosition6.dy);
    expect(Theme.of(tester.element(find.text('HELLO')))!.platform, TargetPlatform.macOS);
  });

  testWidgets('test no back gesture on fullscreen dialogs', (WidgetTester tester) async {
    await tester.pumpWidget(
      const MaterialApp(
        home: Scaffold(body: Text('Page 1')),
      ),
    );

    tester.state<NavigatorState>(find.byType(Navigator)).push(MaterialPageRoute<void>(
      builder: (BuildContext context) {
        return const Scaffold(body: Text('Page 2'));
      },
      fullscreenDialog: true,
    ));
    await tester.pumpAndSettle();

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

    // Drag from left edge to invoke the gesture.
    final TestGesture gesture = await tester.startGesture(const Offset(5.0, 100.0));
    await gesture.moveBy(const Offset(400.0, 0.0));
    await tester.pump();

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

    // Page 2 didn't move
    expect(tester.getTopLeft(find.text('Page 2')), Offset.zero);
  }, variant: const TargetPlatformVariant(<TargetPlatform>{ TargetPlatform.iOS,  TargetPlatform.macOS }));

  testWidgets('test adaptable transitions switch during execution', (WidgetTester tester) async {
    await tester.pumpWidget(
      MaterialApp(
        theme: ThemeData(
          platform: TargetPlatform.android,
          pageTransitionsTheme: const PageTransitionsTheme(
            builders: <TargetPlatform, PageTransitionsBuilder>{
              TargetPlatform.android: FadeUpwardsPageTransitionsBuilder(),
            },
          ),
        ),
        home: const Material(child: Text('Page 1')),
        routes: <String, WidgetBuilder>{
          '/next': (BuildContext context) {
            return const Material(child: Text('Page 2'));
          },
        },
      ),
    );

    final Offset widget1InitialTopLeft = tester.getTopLeft(find.text('Page 1'));

    tester.state<NavigatorState>(find.byType(Navigator)).pushNamed('/next');
    await tester.pump();
    await tester.pump(const Duration(milliseconds: 100));

    Offset widget2TopLeft = tester.getTopLeft(find.text('Page 2'));
    final Size widget2Size = tester.getSize(find.text('Page 2'));

    // Android transition is vertical only.
    expect(widget1InitialTopLeft.dx == widget2TopLeft.dx, true);
    // Page 1 is above page 2 mid-transition.
    expect(widget1InitialTopLeft.dy < widget2TopLeft.dy, true);
    // Animation begins from the top of the page.
    expect(widget2TopLeft.dy < widget2Size.height, true);

    await tester.pump(const Duration(milliseconds: 300));

    // Page 2 covers page 1.
    expect(find.text('Page 1'), findsNothing);
    expect(find.text('Page 2'), isOnstage);

    // Re-pump the same app but with iOS instead of Android.
    await tester.pumpWidget(
      MaterialApp(
        home: const Material(child: Text('Page 1')),
        routes: <String, WidgetBuilder>{
          '/next': (BuildContext context) {
            return const Material(child: Text('Page 2'));
          },
        },
      ),
    );

    tester.state<NavigatorState>(find.byType(Navigator)).pop();
    await tester.pump();
    await tester.pump(const Duration(milliseconds: 100));

    Offset widget1TransientTopLeft = tester.getTopLeft(find.text('Page 1'));
    widget2TopLeft = tester.getTopLeft(find.text('Page 2'));

    // Page 1 is coming back from the left.
    expect(widget1TransientTopLeft.dx < widget1InitialTopLeft.dx, true);
    // Page 1 isn't moving vertically.
    expect(widget1TransientTopLeft.dy == widget1InitialTopLeft.dy, true);
    // iOS transition is horizontal only.
    expect(widget1InitialTopLeft.dy == widget2TopLeft.dy, true);
    // Page 2 is leaving towards the right.
    expect(widget2TopLeft.dx > widget1InitialTopLeft.dx, true);

    await tester.pump(const Duration(milliseconds: 300));

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

    widget1TransientTopLeft = tester.getTopLeft(find.text('Page 1'));

    // Page 1 is back where it started.
    expect(widget1InitialTopLeft == widget1TransientTopLeft, true);
  }, variant: const TargetPlatformVariant(<TargetPlatform>{ TargetPlatform.iOS,  TargetPlatform.macOS }));

  testWidgets('test edge swipe then drop back at starting point works', (WidgetTester tester) async {
    await tester.pumpWidget(
      MaterialApp(
        onGenerateRoute: (RouteSettings settings) {
          return MaterialPageRoute<void>(
            settings: settings,
            builder: (BuildContext context) {
              final String pageNumber = settings.name == '/' ? '1' : '2';
              return Center(child: Text('Page $pageNumber'));
            },
          );
        },
      ),
    );

    tester.state<NavigatorState>(find.byType(Navigator)).pushNamed('/next');

    await tester.pump();
    await tester.pump(const Duration(seconds: 1));

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

    final TestGesture gesture = await tester.startGesture(const Offset(5, 200));
    await gesture.moveBy(const Offset(300, 0));
    await tester.pump();
    // Bring it exactly back such that there's nothing to animate when releasing.
    await gesture.moveBy(const Offset(-300, 0));
    await gesture.up();
    await tester.pump();

    expect(find.text('Page 1'), findsNothing);
    expect(find.text('Page 2'), isOnstage);
  }, variant: const TargetPlatformVariant(<TargetPlatform>{ TargetPlatform.iOS,  TargetPlatform.macOS }));

  testWidgets('test edge swipe then drop back at ending point works', (WidgetTester tester) async {
    await tester.pumpWidget(
      MaterialApp(
        onGenerateRoute: (RouteSettings settings) {
          return MaterialPageRoute<void>(
            settings: settings,
            builder: (BuildContext context) {
              final String pageNumber = settings.name == '/' ? '1' : '2';
              return Center(child: Text('Page $pageNumber'));
            },
          );
        },
      ),
    );

    tester.state<NavigatorState>(find.byType(Navigator)).pushNamed('/next');

    await tester.pump();
    await tester.pump(const Duration(seconds: 1));

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

    final TestGesture gesture = await tester.startGesture(const Offset(5, 200));
    // The width of the page.
    await gesture.moveBy(const Offset(800, 0));
    await gesture.up();
    await tester.pump();

    expect(find.text('Page 1'), isOnstage);
    expect(find.text('Page 2'), findsNothing);
  }, variant: const TargetPlatformVariant(<TargetPlatform>{ TargetPlatform.iOS,  TargetPlatform.macOS }));

  testWidgets('Back swipe dismiss interrupted by route push', (WidgetTester tester) async {
    // Regression test for https://github.com/flutter/flutter/issues/28728
    final GlobalKey scaffoldKey = GlobalKey();

    await tester.pumpWidget(
      MaterialApp(
        home: Scaffold(
          key: scaffoldKey,
          body: Center(
            child: ElevatedButton(
              onPressed: () {
                Navigator.push<void>(scaffoldKey.currentContext!, MaterialPageRoute<void>(
                  builder: (BuildContext context) {
                    return const Scaffold(
                      body: Center(child: Text('route')),
                    );
                  },
                ));
              },
              child: const Text('push'),
            ),
          ),
        ),
      ),
    );

    // Check the basic iOS back-swipe dismiss transition. Dragging the pushed
    // route halfway across the screen will trigger the iOS dismiss animation

    await tester.tap(find.text('push'));
    await tester.pumpAndSettle();
    expect(find.text('route'), findsOneWidget);
    expect(find.text('push'), findsNothing);

    TestGesture gesture = await tester.startGesture(const Offset(5, 300));
    await gesture.moveBy(const Offset(400, 0));
    await gesture.up();
    await tester.pump();
    expect( // The 'route' route has been dragged to the right, halfway across the screen
      tester.getTopLeft(find.ancestor(of: find.text('route'), matching: find.byType(Scaffold))),
      const Offset(400, 0),
    );
    expect( // The 'push' route is sliding in from the left.
      tester.getTopLeft(find.ancestor(of: find.text('push'), matching: find.byType(Scaffold))).dx,
      lessThan(0),
    );
    await tester.pumpAndSettle();
    expect(find.text('push'), findsOneWidget);
    expect(
      tester.getTopLeft(find.ancestor(of: find.text('push'), matching: find.byType(Scaffold))),
      Offset.zero,
    );
    expect(find.text('route'), findsNothing);


    // Run the dismiss animation 60%, which exposes the route "push" button,
    // and then press the button. A drag dropped animation is 400ms when dropped
    // exactly halfway. It follows a curve that is very steep initially.

    await tester.tap(find.text('push'));
    await tester.pumpAndSettle();
    expect(find.text('route'), findsOneWidget);
    expect(find.text('push'), findsNothing);

    gesture = await tester.startGesture(const Offset(5, 300));
    await gesture.moveBy(const Offset(400, 0)); // Drag halfway.
    await gesture.up();
    await tester.pump(); // Trigger the dropped snapping animation.
    expect(
      tester.getTopLeft(find.ancestor(of: find.text('route'), matching: find.byType(Scaffold))),
      const Offset(400, 0),
    );
    // Let the dismissing snapping animation go 60%.
    await tester.pump(const Duration(milliseconds: 240));
    expect(
      tester.getTopLeft(find.ancestor(of: find.text('route'), matching: find.byType(Scaffold))).dx,
      moreOrLessEquals(798, epsilon: 1),
    );

    // Use the navigator to push a route instead of tapping the 'push' button.
    // The topmost route (the one that's animating away), ignores input while
    // the pop is underway because route.navigator.userGestureInProgress.
    Navigator.push<void>(scaffoldKey.currentContext!, MaterialPageRoute<void>(
      builder: (BuildContext context) {
        return const Scaffold(
          body: Center(child: Text('route')),
        );
      },
    ));

    await tester.pumpAndSettle();
    expect(find.text('route'), findsOneWidget);
    expect(find.text('push'), findsNothing);
  }, variant: const TargetPlatformVariant(<TargetPlatform>{ TargetPlatform.iOS,  TargetPlatform.macOS }));

  testWidgets('During back swipe the route ignores input', (WidgetTester tester) async {
    // Regression test for https://github.com/flutter/flutter/issues/39989

    final GlobalKey homeScaffoldKey = GlobalKey();
    final GlobalKey pageScaffoldKey = GlobalKey();
    int homeTapCount = 0;
    int pageTapCount = 0;

    await tester.pumpWidget(
      MaterialApp(
        home: Scaffold(
          key: homeScaffoldKey,
          body: GestureDetector(
            onTap: () {
              homeTapCount += 1;
            }
          ),
        ),
      ),
    );

    await tester.tap(find.byKey(homeScaffoldKey));
    expect(homeTapCount, 1);
    expect(pageTapCount, 0);

    Navigator.push<void>(homeScaffoldKey.currentContext!, MaterialPageRoute<void>(
      builder: (BuildContext context) {
        return Scaffold(
          key: pageScaffoldKey,
          appBar: AppBar(title: const Text('Page')),
          body: Padding(
            padding: const EdgeInsets.all(16),
            child: GestureDetector(
              onTap: () {
                pageTapCount += 1;
              }
            ),
          ),
        );
      },
    ));

    await tester.pumpAndSettle();
    await tester.tap(find.byKey(pageScaffoldKey));
    expect(homeTapCount, 1);
    expect(pageTapCount, 1);

    // Start the basic iOS back-swipe dismiss transition. Drag the pushed
    // "page" route halfway across the screen. The underlying "home" will
    // start sliding in from the left.

    final TestGesture gesture = await tester.startGesture(const Offset(5, 300));
    await gesture.moveBy(const Offset(400, 0));
    await tester.pump();
    expect(tester.getTopLeft(find.byKey(pageScaffoldKey)), const Offset(400, 0));
    expect(tester.getTopLeft(find.byKey(homeScaffoldKey)).dx, lessThan(0));

    // Tapping on the "page" route doesn't trigger the GestureDetector because
    // it's being dragged.
    await tester.tap(find.byKey(pageScaffoldKey));
    expect(homeTapCount, 1);
    expect(pageTapCount, 1);

    // Tapping the "page" route's back button doesn't do anything either.
    await tester.tap(find.byTooltip('Back'));
    await tester.pumpAndSettle();
    expect(tester.getTopLeft(find.byKey(pageScaffoldKey)), const Offset(400, 0));
    expect(tester.getTopLeft(find.byKey(homeScaffoldKey)).dx, lessThan(0));
  }, variant: const TargetPlatformVariant(<TargetPlatform>{ TargetPlatform.iOS,  TargetPlatform.macOS }));

  testWidgets('After a pop caused by a back-swipe, input reaches the exposed route', (WidgetTester tester) async {
    // Regression test for https://github.com/flutter/flutter/issues/41024

    final GlobalKey homeScaffoldKey = GlobalKey();
    final GlobalKey pageScaffoldKey = GlobalKey();
    int homeTapCount = 0;
    int pageTapCount = 0;

    await tester.pumpWidget(
      MaterialApp(
        home: Scaffold(
          key: homeScaffoldKey,
          body: GestureDetector(
            onTap: () {
              homeTapCount += 1;
            }
          ),
        ),
      ),
    );

    await tester.tap(find.byKey(homeScaffoldKey));
    expect(homeTapCount, 1);
    expect(pageTapCount, 0);

    final ValueNotifier<bool> notifier = Navigator.of(homeScaffoldKey.currentContext!)!.userGestureInProgressNotifier;
    expect(notifier.value, false);

    Navigator.push<void>(homeScaffoldKey.currentContext!, MaterialPageRoute<void>(
      builder: (BuildContext context) {
        return Scaffold(
          key: pageScaffoldKey,
          appBar: AppBar(title: const Text('Page')),
          body: Padding(
            padding: const EdgeInsets.all(16),
            child: GestureDetector(
              onTap: () {
                pageTapCount += 1;
              }
            ),
          ),
        );
      },
    ));

    await tester.pumpAndSettle();
    await tester.tap(find.byKey(pageScaffoldKey));
    expect(homeTapCount, 1);
    expect(pageTapCount, 1);

    // Trigger the basic iOS back-swipe dismiss transition. Drag the pushed
    // "page" route more than halfway across the screen and then release it.

    final TestGesture gesture = await tester.startGesture(const Offset(5, 300));
    await gesture.moveBy(const Offset(500, 0));
    await tester.pump();
    expect(tester.getTopLeft(find.byKey(pageScaffoldKey)), const Offset(500, 0));
    expect(tester.getTopLeft(find.byKey(homeScaffoldKey)).dx, lessThan(0));
    expect(notifier.value, true);
    await gesture.up();
    await tester.pumpAndSettle();
    expect(notifier.value, false);
    expect(find.byKey(pageScaffoldKey), findsNothing);

    // The back-swipe dismiss pop transition has finished and input on the
    // home page still works.
    await tester.tap(find.byKey(homeScaffoldKey));
    expect(homeTapCount, 2);
    expect(pageTapCount, 1);
  }, variant: const TargetPlatformVariant(<TargetPlatform>{ TargetPlatform.iOS,  TargetPlatform.macOS }));

  testWidgets('A MaterialPageRoute should slide out with CupertinoPageTransition when a compatible PageRoute is pushed on top of it', (WidgetTester tester) async {
    // Regression test for https://github.com/flutter/flutter/issues/44864.

    await tester.pumpWidget(
      MaterialApp(
        theme: ThemeData(platform: TargetPlatform.iOS),
        home: Scaffold(
          appBar: AppBar(title: const Text('Title')),
        ),
      ),
    );

    final Offset titleInitialTopLeft = tester.getTopLeft(find.text('Title'));

    tester.state<NavigatorState>(find.byType(Navigator)).push<void>(
      CupertinoPageRoute<void>(builder: (BuildContext context) => const Placeholder()),
    );

    await tester.pump();
    await tester.pump(const Duration(milliseconds: 150));

    final Offset titleTransientTopLeft = tester.getTopLeft(find.text('Title'));

    // Title of the first route slides to the left.
    expect(titleInitialTopLeft.dy, equals(titleTransientTopLeft.dy));
    expect(titleInitialTopLeft.dx, greaterThan(titleTransientTopLeft.dx));
  }, variant: const TargetPlatformVariant(<TargetPlatform>{ TargetPlatform.iOS,  TargetPlatform.macOS }));

  testWidgets('MaterialPage works', (WidgetTester tester) async {
    final LocalKey pageKey = UniqueKey();
    final TransitionDetector detector = TransitionDetector();
    List<Page<void>> myPages = <Page<void>>[
      MaterialPage<void>(key: pageKey, child: const Text('first')),
    ];
    await tester.pumpWidget(
      buildNavigator(
        pages: myPages,
        onPopPage: (Route<dynamic> route, dynamic result) {
          assert(false); // The test should never execute this.
          return true;
        },
        transitionDelegate: detector,
      )
    );

    expect(detector.hasTransition, isFalse);
    expect(find.text('first'), findsOneWidget);

    myPages = <Page<void>>[
      MaterialPage<void>(key: pageKey, child: const Text('second')),
    ];

    await tester.pumpWidget(
      buildNavigator(
        pages: myPages,
        onPopPage: (Route<dynamic> route, dynamic result) {
          assert(false); // The test should never execute this.
          return true;
        },
        transitionDelegate: detector,
      )
    );
    // There should be no transition because the page has the same key.
    expect(detector.hasTransition, isFalse);
    // The content does update.
    expect(find.text('first'), findsNothing);
    expect(find.text('second'), findsOneWidget);
  });

  testWidgets('MaterialPage can toggle MaintainState', (WidgetTester tester) async {
    final LocalKey pageKeyOne = UniqueKey();
    final LocalKey pageKeyTwo = UniqueKey();
    final TransitionDetector detector = TransitionDetector();
    List<Page<void>> myPages = <Page<void>>[
      MaterialPage<void>(key: pageKeyOne, maintainState: false, child: const Text('first')),
      MaterialPage<void>(key: pageKeyTwo, child: const Text('second')),
    ];
    await tester.pumpWidget(
      buildNavigator(
        pages: myPages,
        onPopPage: (Route<dynamic> route, dynamic result) {
          assert(false); // The test should never execute this.
          return true;
        },
        transitionDelegate: detector,
      )
    );

    expect(detector.hasTransition, isFalse);
    // Page one does not maintain state.
    expect(find.text('first', skipOffstage: false), findsNothing);
    expect(find.text('second'), findsOneWidget);

    myPages = <Page<void>>[
      MaterialPage<void>(key: pageKeyOne, maintainState: true, child: const Text('first')),
      MaterialPage<void>(key: pageKeyTwo, child: const Text('second')),
    ];

    await tester.pumpWidget(
      buildNavigator(
        pages: myPages,
        onPopPage: (Route<dynamic> route, dynamic result) {
          assert(false); // The test should never execute this.
          return true;
        },
        transitionDelegate: detector,
      )
    );
    // There should be no transition because the page has the same key.
    expect(detector.hasTransition, isFalse);
    // Page one sets the maintain state to be true, its widget tree should be
    // built.
    expect(find.text('first', skipOffstage: false), findsOneWidget);
    expect(find.text('second'), findsOneWidget);
  });

  testWidgets('MaterialPage does not lose its state when transitioning out', (WidgetTester tester) async {
    final GlobalKey<NavigatorState> navigator = GlobalKey<NavigatorState>();
    await tester.pumpWidget(KeepsStateTestWidget(navigatorKey: navigator));
    expect(find.text('subpage'), findsOneWidget);
    expect(find.text('home'), findsNothing);

    navigator.currentState!.pop();
    await tester.pump();

    expect(find.text('subpage'), findsOneWidget);
    expect(find.text('home'), findsOneWidget);
  });
}

class TransitionDetector extends DefaultTransitionDelegate<void> {
  bool hasTransition = false;
  @override
  Iterable<RouteTransitionRecord> resolve({
    required List<RouteTransitionRecord> newPageRouteHistory,
    required Map<RouteTransitionRecord?, RouteTransitionRecord> locationToExitingPageRoute,
    required Map<RouteTransitionRecord?, List<RouteTransitionRecord>> pageRouteToPagelessRoutes
  }) {
    hasTransition = true;
    return super.resolve(
      newPageRouteHistory: newPageRouteHistory,
      locationToExitingPageRoute: locationToExitingPageRoute,
      pageRouteToPagelessRoutes: pageRouteToPagelessRoutes
    );
  }
}

Widget buildNavigator({
  required List<Page<dynamic>> pages,
  required PopPageCallback onPopPage,
  GlobalKey<NavigatorState>? key,
  TransitionDelegate<dynamic>? transitionDelegate
}) {
  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,
          transitionDelegate: transitionDelegate ?? const DefaultTransitionDelegate<dynamic>(),
        ),
      ),
    ),
  );
}

class KeepsStateTestWidget extends StatefulWidget {
  const KeepsStateTestWidget({this.navigatorKey});

  final Key? navigatorKey;

  @override
  State<KeepsStateTestWidget> createState() => _KeepsStateTestWidgetState();
}

class _KeepsStateTestWidgetState extends State<KeepsStateTestWidget> {
  String? _subpage = 'subpage';

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Navigator(
        key: widget.navigatorKey,
        pages: <Page<void>>[
          const MaterialPage<void>(child: Text('home')),
          if (_subpage != null) MaterialPage<void>(child: Text(_subpage!)),
        ],
        onPopPage: (Route<dynamic> route, dynamic result) {
          if (!route.didPop(result)) {
            return false;
          }
          setState(() {
            _subpage = null;
          });
          return true;
        },
      ),
    );
  }
}
