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

@TestOn('!chrome')
import 'dart:ui';

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

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

void main() {
  late MockNavigatorObserver navigatorObserver;

  setUp(() {
    navigatorObserver = MockNavigatorObserver();
  });

  testWidgets('Middle auto-populates with title', (WidgetTester tester) async {
    await tester.pumpWidget(
      const CupertinoApp(
        home: Placeholder(),
      ),
    );

    tester.state<NavigatorState>(find.byType(Navigator)).push(
      CupertinoPageRoute<void>(
        title: 'An iPod',
        builder: (BuildContext context) {
          return const CupertinoPageScaffold(
            navigationBar: CupertinoNavigationBar(),
            child: Placeholder(),
          );
        },
      ),
    );

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

    // There should be a Text widget with the title in the nav bar even though
    // we didn't specify anything in the nav bar constructor.
    expect(find.widgetWithText(CupertinoNavigationBar, 'An iPod'), findsOneWidget);

    // As a title, it should also be centered.
    expect(tester.getCenter(find.text('An iPod')).dx, 400.0);
  });

  testWidgets('Large title auto-populates with title', (WidgetTester tester) async {
    await tester.pumpWidget(
      const CupertinoApp(
        home: Placeholder(),
      ),
    );

    tester.state<NavigatorState>(find.byType(Navigator)).push(
      CupertinoPageRoute<void>(
        title: 'An iPod',
        builder: (BuildContext context) {
          return const CupertinoPageScaffold(
            child: CustomScrollView(
              slivers: <Widget>[
                CupertinoSliverNavigationBar(),
              ],
            ),
          );
        },
      ),
    );

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

    // There should be 2 Text widget with the title in the nav bar. One in the
    // large title position and one in the middle position (though the middle
    // position Text is initially invisible while the sliver is expanded).
    expect(
      find.widgetWithText(CupertinoSliverNavigationBar, 'An iPod'),
      findsNWidgets(2),
    );

    final List<Element> titles = tester.elementList(find.text('An iPod'))
        .toList()
        ..sort((Element a, Element b) {
          final RenderParagraph aParagraph = a.renderObject! as RenderParagraph;
          final RenderParagraph bParagraph = b.renderObject! as RenderParagraph;
          return aParagraph.text.style!.fontSize!.compareTo(
            bParagraph.text.style!.fontSize!,
          );
        });

    final Iterable<double> opacities = titles.map<double>((Element element) {
      final RenderAnimatedOpacity renderOpacity =
          element.findAncestorRenderObjectOfType<RenderAnimatedOpacity>()!;
      return renderOpacity.opacity.value;
    });

    expect(opacities, <double> [
      0.0, // Initially the smaller font title is invisible.
      1.0, // The larger font title is visible.
    ]);

    // Check that the large font title is at the right spot.
    expect(
      tester.getTopLeft(find.byWidget(titles[1].widget)),
      const Offset(16.0, 54.0),
    );

    // The smaller, initially invisible title, should still be positioned in the
    // center.
    expect(tester.getCenter(find.byWidget(titles[0].widget)).dx, 400.0);
  });

  testWidgets('Leading auto-populates with back button with previous title', (WidgetTester tester) async {
    await tester.pumpWidget(
      const CupertinoApp(
        home: Placeholder(),
      ),
    );

    tester.state<NavigatorState>(find.byType(Navigator)).push(
      CupertinoPageRoute<void>(
        title: 'An iPod',
        builder: (BuildContext context) {
          return const CupertinoPageScaffold(
            navigationBar: CupertinoNavigationBar(),
            child: Placeholder(),
          );
        },
      ),
    );

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

    tester.state<NavigatorState>(find.byType(Navigator)).push(
      CupertinoPageRoute<void>(
        title: 'A Phone',
        builder: (BuildContext context) {
          return const CupertinoPageScaffold(
            navigationBar: CupertinoNavigationBar(),
            child: Placeholder(),
          );
        },
      ),
    );

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

    expect(find.widgetWithText(CupertinoNavigationBar, 'A Phone'), findsOneWidget);
    expect(tester.getCenter(find.text('A Phone')).dx, 400.0);

    // Also shows the previous page's title next to the back button.
    expect(find.widgetWithText(CupertinoButton, 'An iPod'), findsOneWidget);
    // 3 paddings + 1 ahem character at font size 34.0.
    expect(tester.getTopLeft(find.text('An iPod')).dx, 8.0 + 4.0 + 34.0 + 6.0);
  });

  testWidgets('Previous title is correct on first transition frame', (WidgetTester tester) async {
    await tester.pumpWidget(
      const CupertinoApp(
        home: Placeholder(),
      ),
    );

    tester.state<NavigatorState>(find.byType(Navigator)).push(
      CupertinoPageRoute<void>(
        title: 'An iPod',
        builder: (BuildContext context) {
          return const CupertinoPageScaffold(
            navigationBar: CupertinoNavigationBar(),
            child: Placeholder(),
          );
        },
      ),
    );

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

    tester.state<NavigatorState>(find.byType(Navigator)).push(
      CupertinoPageRoute<void>(
        title: 'A Phone',
        builder: (BuildContext context) {
          return const CupertinoPageScaffold(
            navigationBar: CupertinoNavigationBar(),
            child: Placeholder(),
          );
        },
      ),
    );

    // Trigger the route push
    await tester.pump();
    // Draw the first frame.
    await tester.pump();

    // Also shows the previous page's title next to the back button.
    expect(find.widgetWithText(CupertinoButton, 'An iPod'), findsOneWidget);
  });

  testWidgets('Previous title stays up to date with changing routes', (WidgetTester tester) async {
    await tester.pumpWidget(
      const CupertinoApp(
        home: Placeholder(),
      ),
    );

    final CupertinoPageRoute<void> route2 = CupertinoPageRoute<void>(
      title: 'An iPod',
      builder: (BuildContext context) {
        return const CupertinoPageScaffold(
          navigationBar: CupertinoNavigationBar(),
          child: Placeholder(),
        );
      },
    );

    final CupertinoPageRoute<void> route3 = CupertinoPageRoute<void>(
      title: 'A Phone',
      builder: (BuildContext context) {
        return const CupertinoPageScaffold(
          navigationBar: CupertinoNavigationBar(),
          child: Placeholder(),
        );
      },
    );

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

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

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

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

    tester.state<NavigatorState>(find.byType(Navigator)).replace(
      oldRoute: route2,
      newRoute: CupertinoPageRoute<void>(
        title: 'An Internet communicator',
        builder: (BuildContext context) {
          return const CupertinoPageScaffold(
            navigationBar: CupertinoNavigationBar(),
            child: Placeholder(),
          );
        },
      ),
    );

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

    expect(find.widgetWithText(CupertinoNavigationBar, 'A Phone'), findsOneWidget);
    expect(tester.getCenter(find.text('A Phone')).dx, 400.0);

    // After swapping the route behind the top one, the previous label changes
    // from An iPod to Back (since An Internet communicator is too long to
    // fit in the back button).
    expect(find.widgetWithText(CupertinoButton, 'Back'), findsOneWidget);
    expect(tester.getTopLeft(find.text('Back')).dx, 8.0 + 4.0 + 34.0 + 6.0);
  });

  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(
      CupertinoApp(
        home: CupertinoPageScaffold(
          key: scaffoldKey,
          child: Center(
            child: CupertinoButton(
              onPressed: () {
                Navigator.push<void>(scaffoldKey.currentContext!, CupertinoPageRoute<void>(
                  builder: (BuildContext context) {
                    return const CupertinoPageScaffold(
                      child: 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(CupertinoPageScaffold))),
      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(CupertinoPageScaffold))).dx,
      lessThan(0),
    );
    await tester.pumpAndSettle();
    expect(find.text('push'), findsOneWidget);
    expect(
      tester.getTopLeft(find.ancestor(of: find.text('push'), matching: find.byType(CupertinoPageScaffold))),
      Offset.zero,
    );
    expect(find.text('route'), findsNothing);


    // Run the dismiss animation 60%, which exposes the route "push" button,
    // and then press the button.

    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();
    // Trigger the snapping animation.
    // Since the back swipe drag was brought to >=50% of the screen, it will
    // self snap to finish the pop transition as the gesture is lifted.
    //
    // This drag drop animation is 400ms when dropped exactly halfway
    // (800 / [pixel distance remaining], see
    // _CupertinoBackGestureController.dragEnd). It follows a curve that is very
    // steep initially.
    await tester.pump();
    expect(
      tester.getTopLeft(find.ancestor(of: find.text('route'), matching: find.byType(CupertinoPageScaffold))),
      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(CupertinoPageScaffold))).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!, CupertinoPageRoute<void>(
      builder: (BuildContext context) {
        return const CupertinoPageScaffold(
          child: Center(child: Text('route')),
        );
      },
    ));

    await tester.pumpAndSettle();
    expect(find.text('route'), findsOneWidget);
    expect(find.text('push'), findsNothing);
    expect(
      tester.state<NavigatorState>(find.byType(Navigator)).userGestureInProgress,
      false,
    );
  });

  testWidgets('Fullscreen route animates correct transform values over time', (WidgetTester tester) async {
    await tester.pumpWidget(
      CupertinoApp(
        home: Builder(
          builder: (BuildContext context) {
            return CupertinoButton(
              child: const Text('Button'),
              onPressed: () {
                Navigator.push<void>(context, CupertinoPageRoute<void>(
                  fullscreenDialog: true,
                  builder: (BuildContext context) {
                    return Column(
                      children: <Widget>[
                        const Placeholder(),
                        CupertinoButton(
                          child: const Text('Close'),
                          onPressed: () {
                            Navigator.pop<void>(context);
                          },
                        ),
                      ],
                    );
                  },
                ));
              },
            );
          },
        ),
      ),
    );

    // Enter animation.
    await tester.tap(find.text('Button'));
    await tester.pump();

    // We use a higher number of intervals since the animation has to scale the
    // entire screen.

    await tester.pump(const Duration(milliseconds: 40));
    expect(tester.getTopLeft(find.byType(Placeholder)).dy, moreOrLessEquals(443.7, epsilon: 0.1));

    await tester.pump(const Duration(milliseconds: 40));
    expect(tester.getTopLeft(find.byType(Placeholder)).dy, moreOrLessEquals(291.9, epsilon: 0.1));

    await tester.pump(const Duration(milliseconds: 40));
    expect(tester.getTopLeft(find.byType(Placeholder)).dy, moreOrLessEquals(168.2, epsilon: 0.1));

    await tester.pump(const Duration(milliseconds: 40));
    expect(tester.getTopLeft(find.byType(Placeholder)).dy, moreOrLessEquals(89.5, epsilon: 0.1));

    await tester.pump(const Duration(milliseconds: 40));
    expect(tester.getTopLeft(find.byType(Placeholder)).dy, moreOrLessEquals(48.1, epsilon: 0.1));

    await tester.pump(const Duration(milliseconds: 40));
    expect(tester.getTopLeft(find.byType(Placeholder)).dy, moreOrLessEquals(26.1, epsilon: 0.1));

    await tester.pump(const Duration(milliseconds: 40));
    expect(tester.getTopLeft(find.byType(Placeholder)).dy, moreOrLessEquals(14.3, epsilon: 0.1));

    await tester.pump(const Duration(milliseconds: 40));
    expect(tester.getTopLeft(find.byType(Placeholder)).dy, moreOrLessEquals(7.41, epsilon: 0.1));

    await tester.pump(const Duration(milliseconds: 40));
    expect(tester.getTopLeft(find.byType(Placeholder)).dy, moreOrLessEquals(3.0, epsilon: 0.1));

    await tester.pump(const Duration(milliseconds: 40));
    expect(tester.getTopLeft(find.byType(Placeholder)).dy, moreOrLessEquals(0.0, epsilon: 0.1));

    // Exit animation
    await tester.tap(find.text('Close'));
    await tester.pump();

    await tester.pump(const Duration(milliseconds: 40));
    expect(tester.getTopLeft(find.byType(Placeholder)).dy, moreOrLessEquals(156.3, epsilon: 0.1));

    await tester.pump(const Duration(milliseconds: 40));
    expect(tester.getTopLeft(find.byType(Placeholder)).dy, moreOrLessEquals(308.1, epsilon: 0.1));

    await tester.pump(const Duration(milliseconds: 40));
    expect(tester.getTopLeft(find.byType(Placeholder)).dy, moreOrLessEquals(431.7, epsilon: 0.1));

    await tester.pump(const Duration(milliseconds: 40));
    expect(tester.getTopLeft(find.byType(Placeholder)).dy, moreOrLessEquals(510.4, epsilon: 0.1));

    await tester.pump(const Duration(milliseconds: 40));
    expect(tester.getTopLeft(find.byType(Placeholder)).dy, moreOrLessEquals(551.8, epsilon: 0.1));

    await tester.pump(const Duration(milliseconds: 40));
    expect(tester.getTopLeft(find.byType(Placeholder)).dy, moreOrLessEquals(573.8, epsilon: 0.1));

    await tester.pump(const Duration(milliseconds: 40));
    expect(tester.getTopLeft(find.byType(Placeholder)).dy, moreOrLessEquals(585.6, epsilon: 0.1));

    await tester.pump(const Duration(milliseconds: 40));
    expect(tester.getTopLeft(find.byType(Placeholder)).dy, moreOrLessEquals(592.6, epsilon: 0.1));

    await tester.pump(const Duration(milliseconds: 40));
    expect(tester.getTopLeft(find.byType(Placeholder)).dy, moreOrLessEquals(596.9, epsilon: 0.1));

    await tester.pump(const Duration(milliseconds: 40));
    expect(tester.getTopLeft(find.byType(Placeholder)).dy, moreOrLessEquals(600.0, epsilon: 0.1));
  });

  Future<void> testParallax(WidgetTester tester, {required bool fromFullscreenDialog}) async {
    await tester.pumpWidget(
      CupertinoApp(
        onGenerateRoute: (RouteSettings settings) => CupertinoPageRoute<void>(
          fullscreenDialog: fromFullscreenDialog,
          settings: settings,
          builder: (BuildContext context) {
            return Column(
              children: <Widget>[
                const Placeholder(),
                CupertinoButton(
                  child: const Text('Button'),
                  onPressed: () {
                    Navigator.push<void>(context, CupertinoPageRoute<void>(
                      builder: (BuildContext context) {
                        return CupertinoButton(
                          child: const Text('Close'),
                          onPressed: () {
                            Navigator.pop<void>(context);
                          },
                        );
                      },
                    ));
                  },
                ),
              ],
            );
          },
        ),
      ),
    );

    // Enter animation.
    await tester.tap(find.text('Button'));
    expect(tester.getTopLeft(find.byType(Placeholder)).dx, moreOrLessEquals(0.0, epsilon: 0.1));
    await tester.pump();

    // We use a higher number of intervals since the animation has to scale the
    // entire screen.

    await tester.pump(const Duration(milliseconds: 40));
    expect(tester.getTopLeft(find.byType(Placeholder)).dx, moreOrLessEquals(-70.0, epsilon: 1.0));

    await tester.pump(const Duration(milliseconds: 40));
    expect(tester.getTopLeft(find.byType(Placeholder)).dx, moreOrLessEquals(-137.0, epsilon: 1.0));

    await tester.pump(const Duration(milliseconds: 40));
    expect(tester.getTopLeft(find.byType(Placeholder)).dx, moreOrLessEquals(-192.0, epsilon: 1.0));

    await tester.pump(const Duration(milliseconds: 40));
    expect(tester.getTopLeft(find.byType(Placeholder)).dx, moreOrLessEquals(-227.0, epsilon: 1.0));

    await tester.pump(const Duration(milliseconds: 40));
    expect(tester.getTopLeft(find.byType(Placeholder)).dx, moreOrLessEquals(-246.0, epsilon: 1.0));

    await tester.pump(const Duration(milliseconds: 40));
    expect(tester.getTopLeft(find.byType(Placeholder)).dx, moreOrLessEquals(-255.0, epsilon: 1.0));

    await tester.pump(const Duration(milliseconds: 40));
    expect(tester.getTopLeft(find.byType(Placeholder)).dx, moreOrLessEquals(-260.0, epsilon: 1.0));

    await tester.pump(const Duration(milliseconds: 40));
    expect(tester.getTopLeft(find.byType(Placeholder)).dx, moreOrLessEquals(-264.0, epsilon: 1.0));

    await tester.pump(const Duration(milliseconds: 40));
    expect(tester.getTopLeft(find.byType(Placeholder)).dx, moreOrLessEquals(-266.0, epsilon: 1.0));

    await tester.pump(const Duration(milliseconds: 40));
    expect(tester.getTopLeft(find.byType(Placeholder)).dx, moreOrLessEquals(-267.0, epsilon: 1.0));

    // Exit animation
    await tester.tap(find.text('Close'));
    await tester.pump();

    await tester.pump(const Duration(milliseconds: 40));
    expect(tester.getTopLeft(find.byType(Placeholder)).dx, moreOrLessEquals(-198.0, epsilon: 1.0));

    await tester.pump(const Duration(milliseconds: 360));
    expect(tester.getTopLeft(find.byType(Placeholder)).dx, moreOrLessEquals(-0.0, epsilon: 1.0));
  }

  testWidgets('CupertinoPageRoute has parallax when non fullscreenDialog route is pushed on top', (WidgetTester tester) async {
    await testParallax(tester, fromFullscreenDialog: false);
  });

  testWidgets('FullscreenDialog CupertinoPageRoute has parallax when non fullscreenDialog route is pushed on top', (WidgetTester tester) async {
    await testParallax(tester, fromFullscreenDialog: true);
  });

  Future<void> testNoParallax(WidgetTester tester, {required bool fromFullscreenDialog}) async{
    await tester.pumpWidget(
      CupertinoApp(
        onGenerateRoute: (RouteSettings settings) => CupertinoPageRoute<void>(
          fullscreenDialog: fromFullscreenDialog,
          builder: (BuildContext context) {
            return Column(
              children: <Widget>[
                const Placeholder(),
                CupertinoButton(
                  child: const Text('Button'),
                  onPressed: () {
                    Navigator.push<void>(context, CupertinoPageRoute<void>(
                      fullscreenDialog: true,
                      builder: (BuildContext context) {
                        return CupertinoButton(
                          child: const Text('Close'),
                          onPressed: () {
                            Navigator.pop<void>(context);
                          },
                        );
                      },
                    ));
                  },
                ),
              ],
            );
          },
        ),
      ),
    );

    // Enter animation.
    await tester.tap(find.text('Button'));
    expect(tester.getTopLeft(find.byType(Placeholder)).dx, moreOrLessEquals(0.0, epsilon: 0.1));
    await tester.pump();

    // We use a higher number of intervals since the animation has to scale the
    // entire screen.

    await tester.pump(const Duration(milliseconds: 40));
    expect(tester.getTopLeft(find.byType(Placeholder)).dx, 0.0);

    await tester.pump(const Duration(milliseconds: 40));
    expect(tester.getTopLeft(find.byType(Placeholder)).dx, 0.0);

    await tester.pump(const Duration(milliseconds: 40));
    expect(tester.getTopLeft(find.byType(Placeholder)).dx, 0.0);

    await tester.pump(const Duration(milliseconds: 40));
    expect(tester.getTopLeft(find.byType(Placeholder)).dx, 0.0);

    await tester.pump(const Duration(milliseconds: 40));
    expect(tester.getTopLeft(find.byType(Placeholder)).dx, 0.0);

    await tester.pump(const Duration(milliseconds: 40));
    expect(tester.getTopLeft(find.byType(Placeholder)).dx, 0.0);

    await tester.pump(const Duration(milliseconds: 40));
    expect(tester.getTopLeft(find.byType(Placeholder)).dx, 0.0);

    await tester.pump(const Duration(milliseconds: 40));
    expect(tester.getTopLeft(find.byType(Placeholder)).dx, 0.0);

    await tester.pump(const Duration(milliseconds: 40));
    expect(tester.getTopLeft(find.byType(Placeholder)).dx, 0.0);

    await tester.pump(const Duration(milliseconds: 40));
    expect(tester.getTopLeft(find.byType(Placeholder)).dx, 0.0);

    // Exit animation
    await tester.tap(find.text('Close'));
    await tester.pump();

    await tester.pump(const Duration(milliseconds: 40));
    expect(tester.getTopLeft(find.byType(Placeholder)).dx, 0.0);

    await tester.pump(const Duration(milliseconds: 360));
    expect(tester.getTopLeft(find.byType(Placeholder)).dx, 0.0);
  }

  testWidgets('CupertinoPageRoute has no parallax when fullscreenDialog route is pushed on top', (WidgetTester tester) async {
    await testNoParallax(tester, fromFullscreenDialog: false);
  });

  testWidgets('FullscreenDialog CupertinoPageRoute has no parallax when fullscreenDialog route is pushed on top', (WidgetTester tester) async {
    await testNoParallax(tester, fromFullscreenDialog: true);
  });

  testWidgets('Animated push/pop is not linear', (WidgetTester tester) async {
    await tester.pumpWidget(
      const CupertinoApp(
        home: Text('1'),
      ),
    );

    final CupertinoPageRoute<void> route2 = CupertinoPageRoute<void>(
      builder: (BuildContext context) {
        return const CupertinoPageScaffold(
          child: Text('2'),
        );
      },
    );

    tester.state<NavigatorState>(find.byType(Navigator)).push(route2);
    // The whole transition is 400ms based on CupertinoPageRoute.transitionDuration.
    // Break it up into small chunks.

    await tester.pump();
    await tester.pump(const Duration(milliseconds: 50));
    expect(tester.getTopLeft(find.text('1')).dx, moreOrLessEquals(-87, epsilon: 1));
    expect(tester.getTopLeft(find.text('2')).dx, moreOrLessEquals(537, epsilon: 1));

    await tester.pump(const Duration(milliseconds: 50));
    expect(tester.getTopLeft(find.text('1')).dx, moreOrLessEquals(-166, epsilon: 1));
    expect(tester.getTopLeft(find.text('2')).dx, moreOrLessEquals(301, epsilon: 1));

    await tester.pump(const Duration(milliseconds: 50));
    // Translation slows down as time goes on.
    expect(tester.getTopLeft(find.text('1')).dx, moreOrLessEquals(-220, epsilon: 1));
    expect(tester.getTopLeft(find.text('2')).dx, moreOrLessEquals(141, epsilon: 1));

    // Finish the rest of the animation
    await tester.pump(const Duration(milliseconds: 250));

    tester.state<NavigatorState>(find.byType(Navigator)).pop();
    await tester.pump();
    await tester.pump(const Duration(milliseconds: 50));
    expect(tester.getTopLeft(find.text('1')).dx, moreOrLessEquals(-179, epsilon: 1));
    expect(tester.getTopLeft(find.text('2')).dx, moreOrLessEquals(262, epsilon: 1));

    await tester.pump(const Duration(milliseconds: 50));
    expect(tester.getTopLeft(find.text('1')).dx, moreOrLessEquals(-100, epsilon: 1));
    expect(tester.getTopLeft(find.text('2')).dx, moreOrLessEquals(499, epsilon: 1));

    await tester.pump(const Duration(milliseconds: 50));
    // Translation slows down as time goes on.
    expect(tester.getTopLeft(find.text('1')).dx, moreOrLessEquals(-47, epsilon: 1));
    expect(tester.getTopLeft(find.text('2')).dx, moreOrLessEquals(659, epsilon: 1));
  });

  testWidgets('Dragged pop gesture is linear', (WidgetTester tester) async {
    await tester.pumpWidget(
      const CupertinoApp(
        home: Text('1'),
      ),
    );

    final CupertinoPageRoute<void> route2 = CupertinoPageRoute<void>(
      builder: (BuildContext context) {
        return const CupertinoPageScaffold(
          child: Text('2'),
        );
      },
    );

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

    await tester.pumpAndSettle();

    expect(find.text('1'), findsNothing);
    expect(tester.getTopLeft(find.text('2')).dx, moreOrLessEquals(0));

    final TestGesture swipeGesture = await tester.startGesture(const Offset(5, 100));

    await swipeGesture.moveBy(const Offset(100, 0));
    await tester.pump();
    expect(tester.getTopLeft(find.text('1')).dx, moreOrLessEquals(-233, epsilon: 1));
    expect(tester.getTopLeft(find.text('2')).dx, moreOrLessEquals(100));
    expect(
      tester.state<NavigatorState>(find.byType(Navigator)).userGestureInProgress,
      true,
    );

    await swipeGesture.moveBy(const Offset(100, 0));
    await tester.pump();
    expect(tester.getTopLeft(find.text('1')).dx, moreOrLessEquals(-200));
    expect(tester.getTopLeft(find.text('2')).dx, moreOrLessEquals(200));

    // Moving by the same distance each time produces linear movements on both
    // routes.
    await swipeGesture.moveBy(const Offset(100, 0));
    await tester.pump();
    expect(tester.getTopLeft(find.text('1')).dx, moreOrLessEquals(-166, epsilon: 1));
    expect(tester.getTopLeft(find.text('2')).dx, moreOrLessEquals(300));
  });

  testWidgets('Pop gesture snapping is not linear', (WidgetTester tester) async {
    await tester.pumpWidget(
      const CupertinoApp(
        home: Text('1'),
      ),
    );

    final CupertinoPageRoute<void> route2 = CupertinoPageRoute<void>(
      builder: (BuildContext context) {
        return const CupertinoPageScaffold(
          child: Text('2'),
        );
      },
    );

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

    await tester.pumpAndSettle();

    final TestGesture swipeGesture = await tester.startGesture(const Offset(5, 100));

    await swipeGesture.moveBy(const Offset(500, 0));
    await swipeGesture.up();
    await tester.pump();
    expect(tester.getTopLeft(find.text('1')).dx, moreOrLessEquals(-100));
    expect(tester.getTopLeft(find.text('2')).dx, moreOrLessEquals(500));
    expect(
      tester.state<NavigatorState>(find.byType(Navigator)).userGestureInProgress,
      true,
    );

    await tester.pump(const Duration(milliseconds: 50));
    expect(tester.getTopLeft(find.text('1')).dx, moreOrLessEquals(-19, epsilon: 1));
    expect(tester.getTopLeft(find.text('2')).dx, moreOrLessEquals(744, epsilon: 1));

    await tester.pump(const Duration(milliseconds: 50));
    // Rate of change is slowing down.
    expect(tester.getTopLeft(find.text('1')).dx, moreOrLessEquals(-4, epsilon: 1));
    expect(tester.getTopLeft(find.text('2')).dx, moreOrLessEquals(787, epsilon: 1));

    await tester.pumpAndSettle();
    expect(
      tester.state<NavigatorState>(find.byType(Navigator)).userGestureInProgress,
      false,
    );
  });

  testWidgets('Snapped drags forwards and backwards should signal didStart/StopUserGesture', (WidgetTester tester) async {
    final GlobalKey<NavigatorState> navigatorKey = GlobalKey();
    await tester.pumpWidget(
      CupertinoApp(
        navigatorObservers: <NavigatorObserver>[navigatorObserver],
        navigatorKey: navigatorKey,
        home: const Text('1'),
      ),
    );

    final CupertinoPageRoute<void> route2 = CupertinoPageRoute<void>(
      builder: (BuildContext context) {
        return const CupertinoPageScaffold(
          child: Text('2'),
        );
      },
    );

    navigatorKey.currentState!.push(route2);
    await tester.pumpAndSettle();
    expect(navigatorObserver.invocations.removeLast(), NavigatorInvocation.didPush);

    await tester.dragFrom(const Offset(5, 100), const Offset(100, 0));
    expect(navigatorObserver.invocations.removeLast(), NavigatorInvocation.didStartUserGesture);
    await tester.pump();
    expect(tester.getTopLeft(find.text('2')).dx, moreOrLessEquals(100));
    expect(navigatorKey.currentState!.userGestureInProgress, true);

    // Didn't drag far enough to snap into dismissing this route.
    // Each 100px distance takes 100ms to snap back.
    await tester.pump(const Duration(milliseconds: 101));
    // Back to the page covering the whole screen.
    expect(tester.getTopLeft(find.text('2')).dx, moreOrLessEquals(0));
    expect(navigatorKey.currentState!.userGestureInProgress, false);

    expect(navigatorObserver.invocations.removeLast(), NavigatorInvocation.didStopUserGesture);
    expect(navigatorObserver.invocations.removeLast(), isNot(NavigatorInvocation.didPop));

    await tester.dragFrom(const Offset(5, 100), const Offset(500, 0));
    await tester.pump();
    expect(tester.getTopLeft(find.text('2')).dx, moreOrLessEquals(500));
    expect(navigatorKey.currentState!.userGestureInProgress, true);
    expect(navigatorObserver.invocations.removeLast(), NavigatorInvocation.didPop);

    // Did go far enough to snap out of this route.
    await tester.pump(const Duration(milliseconds: 301));
    // Back to the page covering the whole screen.
    expect(find.text('2'), findsNothing);
    // First route covers the whole screen.
    expect(tester.getTopLeft(find.text('1')).dx, moreOrLessEquals(0));
    expect(navigatorKey.currentState!.userGestureInProgress, false);
  });

  /// Regression test for https://github.com/flutter/flutter/issues/29596.
  testWidgets('test edge swipe then drop back at ending point works', (WidgetTester tester) async {
    await tester.pumpWidget(
      CupertinoApp(
        navigatorObservers: <NavigatorObserver>[navigatorObserver],
        onGenerateRoute: (RouteSettings settings) {
          return CupertinoPageRoute<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));
    expect(navigatorObserver.invocations.removeLast(), NavigatorInvocation.didStartUserGesture);
    await gesture.up();
    await tester.pump();

    expect(find.text('Page 1'), isOnstage);
    expect(find.text('Page 2'), findsNothing);
    expect(navigatorObserver.invocations.removeLast(), NavigatorInvocation.didStopUserGesture);
    expect(navigatorObserver.invocations.removeLast(), NavigatorInvocation.didPop);
  });

  testWidgets('test edge swipe then drop back at starting point works', (WidgetTester tester) async {
    await tester.pumpWidget(
      CupertinoApp(
        navigatorObservers: <NavigatorObserver>[navigatorObserver],
        onGenerateRoute: (RouteSettings settings) {
          return CupertinoPageRoute<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));
    // Move right a bit
    await gesture.moveBy(const Offset(300, 0));
    expect(navigatorObserver.invocations.removeLast(), NavigatorInvocation.didStartUserGesture);
    expect(
      tester.state<NavigatorState>(find.byType(Navigator)).userGestureInProgress,
      true,
    );
    await tester.pump();

    // Move back to where we started.
    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);
    expect(navigatorObserver.invocations.removeLast(), NavigatorInvocation.didStopUserGesture);
    expect(navigatorObserver.invocations.removeLast(), isNot(NavigatorInvocation.didPop));
    expect(
      tester.state<NavigatorState>(find.byType(Navigator)).userGestureInProgress,
      false,
    );
  });

  group('Cupertino page transitions', () {
    CupertinoPageRoute<void> buildRoute({required bool fullscreenDialog}) {
      return CupertinoPageRoute<void>(
        fullscreenDialog: fullscreenDialog,
        builder: (_) => const SizedBox(),
      );
    }

    testWidgets('when route is not fullscreenDialog, it has a barrierColor', (WidgetTester tester) async {
      await tester.pumpWidget(
        const MaterialApp(
          home: SizedBox.expand(),
        ),
      );

      tester.state<NavigatorState>(find.byType(Navigator)).push(
        buildRoute(fullscreenDialog: false),
      );
      await tester.pumpAndSettle();

      expect(tester.widget<ModalBarrier>(find.byType(ModalBarrier).last).color, const Color(0x18000000));
    });

    testWidgets('when route is a fullscreenDialog, it has no barrierColor', (WidgetTester tester) async {
      await tester.pumpWidget(
        const MaterialApp(
          home: SizedBox.expand(),
        ),
      );

      tester.state<NavigatorState>(find.byType(Navigator)).push(
        buildRoute(fullscreenDialog: true),
      );
      await tester.pumpAndSettle();

      expect(tester.widget<ModalBarrier>(find.byType(ModalBarrier).last).color, isNull);
    });

    testWidgets('when route is not fullscreenDialog, it has a _CupertinoEdgeShadowDecoration', (WidgetTester tester) async {
      PaintPattern paintsShadowRect({required double dx, required Color color}) {
        return paints..everything((Symbol methodName, List<dynamic> arguments) {
          if (methodName != #drawRect)
            return true;
          final Rect rect = arguments[0] as Rect;
          final Color paintColor = (arguments[1] as Paint).color;
          if (rect.top != 0 || rect.width != 1.0 || rect.height != 600)
            // _CupertinoEdgeShadowDecoration draws the shadows with a series of
            // differently colored 1px-wide rects. Skip rects that aren't being
            // drawn by the _CupertinoEdgeShadowDecoration.
            return true;
          if ((rect.left - dx).abs() >= 1)
            // Skip calls for rects until the one with the given position offset
            return true;
          if (paintColor.value == color.value)
            return true;
          throw '''
  For a rect with an expected left-side position: $dx (drawn at ${rect.left}):
              Expected a rect with color: $color,
              And drew a rect with color: $paintColor.
          ''';
        });
      }

      await tester.pumpWidget(
        const MaterialApp(
          home: SizedBox.expand(),
        ),
      );

      tester.state<NavigatorState>(find.byType(Navigator)).push(
        buildRoute(fullscreenDialog: false),
      );
      await tester.pump();
      await tester.pump(const Duration(milliseconds: 1));

      final RenderBox box = tester.firstRenderObject<RenderBox>(find.byType(CustomPaint));

      // Animation starts with effectively no shadow
      expect(box, paintsShadowRect(dx: 795, color: const Color(0x00000000)));
      expect(box, paintsShadowRect(dx: 785, color: const Color(0x00000000)));
      expect(box, paintsShadowRect(dx: 775, color: const Color(0x00000000)));
      expect(box, paintsShadowRect(dx: 765, color: const Color(0x00000000)));
      expect(box, paintsShadowRect(dx: 755, color: const Color(0x00000000)));

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

      // Part-way through the transition, the shadow is approaching the full gradient
      expect(box, paintsShadowRect(dx: 296, color: const Color(0x03000000)));
      expect(box, paintsShadowRect(dx: 286, color: const Color(0x02000000)));
      expect(box, paintsShadowRect(dx: 276, color: const Color(0x01000000)));
      expect(box, paintsShadowRect(dx: 266, color: const Color(0x00000000)));
      expect(box, paintsShadowRect(dx: 266, color: const Color(0x00000000)));

      await tester.pumpAndSettle();

      // At the end of the transition, the shadow is a gradient between
      // 0x04000000 and 0x00000000 and is now offscreen
      expect(box, paintsShadowRect(dx: -1, color: const Color(0x04000000)));
      expect(box, paintsShadowRect(dx: -10, color: const Color(0x03000000)));
      expect(box, paintsShadowRect(dx: -20, color: const Color(0x02000000)));
      expect(box, paintsShadowRect(dx: -30, color: const Color(0x01000000)));
      expect(box, paintsShadowRect(dx: -40, color: const Color(0x00000000)));

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

      expect(box, paintsShadowRect(dx: 498, color: const Color(0x04000000)));
      expect(box, paintsShadowRect(dx: 488, color: const Color(0x03000000)));
      expect(box, paintsShadowRect(dx: 478, color: const Color(0x02000000)));
      expect(box, paintsShadowRect(dx: 468, color: const Color(0x01000000)));
      expect(box, paintsShadowRect(dx: 458, color: const Color(0x00000000)));

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

      // At the end of the animation, the shadow approaches full transparency
      expect(box, paintsShadowRect(dx: 794, color: const Color(0x01000000)));
      expect(box, paintsShadowRect(dx: 784, color: const Color(0x00000000)));
      expect(box, paintsShadowRect(dx: 774, color: const Color(0x00000000)));
      expect(box, paintsShadowRect(dx: 764, color: const Color(0x00000000)));
      expect(box, paintsShadowRect(dx: 754, color: const Color(0x00000000)));
    });

    testWidgets('when route is fullscreenDialog, it has no visible _CupertinoEdgeShadowDecoration', (WidgetTester tester) async {
      PaintPattern paintsNoShadows() {
        return paints..everything((Symbol methodName, List<dynamic> arguments) {
          if (methodName != #drawRect)
            return true;
          final Rect rect = arguments[0] as Rect;
          // _CupertinoEdgeShadowDecoration draws the shadows with a series of
          // differently colored 1px rects. Skip all rects not drawn by a
          // _CupertinoEdgeShadowDecoration.
          if (rect.width != 1.0)
            return true;
          throw '''
    Expected: no rects with a width of 1px.
          Found: $rect.
          ''';
        });
      }

      await tester.pumpWidget(
        const MaterialApp(
          home: SizedBox.expand(),
        ),
      );

      final RenderBox box = tester.firstRenderObject<RenderBox>(find.byType(CustomPaint));

      tester.state<NavigatorState>(find.byType(Navigator)).push(
        buildRoute(fullscreenDialog: true),
      );

      await tester.pumpAndSettle();
      expect(box, paintsNoShadows());

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

      await tester.pumpAndSettle();
      expect(box, paintsNoShadows());
    });
  });

  testWidgets('ModalPopup overlay dark mode', (WidgetTester tester) async {
    late StateSetter stateSetter;
    Brightness brightness = Brightness.light;

    await tester.pumpWidget(
      StatefulBuilder(
        builder: (BuildContext context, StateSetter setter) {
          stateSetter = setter;
          return CupertinoApp(
            theme: CupertinoThemeData(brightness: brightness),
            home: CupertinoPageScaffold(
              child: Builder(builder: (BuildContext context) {
                return GestureDetector(
                  onTap: () async {
                    await showCupertinoModalPopup<void>(
                      context: context,
                      builder: (BuildContext context) => const SizedBox(),
                    );
                  },
                  child: const Text('tap'),
                );
              }),
            ),
          );
        },
      ),
    );

    await tester.tap(find.text('tap'));
    await tester.pumpAndSettle();

    expect(
      tester.widget<ModalBarrier>(find.byType(ModalBarrier).last).color!.value,
      0x33000000,
    );

    stateSetter(() { brightness = Brightness.dark; });
    await tester.pump();

    // TODO(LongCatIsLooong): The background overlay SHOULD switch to dark color.
    expect(
      tester.widget<ModalBarrier>(find.byType(ModalBarrier).last).color!.value,
      0x33000000,
    );

    await tester.pumpWidget(
      CupertinoApp(
        theme: const CupertinoThemeData(brightness: Brightness.dark),
        home: CupertinoPageScaffold(
          child: Builder(builder: (BuildContext context) {
            return GestureDetector(
              onTap: () async {
                await showCupertinoModalPopup<void>(
                  context: context,
                  builder: (BuildContext context) => const SizedBox(),
                );
              },
              child: const Text('tap'),
            );
          }),
        ),
      ),
    );

    await tester.tap(find.text('tap'));
    await tester.pumpAndSettle();

    expect(
      tester.widget<ModalBarrier>(find.byType(ModalBarrier).last).color!.value,
      0x7A000000,
    );
  });

  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(
      CupertinoApp(
        home: CupertinoPageScaffold(
          key: homeScaffoldKey,
          child: GestureDetector(
            onTap: () {
              homeTapCount += 1;
            },
          ),
        ),
      ),
    );

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

    Navigator.push<void>(homeScaffoldKey.currentContext!, CupertinoPageRoute<void>(
      builder: (BuildContext context) {
        return CupertinoPageScaffold(
          key: pageScaffoldKey,
          child: 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), warnIfMissed: false);
    expect(homeTapCount, 1);
    expect(pageTapCount, 1);
  });

  testWidgets('showCupertinoModalPopup uses root navigator by default', (WidgetTester tester) async {
    final PopupObserver rootObserver = PopupObserver();
    final PopupObserver nestedObserver = PopupObserver();

    await tester.pumpWidget(CupertinoApp(
      navigatorObservers: <NavigatorObserver>[rootObserver],
      home: Navigator(
        observers: <NavigatorObserver>[nestedObserver],
        onGenerateRoute: (RouteSettings settings) {
          return PageRouteBuilder<dynamic>(
            pageBuilder: (BuildContext context, Animation<double> _, Animation<double> __) {
              return GestureDetector(
                onTap: () async {
                  await showCupertinoModalPopup<void>(
                    context: context,
                    builder: (BuildContext context) => const SizedBox(),
                  );
                },
                child: const Text('tap'),
              );
            },
          );
        },
      ),
    ));

    // Open the dialog.
    await tester.tap(find.text('tap'));

    expect(rootObserver.popupCount, 1);
    expect(nestedObserver.popupCount, 0);
  });

  testWidgets('back swipe to screen edges does not dismiss the hero animation', (WidgetTester tester) async {
    final GlobalKey<NavigatorState> navigator = GlobalKey<NavigatorState>();
    final UniqueKey container = UniqueKey();
    await tester.pumpWidget(CupertinoApp(
      navigatorKey: navigator,
      routes: <String, WidgetBuilder>{
        '/': (BuildContext context) {
          return CupertinoPageScaffold(
            child: Center(
              child: Hero(
                tag: 'tag',
                transitionOnUserGestures: true,
                child: SizedBox(key: container, height: 150.0, width: 150.0),
              ),
            ),
          );
        },
        '/page2': (BuildContext context) {
          return CupertinoPageScaffold(
            child: Center(
              child: Padding(
                padding: const EdgeInsets.fromLTRB(100.0, 0.0, 0.0, 0.0),
                child: Hero(
                  tag: 'tag',
                  transitionOnUserGestures: true,
                  child: SizedBox(key: container, height: 150.0, width: 150.0),
                ),
              ),
            ),
          );
        },
      },
    ));

    RenderBox box = tester.renderObject(find.byKey(container)) as RenderBox;
    final double initialPosition = box.localToGlobal(Offset.zero).dx;

    navigator.currentState!.pushNamed('/page2');
    await tester.pumpAndSettle();
    box = tester.renderObject(find.byKey(container)) as RenderBox;
    final double finalPosition = box.localToGlobal(Offset.zero).dx;

    final TestGesture gesture = await tester.startGesture(const Offset(5, 300));
    await gesture.moveBy(const Offset(200, 0));
    await tester.pump();
    box = tester.renderObject(find.byKey(container)) as RenderBox;
    final double firstPosition = box.localToGlobal(Offset.zero).dx;
    // Checks the hero is in-transit.
    expect(finalPosition, greaterThan(firstPosition));
    expect(firstPosition, greaterThan(initialPosition));

    // Goes back to final position.
    await gesture.moveBy(const Offset(-200, 0));
    await tester.pump();
    box = tester.renderObject(find.byKey(container)) as RenderBox;
    final double secondPosition = box.localToGlobal(Offset.zero).dx;
    // There will be a small difference.
    expect(finalPosition - secondPosition, lessThan(0.001));

    await gesture.moveBy(const Offset(400, 0));
    await tester.pump();
    box = tester.renderObject(find.byKey(container)) as RenderBox;
    final double thirdPosition = box.localToGlobal(Offset.zero).dx;
    // Checks the hero is still in-transit and moves further away from the first
    // position.
    expect(finalPosition, greaterThan(thirdPosition));
    expect(thirdPosition, greaterThan(initialPosition));
    expect(firstPosition, greaterThan(thirdPosition));
  });

  testWidgets('showCupertinoModalPopup uses nested navigator if useRootNavigator is false', (WidgetTester tester) async {
    final PopupObserver rootObserver = PopupObserver();
    final PopupObserver nestedObserver = PopupObserver();

    await tester.pumpWidget(CupertinoApp(
      navigatorObservers: <NavigatorObserver>[rootObserver],
      home: Navigator(
        observers: <NavigatorObserver>[nestedObserver],
        onGenerateRoute: (RouteSettings settings) {
          return PageRouteBuilder<dynamic>(
            pageBuilder: (BuildContext context, Animation<double> _, Animation<double> __) {
              return GestureDetector(
                onTap: () async {
                  await showCupertinoModalPopup<void>(
                    context: context,
                    useRootNavigator: false,
                    builder: (BuildContext context) => const SizedBox(),
                  );
                },
                child: const Text('tap'),
              );
            },
          );
        },
      ),
    ));

    // Open the dialog.
    await tester.tap(find.text('tap'));

    expect(rootObserver.popupCount, 0);
    expect(nestedObserver.popupCount, 1);
  });

  testWidgets('showCupertinoDialog uses root navigator by default', (WidgetTester tester) async {
    final DialogObserver rootObserver = DialogObserver();
    final DialogObserver nestedObserver = DialogObserver();

    await tester.pumpWidget(CupertinoApp(
      navigatorObservers: <NavigatorObserver>[rootObserver],
      home: Navigator(
        observers: <NavigatorObserver>[nestedObserver],
        onGenerateRoute: (RouteSettings settings) {
          return PageRouteBuilder<dynamic>(
            pageBuilder: (BuildContext context, Animation<double> _, Animation<double> __) {
              return GestureDetector(
                onTap: () async {
                  await showCupertinoDialog<void>(
                    context: context,
                    builder: (BuildContext context) => const SizedBox(),
                  );
                },
                child: const Text('tap'),
              );
            },
          );
        },
      ),
    ));

    // Open the dialog.
    await tester.tap(find.text('tap'));

    expect(rootObserver.dialogCount, 1);
    expect(nestedObserver.dialogCount, 0);
  });

  testWidgets('showCupertinoDialog uses nested navigator if useRootNavigator is false', (WidgetTester tester) async {
    final DialogObserver rootObserver = DialogObserver();
    final DialogObserver nestedObserver = DialogObserver();

    await tester.pumpWidget(CupertinoApp(
      navigatorObservers: <NavigatorObserver>[rootObserver],
      home: Navigator(
        observers: <NavigatorObserver>[nestedObserver],
        onGenerateRoute: (RouteSettings settings) {
          return PageRouteBuilder<dynamic>(
            pageBuilder: (BuildContext context, Animation<double> _, Animation<double> __) {
              return GestureDetector(
                onTap: () async {
                  await showCupertinoDialog<void>(
                    context: context,
                    useRootNavigator: false,
                    builder: (BuildContext context) => const SizedBox(),
                  );
                },
                child: const Text('tap'),
              );
            },
          );
        },
      ),
    ));

    // Open the dialog.
    await tester.tap(find.text('tap'));

    expect(rootObserver.dialogCount, 0);
    expect(nestedObserver.dialogCount, 1);
  });

  testWidgets('showCupertinoModalPopup does not allow for semantics dismiss by default', (WidgetTester tester) async {
    debugDefaultTargetPlatformOverride = TargetPlatform.iOS;
    final SemanticsTester semantics = SemanticsTester(tester);
    await tester.pumpWidget(CupertinoApp(
      home: Navigator(
        onGenerateRoute: (RouteSettings settings) {
          return PageRouteBuilder<dynamic>(
            pageBuilder: (BuildContext context, Animation<double> _, Animation<double> __) {
              return GestureDetector(
                onTap: () async {
                  await showCupertinoModalPopup<void>(
                    context: context,
                    builder: (BuildContext context) => const SizedBox(),
                  );
                },
                child: const Text('tap'),
              );
            },
          );
        },
      ),
    ));

    // Push the route.
    await tester.tap(find.text('tap'));
    await tester.pumpAndSettle();

    expect(semantics, isNot(includesNodeWith(
      actions: <SemanticsAction>[SemanticsAction.tap],
      label: 'Dismiss',
    )));
    debugDefaultTargetPlatformOverride = null;
  });

  testWidgets('showCupertinoModalPopup allows for semantics dismiss when set', (WidgetTester tester) async {
    debugDefaultTargetPlatformOverride = TargetPlatform.iOS;
    final SemanticsTester semantics = SemanticsTester(tester);
    await tester.pumpWidget(CupertinoApp(
      home: Navigator(
        onGenerateRoute: (RouteSettings settings) {
          return PageRouteBuilder<dynamic>(
            pageBuilder: (BuildContext context, Animation<double> _, Animation<double> __) {
              return GestureDetector(
                onTap: () async {
                  await showCupertinoModalPopup<void>(
                    context: context,
                    semanticsDismissible: true,
                    builder: (BuildContext context) => const SizedBox(),
                  );
                },
                child: const Text('tap'),
              );
            },
          );
        },
      ),
    ));

    // Push the route.
    await tester.tap(find.text('tap'));
    await tester.pumpAndSettle();

    expect(semantics, includesNodeWith(
      actions: <SemanticsAction>[SemanticsAction.tap, SemanticsAction.dismiss],
      label: 'Dismiss',
    ));
    debugDefaultTargetPlatformOverride = null;
  });

  testWidgets('showCupertinoModalPopup passes RouteSettings to PopupRoute', (WidgetTester tester) async {
    final RouteSettingsObserver routeSettingsObserver = RouteSettingsObserver();

    await tester.pumpWidget(CupertinoApp(
      navigatorObservers: <NavigatorObserver>[routeSettingsObserver],
      home: Navigator(
        onGenerateRoute: (RouteSettings settings) {
          return PageRouteBuilder<dynamic>(
            pageBuilder: (BuildContext context, Animation<double> _, Animation<double> __) {
              return GestureDetector(
                onTap: () async {
                  await showCupertinoModalPopup<void>(
                    context: context,
                    builder: (BuildContext context) => const SizedBox(),
                    routeSettings: const RouteSettings(name: '/modal'),
                  );
                },
                child: const Text('tap'),
              );
            },
          );
        },
      ),
    ));

    // Open the dialog.
    await tester.tap(find.text('tap'));

    expect(routeSettingsObserver.routeName, '/modal');
  });

  testWidgets('showCupertinoModalPopup transparent barrier color is transparent', (WidgetTester tester) async {
    const Color kTransparentColor = Color(0x00000000);

    await tester.pumpWidget(CupertinoApp(
      home: CupertinoPageScaffold(
        child: Builder(builder: (BuildContext context) {
          return GestureDetector(
            onTap: () async {
              await showCupertinoModalPopup<void>(
                context: context,
                builder: (BuildContext context) => const SizedBox(),
                barrierColor: kTransparentColor,
              );
            },
            child: const Text('tap'),
          );
        }),
      ),
    ));

    await tester.tap(find.text('tap'));
    await tester.pumpAndSettle();

    expect(tester.widget<ModalBarrier>(find.byType(ModalBarrier).last).color, null);
  });

  testWidgets('showCupertinoModalPopup null barrier color must be default gray barrier color', (WidgetTester tester) async {
    // Barrier color for a Cupertino modal barrier.
    // Extracted from https://developer.apple.com/design/resources/.
    const Color kModalBarrierColor = CupertinoDynamicColor.withBrightness(
      color: Color(0x33000000),
      darkColor: Color(0x7A000000),
    );

    await tester.pumpWidget(CupertinoApp(
      home: CupertinoPageScaffold(
        child: Builder(builder: (BuildContext context) {
          return GestureDetector(
            onTap: () async {
              await showCupertinoModalPopup<void>(
                context: context,
                builder: (BuildContext context) => const SizedBox(),
              );
            },
            child: const Text('tap'),
          );
        }),
      ),
    ));

    await tester.tap(find.text('tap'));
    await tester.pumpAndSettle();

    expect(tester.widget<ModalBarrier>(find.byType(ModalBarrier).last).color, kModalBarrierColor);
  });

  testWidgets('showCupertinoModalPopup custom barrier color', (WidgetTester tester) async {
    const Color customColor = Color(0x11223344);

    await tester.pumpWidget(CupertinoApp(
      home: CupertinoPageScaffold(
        child: Builder(builder: (BuildContext context) {
          return GestureDetector(
            onTap: () async {
              await showCupertinoModalPopup<void>(
                context: context,
                builder: (BuildContext context) => const SizedBox(),
                barrierColor: customColor,
              );
            },
            child: const Text('tap'),
          );
        }),
      ),
    ));

    await tester.tap(find.text('tap'));
    await tester.pumpAndSettle();

    expect(tester.widget<ModalBarrier>(find.byType(ModalBarrier).last).color, customColor);
  });

  testWidgets('showCupertinoModalPopup barrier dismissible', (WidgetTester tester) async {
    await tester.pumpWidget(CupertinoApp(
      home: CupertinoPageScaffold(
        child: Builder(builder: (BuildContext context) {
          return GestureDetector(
            onTap: () async {
              await showCupertinoModalPopup<void>(
                context: context,
                builder: (BuildContext context) => const Text('Visible'),
                barrierDismissible: true,
              );
            },
            child: const Text('tap'),
          );
        }),
      ),
    ));

    await tester.tap(find.text('tap'));
    await tester.pumpAndSettle();
    await tester.tapAt(tester.getTopLeft(find.ancestor(of: find.text('tap'), matching: find.byType(CupertinoPageScaffold))));
    await tester.pumpAndSettle();

    expect(find.text('Visible'), findsNothing);
  });

  testWidgets('showCupertinoModalPopup barrier not dismissible', (WidgetTester tester) async {
    await tester.pumpWidget(CupertinoApp(
      home: CupertinoPageScaffold(
        child: Builder(builder: (BuildContext context) {
          return GestureDetector(
            onTap: () async {
              await showCupertinoModalPopup<void>(
                context: context,
                builder: (BuildContext context) => const Text('Visible'),
                barrierDismissible: false,
              );
            },
            child: const Text('tap'),
          );
        }),
      ),
    ));

    await tester.tap(find.text('tap'));
    await tester.pumpAndSettle();
    await tester.tapAt(tester.getTopLeft(find.ancestor(of: find.text('tap'), matching: find.byType(CupertinoPageScaffold))));
    await tester.pumpAndSettle();

    expect(find.text('Visible'), findsOneWidget);
  });

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

    expect(detector.hasTransition, isFalse);
    expect(find.widgetWithText(CupertinoNavigationBar, 'title one'), findsOneWidget);
    expect(find.text('first'), findsOneWidget);

    myPages = <Page<void>>[
      CupertinoPage<void>(
        key: pageKey,
        title: 'title two',
        child: CupertinoPageScaffold(
          navigationBar: CupertinoNavigationBar(key: UniqueKey()),
          child: const Text('second'),
        ),
      ),
    ];

    await tester.pumpWidget(
      buildNavigator(
        pages: myPages,
        onPopPage: (Route<dynamic> route, dynamic result) {
          assert(false); // The test shouldn't call 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.widgetWithText(CupertinoNavigationBar, 'title one'), findsNothing);
    expect(find.text('second'), findsOneWidget);
    expect(find.widgetWithText(CupertinoNavigationBar, 'title two'), findsOneWidget);
  });

  testWidgets('CupertinoPage can toggle MaintainState', (WidgetTester tester) async {
    final LocalKey pageKeyOne = UniqueKey();
    final LocalKey pageKeyTwo = UniqueKey();
    final TransitionDetector detector = TransitionDetector();
    List<Page<void>> myPages = <Page<void>>[
      CupertinoPage<void>(key: pageKeyOne, maintainState: false, child: const Text('first')),
      CupertinoPage<void>(key: pageKeyTwo, child: const Text('second')),
    ];
    await tester.pumpWidget(
      buildNavigator(
        pages: myPages,
        onPopPage: (Route<dynamic> route, dynamic result) {
          assert(false); // The test shouldn't call 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>>[
      CupertinoPage<void>(key: pageKeyOne, child: const Text('first')),
      CupertinoPage<void>(key: pageKeyTwo, child: const Text('second')),
    ];

    await tester.pumpWidget(
      buildNavigator(
        pages: myPages,
        onPopPage: (Route<dynamic> route, dynamic result) {
          assert(false); // The test shouldn't call 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('Popping routes should cancel down events', (WidgetTester tester) async {
    await tester.pumpWidget(_TestPostRouteCancel());

    final TestGesture gesture = await tester.createGesture();
    await gesture.down(tester.getCenter(find.text('PointerCancelEvents: 0')));
    await gesture.up();

    await tester.pumpAndSettle();
    expect(find.byType(CupertinoButton), findsNothing);
    expect(find.text('Hold'), findsOneWidget);

    await gesture.down(tester.getCenter(find.text('Hold')));
    await tester.pump(const Duration(seconds: 2));
    await tester.pumpAndSettle();
    expect(find.text('Hold'), findsNothing);
    expect(find.byType(CupertinoButton), findsOneWidget);
    expect(find.text('PointerCancelEvents: 1'), findsOneWidget);
  });

  testWidgets('Popping routes during back swipe should not crash', (WidgetTester tester) async {
    // Regression test for https://github.com/flutter/flutter/issues/63984#issuecomment-675679939

    final CupertinoPageRoute<void> r = CupertinoPageRoute<void>(builder: (BuildContext context) {
      return const Scaffold(
        body: Center(
          child: Text('child'),
        ),
      );
    });

    late NavigatorState navigator;

    await tester.pumpWidget(CupertinoApp(
      home: Center(
        child: Builder(builder: (BuildContext context) {
          return ElevatedButton(
            child: const Text('Home'),
            onPressed: () {
              navigator = Navigator.of(context);
              assert(navigator != null);
              navigator.push<void>(r);
            },
          );
        }),
      ),
    ));

    final TestGesture gesture = await tester.createGesture();
    await gesture.down(tester.getCenter(find.byType(ElevatedButton)));
    await gesture.up();

    await tester.pumpAndSettle();

    await gesture.down(const Offset(3, 300));

    // Need 2 events to form a valid drag
    await tester.pump(const Duration(milliseconds: 100));
    await gesture.moveTo(const Offset(30, 300), timeStamp: const Duration(milliseconds: 100));
    await tester.pump(const Duration(milliseconds: 200));
    await gesture.moveTo(const Offset(50, 300), timeStamp: const Duration(milliseconds: 200));

    // Pause a while so that the route is popped when the drag is canceled
    await tester.pump(const Duration(milliseconds: 1000));
    await gesture.moveTo(const Offset(51, 300), timeStamp: const Duration(milliseconds: 1200));

    // Remove the drag
    navigator.removeRoute(r);
    await tester.pump();
  });

  testWidgets('CupertinoModalPopupRoute is state restorable', (WidgetTester tester) async {
    await tester.pumpWidget(
      CupertinoApp(
        restorationScopeId: 'app',
        home: _RestorableModalTestWidget(),
      ),
    );

    expect(find.byType(CupertinoActionSheet), findsNothing);

    await tester.tap(find.text('X'));
    await tester.pumpAndSettle();

    expect(find.byType(CupertinoActionSheet), findsOneWidget);
    final TestRestorationData restorationData = await tester.getRestorationData();

    await tester.restartAndRestore();

    expect(find.byType(CupertinoActionSheet), findsOneWidget);

    // Tap on the barrier.
    await tester.tapAt(const Offset(10.0, 10.0));
    await tester.pumpAndSettle();

    expect(find.byType(CupertinoActionSheet), findsNothing);

    await tester.restoreFrom(restorationData);
    expect(find.byType(CupertinoActionSheet), findsOneWidget);
  }, skip: isBrowser); // https://github.com/flutter/flutter/issues/33615

  group('showCupertinoDialog avoids overlapping display features', () {
    testWidgets('positioning with anchorPoint', (WidgetTester tester) async {
      await tester.pumpWidget(
        CupertinoApp(
          builder: (BuildContext context, Widget? child) {
            return MediaQuery(
              // Display has a vertical hinge down the middle
              data: const MediaQueryData(
                size: Size(800, 600),
                displayFeatures: <DisplayFeature>[
                  DisplayFeature(
                    bounds: Rect.fromLTRB(390, 0, 410, 600),
                    type: DisplayFeatureType.hinge,
                    state: DisplayFeatureState.unknown,
                  ),
                ],
              ),
              child: child!,
            );
          },
          home: const Center(child: Text('Test')),
        ),
      );
      final BuildContext context = tester.element(find.text('Test'));

      showCupertinoDialog<void>(
        context: context,
        builder: (BuildContext context) {
          return const Placeholder();
        },
        anchorPoint: const Offset(1000, 0),
      );
      await tester.pumpAndSettle();

      // Should take the right side of the screen
      expect(tester.getTopLeft(find.byType(Placeholder)), const Offset(410.0, 0.0));
      expect(tester.getBottomRight(find.byType(Placeholder)), const Offset(800.0, 600.0));
    });

    testWidgets('positioning with Directionality', (WidgetTester tester) async {
      await tester.pumpWidget(
        CupertinoApp(
          builder: (BuildContext context, Widget? child) {
            return MediaQuery(
              // Display has a vertical hinge down the middle
              data: const MediaQueryData(
                size: Size(800, 600),
                displayFeatures: <DisplayFeature>[
                  DisplayFeature(
                    bounds: Rect.fromLTRB(390, 0, 410, 600),
                    type: DisplayFeatureType.hinge,
                    state: DisplayFeatureState.unknown,
                  ),
                ],
              ),
              child: Directionality(
                textDirection: TextDirection.rtl,
                child: child!,
              ),
            );
          },
          home: const Center(child: Text('Test')),
        ),
      );
      final BuildContext context = tester.element(find.text('Test'));

      showCupertinoDialog<void>(
        context: context,
        builder: (BuildContext context) {
          return const Placeholder();
        },
      );
      await tester.pumpAndSettle();

      // Since this is RTL, it should place the dialog on the right screen
      expect(tester.getTopLeft(find.byType(Placeholder)), const Offset(410.0, 0.0));
      expect(tester.getBottomRight(find.byType(Placeholder)), const Offset(800.0, 600.0));
    });

    testWidgets('positioning by default', (WidgetTester tester) async {
      await tester.pumpWidget(
        CupertinoApp(
          builder: (BuildContext context, Widget? child) {
            return MediaQuery(
              // Display has a vertical hinge down the middle
              data: const MediaQueryData(
                size: Size(800, 600),
                displayFeatures: <DisplayFeature>[
                  DisplayFeature(
                    bounds: Rect.fromLTRB(390, 0, 410, 600),
                    type: DisplayFeatureType.hinge,
                    state: DisplayFeatureState.unknown,
                  ),
                ],
              ),
              child: child!,
            );
          },
          home: const Center(child: Text('Test')),
        ),
      );
      final BuildContext context = tester.element(find.text('Test'));

      showCupertinoDialog<void>(
        context: context,
        builder: (BuildContext context) {
          return const Placeholder();
        },
      );
      await tester.pumpAndSettle();

      // By default it should place the dialog on the left screen
      expect(tester.getTopLeft(find.byType(Placeholder)), Offset.zero);
      expect(tester.getBottomRight(find.byType(Placeholder)), const Offset(390.0, 600.0));
    });
  });

  group('showCupertinoModalPopup avoids overlapping display features', () {
    testWidgets('positioning using anchorPoint', (WidgetTester tester) async {
      await tester.pumpWidget(
        CupertinoApp(
          builder: (BuildContext context, Widget? child) {
            return MediaQuery(
              // Display has a vertical hinge down the middle
              data: const MediaQueryData(
                size: Size(800, 600),
                displayFeatures: <DisplayFeature>[
                  DisplayFeature(
                    bounds: Rect.fromLTRB(390, 0, 410, 600),
                    type: DisplayFeatureType.hinge,
                    state: DisplayFeatureState.unknown,
                  ),
                ],
              ),
              child: child!,
            );
          },
          home: const Center(child: Text('Test')),
        ),
      );

      final BuildContext context = tester.element(find.text('Test'));
      showCupertinoModalPopup<void>(
        context: context,
        builder: (BuildContext context) {
          return const Placeholder();
        },
        anchorPoint: const Offset(1000, 0),
      );
      await tester.pumpAndSettle();

      // Should take the right side of the screen
      expect(tester.getTopLeft(find.byType(Placeholder)).dx, 410);
      expect(tester.getBottomRight(find.byType(Placeholder)).dx, 800);
    });

    testWidgets('positioning using Directionality', (WidgetTester tester) async {
      await tester.pumpWidget(
        CupertinoApp(
          builder: (BuildContext context, Widget? child) {
            return MediaQuery(
              // Display has a vertical hinge down the middle
              data: const MediaQueryData(
                size: Size(800, 600),
                displayFeatures: <DisplayFeature>[
                  DisplayFeature(
                    bounds: Rect.fromLTRB(390, 0, 410, 600),
                    type: DisplayFeatureType.hinge,
                    state: DisplayFeatureState.unknown,
                  ),
                ],
              ),
              child: Directionality(
                textDirection: TextDirection.rtl,
                child: child!,
              ),
            );
          },
          home: const Center(child: Text('Test')),
        ),
      );

      final BuildContext context = tester.element(find.text('Test'));
      showCupertinoModalPopup<void>(
        context: context,
        builder: (BuildContext context) {
          return const Placeholder();
        },
      );
      await tester.pumpAndSettle();

      // This is RTL, so it should place the dialog on the right screen
      expect(tester.getTopLeft(find.byType(Placeholder)).dx, 410);
      expect(tester.getBottomRight(find.byType(Placeholder)).dx, 800);
    });

    testWidgets('default positioning', (WidgetTester tester) async {
      await tester.pumpWidget(
        CupertinoApp(
          builder: (BuildContext context, Widget? child) {
            return MediaQuery(
              // Display has a vertical hinge down the middle
              data: const MediaQueryData(
                size: Size(800, 600),
                displayFeatures: <DisplayFeature>[
                  DisplayFeature(
                    bounds: Rect.fromLTRB(390, 0, 410, 600),
                    type: DisplayFeatureType.hinge,
                    state: DisplayFeatureState.unknown,
                  ),
                ],
              ),
              child: child!,
            );
          },
          home: const Center(child: Text('Test')),
        ),
      );

      final BuildContext context = tester.element(find.text('Test'));
      showCupertinoModalPopup<void>(
        context: context,
        builder: (BuildContext context) {
          return const Placeholder();
        },
      );
      await tester.pumpAndSettle();

      // By default it should place the dialog on the left screen
      expect(tester.getTopLeft(find.byType(Placeholder)).dx, 0.0);
      expect(tester.getBottomRight(find.byType(Placeholder)).dx, 390.0);
    });
  });
}

class MockNavigatorObserver extends NavigatorObserver {
  final List<NavigatorInvocation> invocations = <NavigatorInvocation>[];

  @override
  void didStartUserGesture(Route<dynamic> route, Route<dynamic>? previousRoute) {
    invocations.add(NavigatorInvocation.didStartUserGesture);
  }

  @override
  void didPop(Route<dynamic> route, Route<dynamic>? previousRoute) {
    invocations.add(NavigatorInvocation.didPop);
  }

  @override
  void didPush(Route<dynamic> route, Route<dynamic>? previousRoute) {
    invocations.add(NavigatorInvocation.didPush);
  }

  @override
  void didStopUserGesture() {
    invocations.add(NavigatorInvocation.didStopUserGesture);
  }
}

enum NavigatorInvocation {
  didStartUserGesture,
  didPop,
  didPush,
  didStopUserGesture,
}

class PopupObserver extends NavigatorObserver {
  int popupCount = 0;

  @override
  void didPush(Route<dynamic> route, Route<dynamic>? previousRoute) {
    if (route is CupertinoModalPopupRoute) {
      popupCount++;
    }
    super.didPush(route, previousRoute);
  }
}

class DialogObserver extends NavigatorObserver {
  int dialogCount = 0;

  @override
  void didPush(Route<dynamic> route, Route<dynamic>? previousRoute) {
    if (route is CupertinoDialogRoute) {
      dialogCount++;
    }
    super.didPush(route, previousRoute);
  }
}

class RouteSettingsObserver extends NavigatorObserver {
  String? routeName;

  @override
  void didPush(Route<dynamic> route, Route<dynamic>? previousRoute) {
    if (route is CupertinoModalPopupRoute) {
      routeName = route.settings.name;
    }
    super.didPush(route, previousRoute);
  }
}

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,
  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>>[
        DefaultCupertinoLocalizations.delegate,
        DefaultWidgetsLocalizations.delegate,
      ],
      child: Directionality(
        textDirection: TextDirection.ltr,
        child: Navigator(
          key: key,
          pages: pages,
          onPopPage: onPopPage,
          transitionDelegate: transitionDelegate ?? const DefaultTransitionDelegate<dynamic>(),
        ),
      ),
    ),
  );
}


// A test target for post-route cancel events.
//
// It contains 2 routes:
//
//  * The initial route, 'home', displays a button showing 'PointerCancelEvents: #',
//    where # is the number of cancel events received. Tapping the button pushes
//    route 'sub'.
//  * The 'sub' route, displays a text showing 'Hold'. Holding the button (a down
//    event) will pop this route after 1 second.
//
// Holding the 'Hold' button at the moment of popping will force the navigator to
// cancel the down event, increasing the Home counter by 1.
class _TestPostRouteCancel extends StatefulWidget {
  @override
  State<StatefulWidget> createState() => _TestPostRouteCancelState();
}

class _TestPostRouteCancelState extends State<_TestPostRouteCancel> {

  int counter = 0;

  Widget _buildHome(BuildContext context) {
    return Center(
      child: CupertinoButton(
        child: Text('PointerCancelEvents: $counter'),
        onPressed: () => Navigator.pushNamed<void>(context, 'sub'),
      ),
    );
  }

  Widget _buildSub(BuildContext context) {
    return Listener(
      onPointerDown: (_) {
        Future<void>.delayed(const Duration(seconds: 1)).then((_) {
          Navigator.pop(context);
        });
      },
      onPointerCancel: (_) {
        setState(() {
          counter += 1;
        });
      },
      child: const Center(
        child: Text('Hold', style: TextStyle(color: Colors.blue)),
      ),
    );
  }

  @override
  Widget build(BuildContext context) {
    return CupertinoApp(
      initialRoute: 'home',
      onGenerateRoute: (RouteSettings settings) {
        return CupertinoPageRoute<void>(
          settings: settings,
          builder: (BuildContext context) {
            switch (settings.name) {
              case 'home':
                return _buildHome(context);
              case 'sub':
                return _buildSub(context);
              default:
                throw UnimplementedError();
            }
          },
        );
      },
    );
  }
}

class _RestorableModalTestWidget extends StatelessWidget {
  static Route<void> _modalBuilder(BuildContext context, Object? arguments) {
    return CupertinoModalPopupRoute<void>(
      builder: (BuildContext context) {
        return CupertinoActionSheet(
          title: const Text('Title'),
          message: const Text('Message'),
          actions: <Widget>[
            CupertinoActionSheetAction(
              child: const Text('Action One'),
              onPressed: () {
                Navigator.pop(context);
              },
            ),
            CupertinoActionSheetAction(
              child: const Text('Action Two'),
              onPressed: () {
                Navigator.pop(context);
              },
            ),
          ],
        );
      },
    );
  }

  @override
  Widget build(BuildContext context) {
    return CupertinoPageScaffold(
      navigationBar: const CupertinoNavigationBar(
        middle: Text('Home'),
      ),
      child: Center(child: CupertinoButton(
        onPressed: () {
          Navigator.of(context).restorablePush(_modalBuilder);
        },
        child: const Text('X'),
      )),
    );
  }
}
