// 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:collection/collection.dart';
import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:stack_trace/stack_trace.dart';

class TestDragData {
  const TestDragData(this.slop, this.dragDistance, this.expectedOffsets);

  final Offset slop;
  final Offset dragDistance;
  final List<Offset> expectedOffsets;
}

void main() {
  testWidgets('WidgetTester.drag must break the offset into multiple parallel components if '
      'the drag goes outside the touch slop values', (WidgetTester tester) async {
    // This test checks to make sure that the total drag will be correctly split into
    // pieces such that the first (and potentially second) moveBy function call(s) in
    // controller.drag() will never have a component greater than the touch
    // slop in that component's respective axis.
    const offsetResults = <TestDragData>[
      TestDragData(Offset(10.0, 10.0), Offset(-150.0, 200.0), <Offset>[
        Offset(-7.5, 10.0),
        Offset(-2.5, 3.333333333333333),
        Offset(-140.0, 186.66666666666666),
      ]),
      TestDragData(Offset(10.0, 10.0), Offset(150, -200), <Offset>[
        Offset(7.5, -10),
        Offset(2.5, -3.333333333333333),
        Offset(140.0, -186.66666666666666),
      ]),
      TestDragData(Offset(10.0, 10.0), Offset(-200, 150), <Offset>[
        Offset(-10, 7.5),
        Offset(-3.333333333333333, 2.5),
        Offset(-186.66666666666666, 140.0),
      ]),
      TestDragData(Offset(10.0, 10.0), Offset(200.0, -150.0), <Offset>[
        Offset(10, -7.5),
        Offset(3.333333333333333, -2.5),
        Offset(186.66666666666666, -140.0),
      ]),
      TestDragData(Offset(10.0, 10.0), Offset(-150.0, -200.0), <Offset>[
        Offset(-7.5, -10.0),
        Offset(-2.5, -3.333333333333333),
        Offset(-140.0, -186.66666666666666),
      ]),
      TestDragData(Offset(10.0, 10.0), Offset(8.0, 3.0), <Offset>[Offset(8.0, 3.0)]),
      TestDragData(Offset(10.0, 10.0), Offset(3.0, 8.0), <Offset>[Offset(3.0, 8.0)]),
      TestDragData(Offset(10.0, 10.0), Offset(20.0, 5.0), <Offset>[
        Offset(10.0, 2.5),
        Offset(10.0, 2.5),
      ]),
      TestDragData(Offset(10.0, 10.0), Offset(5.0, 20.0), <Offset>[
        Offset(2.5, 10.0),
        Offset(2.5, 10.0),
      ]),
      TestDragData(Offset(10.0, 10.0), Offset(20.0, 15.0), <Offset>[
        Offset(10.0, 7.5),
        Offset(3.333333333333333, 2.5),
        Offset(6.666666666666668, 5.0),
      ]),
      TestDragData(Offset(10.0, 10.0), Offset(15.0, 20.0), <Offset>[
        Offset(7.5, 10.0),
        Offset(2.5, 3.333333333333333),
        Offset(5.0, 6.666666666666668),
      ]),
      TestDragData(Offset(10.0, 10.0), Offset(20.0, 20.0), <Offset>[
        Offset(10.0, 10.0),
        Offset(10.0, 10.0),
      ]),
      TestDragData(Offset(10.0, 10.0), Offset(0.0, 5.0), <Offset>[Offset(0.0, 5.0)]),

      //// Varying touch slops
      TestDragData(Offset(12.0, 5.0), Offset(0.0, 5.0), <Offset>[Offset(0.0, 5.0)]),
      TestDragData(Offset(12.0, 5.0), Offset(20.0, 5.0), <Offset>[
        Offset(12.0, 3.0),
        Offset(8.0, 2.0),
      ]),
      TestDragData(Offset(12.0, 5.0), Offset(5.0, 20.0), <Offset>[
        Offset(1.25, 5.0),
        Offset(3.75, 15.0),
      ]),
      TestDragData(Offset(5.0, 12.0), Offset(5.0, 20.0), <Offset>[
        Offset(3.0, 12.0),
        Offset(2.0, 8.0),
      ]),
      TestDragData(Offset(5.0, 12.0), Offset(20.0, 5.0), <Offset>[
        Offset(5.0, 1.25),
        Offset(15.0, 3.75),
      ]),
      TestDragData(Offset(18.0, 18.0), Offset(0.0, 150.0), <Offset>[
        Offset(0.0, 18.0),
        Offset(0.0, 132.0),
      ]),
      TestDragData(Offset(18.0, 18.0), Offset(0.0, -150.0), <Offset>[
        Offset(0.0, -18.0),
        Offset(0.0, -132.0),
      ]),
      TestDragData(Offset(18.0, 18.0), Offset(-150.0, 0.0), <Offset>[
        Offset(-18.0, 0.0),
        Offset(-132.0, 0.0),
      ]),
      TestDragData(Offset.zero, Offset(-150.0, 0.0), <Offset>[Offset(-150.0, 0.0)]),
      TestDragData(Offset(18.0, 18.0), Offset(-32.0, 0.0), <Offset>[
        Offset(-18.0, 0.0),
        Offset(-14.0, 0.0),
      ]),
    ];

    final dragOffsets = <Offset>[];

    await tester.pumpWidget(
      Listener(
        onPointerMove: (PointerMoveEvent event) {
          dragOffsets.add(event.delta);
        },
        child: const Text('test', textDirection: TextDirection.ltr),
      ),
    );

    for (var resultIndex = 0; resultIndex < offsetResults.length; resultIndex += 1) {
      final TestDragData testResult = offsetResults[resultIndex];
      await tester.drag(
        find.text('test'),
        testResult.dragDistance,
        touchSlopX: testResult.slop.dx,
        touchSlopY: testResult.slop.dy,
      );
      expect(
        testResult.expectedOffsets.length,
        dragOffsets.length,
        reason:
            'There is a difference in the number of expected and actual split offsets for the drag with:\n'
            'Touch Slop: ${testResult.slop}\n'
            'Delta:      ${testResult.dragDistance}\n',
      );
      for (
        var valueIndex = 0;
        valueIndex < offsetResults[resultIndex].expectedOffsets.length;
        valueIndex += 1
      ) {
        expect(
          testResult.expectedOffsets[valueIndex],
          offsetMoreOrLessEquals(dragOffsets[valueIndex]),
          reason:
              'There is a difference in the expected and actual value of the '
              '${valueIndex == 2
                  ? 'first'
                  : valueIndex == 3
                  ? 'second'
                  : 'third'}'
              ' split offset for the drag with:\n'
              'Touch slop: ${testResult.slop}\n'
              'Delta:      ${testResult.dragDistance}\n',
        );
      }
      dragOffsets.clear();
    }
  });

  testWidgets('WidgetTester.tap must respect buttons', (WidgetTester tester) async {
    final logs = <String>[];

    await tester.pumpWidget(
      Directionality(
        textDirection: TextDirection.ltr,
        child: Listener(
          onPointerDown: (PointerDownEvent event) => logs.add('down ${event.buttons}'),
          onPointerMove: (PointerMoveEvent event) => logs.add('move ${event.buttons}'),
          onPointerUp: (PointerUpEvent event) => logs.add('up ${event.buttons}'),
          child: const Text('test'),
        ),
      ),
    );

    await tester.tap(find.text('test'), buttons: kSecondaryMouseButton);

    const b = '$kSecondaryMouseButton';
    for (var i = 0; i < logs.length; i++) {
      if (i == 0) {
        expect(logs[i], 'down $b');
      } else if (i != logs.length - 1) {
        expect(logs[i], 'move $b');
      } else {
        expect(logs[i], 'up 0');
      }
    }
  });

  testWidgets('WidgetTester.press must respect buttons', (WidgetTester tester) async {
    final logs = <String>[];

    await tester.pumpWidget(
      Directionality(
        textDirection: TextDirection.ltr,
        child: Listener(
          onPointerDown: (PointerDownEvent event) => logs.add('down ${event.buttons}'),
          onPointerMove: (PointerMoveEvent event) => logs.add('move ${event.buttons}'),
          onPointerUp: (PointerUpEvent event) => logs.add('up ${event.buttons}'),
          child: const Text('test'),
        ),
      ),
    );

    await tester.press(find.text('test'), buttons: kSecondaryMouseButton);

    const b = '$kSecondaryMouseButton';
    expect(logs, equals(<String>['down $b']));
  });

  testWidgets('WidgetTester.longPress must respect buttons', (WidgetTester tester) async {
    final logs = <String>[];

    await tester.pumpWidget(
      Directionality(
        textDirection: TextDirection.ltr,
        child: Listener(
          onPointerDown: (PointerDownEvent event) => logs.add('down ${event.buttons}'),
          onPointerMove: (PointerMoveEvent event) => logs.add('move ${event.buttons}'),
          onPointerUp: (PointerUpEvent event) => logs.add('up ${event.buttons}'),
          child: const Text('test'),
        ),
      ),
    );

    await tester.longPress(find.text('test'), buttons: kSecondaryMouseButton);
    await tester.pumpAndSettle();

    const b = '$kSecondaryMouseButton';
    for (var i = 0; i < logs.length; i++) {
      if (i == 0) {
        expect(logs[i], 'down $b');
      } else if (i != logs.length - 1) {
        expect(logs[i], 'move $b');
      } else {
        expect(logs[i], 'up 0');
      }
    }
  });

  testWidgets('WidgetTester.drag must respect buttons', (WidgetTester tester) async {
    final logs = <String>[];

    await tester.pumpWidget(
      Directionality(
        textDirection: TextDirection.ltr,
        child: Listener(
          onPointerDown: (PointerDownEvent event) => logs.add('down ${event.buttons}'),
          onPointerMove: (PointerMoveEvent event) => logs.add('move ${event.buttons}'),
          onPointerUp: (PointerUpEvent event) => logs.add('up ${event.buttons}'),
          child: const Text('test'),
        ),
      ),
    );

    await tester.drag(
      find.text('test'),
      const Offset(-150.0, 200.0),
      buttons: kSecondaryMouseButton,
    );

    const b = '$kSecondaryMouseButton';
    for (var i = 0; i < logs.length; i++) {
      if (i == 0) {
        expect(logs[i], 'down $b');
      } else if (i != logs.length - 1) {
        expect(logs[i], 'move $b');
      } else {
        expect(logs[i], 'up 0');
      }
    }
  });

  testWidgets('WidgetTester.drag works with trackpad kind', (WidgetTester tester) async {
    final logs = <String>[];

    await tester.pumpWidget(
      Directionality(
        textDirection: TextDirection.ltr,
        child: Listener(
          onPointerDown: (PointerDownEvent event) => logs.add('down ${event.buttons}'),
          onPointerMove: (PointerMoveEvent event) => logs.add('move ${event.buttons}'),
          onPointerUp: (PointerUpEvent event) => logs.add('up ${event.buttons}'),
          onPointerPanZoomStart: (PointerPanZoomStartEvent event) => logs.add('panZoomStart'),
          onPointerPanZoomUpdate: (PointerPanZoomUpdateEvent event) =>
              logs.add('panZoomUpdate ${event.pan}'),
          onPointerPanZoomEnd: (PointerPanZoomEndEvent event) => logs.add('panZoomEnd'),
          child: const Text('test'),
        ),
      ),
    );

    await tester.drag(
      find.text('test'),
      const Offset(-150.0, 200.0),
      kind: PointerDeviceKind.trackpad,
    );

    for (var i = 0; i < logs.length; i++) {
      if (i == 0) {
        expect(logs[i], 'panZoomStart');
      } else if (i != logs.length - 1) {
        expect(logs[i], startsWith('panZoomUpdate'));
      } else {
        expect(logs[i], 'panZoomEnd');
      }
    }
  });

  testWidgets('WidgetTester.fling must respect buttons', (WidgetTester tester) async {
    final logs = <String>[];

    await tester.pumpWidget(
      Directionality(
        textDirection: TextDirection.ltr,
        child: Listener(
          onPointerDown: (PointerDownEvent event) => logs.add('down ${event.buttons}'),
          onPointerMove: (PointerMoveEvent event) => logs.add('move ${event.buttons}'),
          onPointerUp: (PointerUpEvent event) => logs.add('up ${event.buttons}'),
          child: const Text('test'),
        ),
      ),
    );

    await tester.fling(
      find.text('test'),
      const Offset(-10.0, 0.0),
      1000.0,
      buttons: kSecondaryMouseButton,
    );
    await tester.pumpAndSettle();

    const b = '$kSecondaryMouseButton';
    for (var i = 0; i < logs.length; i++) {
      if (i == 0) {
        expect(logs[i], 'down $b');
      } else if (i != logs.length - 1) {
        expect(logs[i], 'move $b');
      } else {
        expect(logs[i], 'up 0');
      }
    }
  });

  testWidgets('WidgetTester.fling produces strictly monotonically increasing timestamps, '
      'when given a large velocity', (WidgetTester tester) async {
    // Velocity trackers may misbehave if the `PointerMoveEvent`s' have the
    // same timestamp. This is more likely to happen when the velocity tracker
    // has a small sample size.
    final logs = <Duration>[];

    await tester.pumpWidget(
      Directionality(
        textDirection: TextDirection.ltr,
        child: Listener(
          onPointerMove: (PointerMoveEvent event) => logs.add(event.timeStamp),
          child: const Text('test'),
        ),
      ),
    );

    await tester.fling(find.text('test'), const Offset(0.0, -50.0), 10000.0);
    await tester.pumpAndSettle();

    for (var i = 0; i + 1 < logs.length; i += 1) {
      expect(logs[i + 1], greaterThan(logs[i]));
    }
  });

  testWidgets('WidgetTester.timedDrag must respect buttons', (WidgetTester tester) async {
    final logs = <String>[];

    await tester.pumpWidget(
      Directionality(
        textDirection: TextDirection.ltr,
        child: Listener(
          onPointerDown: (PointerDownEvent event) => logs.add('down ${event.buttons}'),
          onPointerMove: (PointerMoveEvent event) => logs.add('move ${event.buttons}'),
          onPointerUp: (PointerUpEvent event) => logs.add('up ${event.buttons}'),
          child: const Text('test'),
        ),
      ),
    );

    await tester.timedDrag(
      find.text('test'),
      const Offset(-200.0, 0.0),
      const Duration(seconds: 1),
      buttons: kSecondaryMouseButton,
    );
    await tester.pumpAndSettle();

    const b = '$kSecondaryMouseButton';
    for (var i = 0; i < logs.length; i++) {
      if (i == 0) {
        expect(logs[i], 'down $b');
      } else if (i != logs.length - 1) {
        expect(logs[i], 'move $b');
      } else {
        expect(logs[i], 'up 0');
      }
    }
  });

  testWidgets('WidgetTester.timedDrag uses correct pointer', (WidgetTester tester) async {
    final logs = <String>[];

    await tester.pumpWidget(
      Directionality(
        textDirection: TextDirection.ltr,
        child: Listener(
          onPointerDown: (PointerDownEvent event) => logs.add('down ${event.pointer}'),
          child: const Text('test'),
        ),
      ),
    );

    await tester.timedDrag(
      find.text('test'),
      const Offset(-200.0, 0.0),
      const Duration(seconds: 1),
      buttons: kSecondaryMouseButton,
    );
    await tester.pumpAndSettle();

    await tester.timedDrag(
      find.text('test'),
      const Offset(200.0, 0.0),
      const Duration(seconds: 1),
      buttons: kSecondaryMouseButton,
    );
    await tester.pumpAndSettle();

    expect(logs.length, 2);
    expect(logs[0], isNotNull);
    expect(logs[1], isNotNull);
    expect(logs[1] != logs[0], isTrue);
  });

  testWidgets('WidgetTester.tap appears in stack trace on error', (WidgetTester tester) async {
    // Regression test from https://github.com/flutter/flutter/pull/123946
    await tester.pumpWidget(const MaterialApp(home: Scaffold(body: Text('target'))));

    final TestGesture gesture = await tester.startGesture(
      tester.getCenter(find.text('target')),
      pointer: 1,
    );
    addTearDown(() => gesture.up());

    Trace? stackTrace;
    try {
      await tester.tap(find.text('target'), pointer: 1);
    } on Error catch (e) {
      stackTrace = Trace.from(e.stackTrace!);
    }
    expect(stackTrace, isNotNull);

    final int tapFrame = stackTrace!.frames.indexWhere(
      (Frame frame) => frame.member == 'WidgetController.tap',
    );
    expect(tapFrame, greaterThanOrEqualTo(0));
    expect(stackTrace.frames[tapFrame].package, 'flutter_test');
    expect(stackTrace.frames[tapFrame + 1].member, 'main.<fn>');
    expect(stackTrace.frames[tapFrame + 1].package, null);
  });

  testWidgets('ensureVisible: scrolls to make widget visible', (WidgetTester tester) async {
    await tester.pumpWidget(
      MaterialApp(
        home: Scaffold(
          body: ListView.builder(
            itemCount: 20,
            shrinkWrap: true,
            itemBuilder: (BuildContext context, int i) => ListTile(title: Text('Item $i')),
          ),
        ),
      ),
    );

    // Make sure widget isn't on screen
    expect(find.text('Item 15'), findsNothing);

    await tester.ensureVisible(find.text('Item 15', skipOffstage: false));
    await tester.pumpAndSettle();

    expect(find.text('Item 15'), findsOneWidget);
  });

  group('scrollUntilVisible: scrolls to make unbuilt widget visible', () {
    testWidgets('Vertical', (WidgetTester tester) async {
      await tester.pumpWidget(
        MaterialApp(
          home: Scaffold(
            body: ListView.builder(
              itemCount: 50,
              shrinkWrap: true,
              itemBuilder: (BuildContext context, int i) => ListTile(title: Text('Item $i')),
            ),
          ),
        ),
      );

      // Make sure widget isn't built yet.
      expect(find.text('Item 45', skipOffstage: false), findsNothing);

      await tester.scrollUntilVisible(find.text('Item 45', skipOffstage: false), 100);
      await tester.pumpAndSettle();

      // Now the widget is on screen.
      expect(find.text('Item 45'), findsOneWidget);
    });

    testWidgets('Horizontal', (WidgetTester tester) async {
      await tester.pumpWidget(
        MaterialApp(
          home: Scaffold(
            body: ListView.builder(
              itemCount: 50,
              shrinkWrap: true,
              scrollDirection: Axis.horizontal,
              // ListTile does not support horizontal list
              itemBuilder: (BuildContext context, int i) => Text('Item $i'),
            ),
          ),
        ),
      );

      // Make sure widget isn't built yet.
      expect(find.text('Item 45', skipOffstage: false), findsNothing);

      await tester.scrollUntilVisible(find.text('Item 45', skipOffstage: false), 100);
      await tester.pumpAndSettle();

      // Now the widget is on screen.
      expect(find.text('Item 45'), findsOneWidget);
    });

    testWidgets('Fail', (WidgetTester tester) async {
      await tester.pumpWidget(
        MaterialApp(
          home: Scaffold(
            body: ListView.builder(
              itemCount: 50,
              shrinkWrap: true,
              itemBuilder: (BuildContext context, int i) => ListTile(title: Text('Item $i')),
            ),
          ),
        ),
      );

      try {
        await tester.scrollUntilVisible(find.text('Item 55', skipOffstage: false), 100);
      } on StateError catch (e) {
        expect(e.message, 'No element');
      }
    });

    testWidgets('Drag Until Visible', (WidgetTester tester) async {
      // when there are two implicit [Scrollable], `scrollUntilVisible` is hard
      // to use.
      await tester.pumpWidget(
        MaterialApp(
          home: Scaffold(
            body: Column(
              children: <Widget>[
                SizedBox(
                  height: 200,
                  child: ListView.builder(
                    key: const Key('listView-a'),
                    itemCount: 50,
                    shrinkWrap: true,
                    itemBuilder: (BuildContext context, int i) =>
                        ListTile(title: Text('Item a-$i')),
                  ),
                ),
                const Padding(
                  padding: EdgeInsets.all(4),
                  child: ColoredBox(
                    color: Color(0xFF000000),
                    child: SizedBox(height: 5, width: double.infinity),
                  ),
                ),
                Expanded(
                  child: ListView.builder(
                    key: const Key('listView-b'),
                    itemCount: 50,
                    shrinkWrap: true,
                    itemBuilder: (BuildContext context, int i) =>
                        ListTile(title: Text('Item b-$i')),
                  ),
                ),
              ],
            ),
          ),
        ),
      );
      await tester.pumpAndSettle();
      expect(find.byType(Scrollable), findsNWidgets(2));

      // Make sure widget isn't built yet.
      expect(find.text('Item b-45', skipOffstage: false), findsNothing);

      await tester.dragUntilVisible(
        find.text('Item b-45', skipOffstage: false),
        find.byKey(const ValueKey<String>('listView-b')),
        const Offset(0, -100),
      );
      await tester.pumpAndSettle();

      // Now the widget is on screen.
      expect(find.text('Item b-45'), findsOneWidget);
    });
  });

  // Regression test for https://github.com/flutter/flutter/issues/143921.
  testWidgets('WidgetTester.scrollUntilVisible should work together with onTap', (
    WidgetTester tester,
  ) async {
    const itemCount = 20;

    Widget buildFrame(bool hasOnTap) {
      return MaterialApp(
        home: Scaffold(
          body: ListView.builder(
            key: ValueKey<bool>(hasOnTap), // Trigger a rebuild.
            itemCount: itemCount,
            itemBuilder: (BuildContext context, int index) {
              return ListTile(onTap: hasOnTap ? () {} : null, title: Text('$index'));
            },
          ),
        ),
      );
    }

    final Finder target = find.text('${itemCount - 1}');
    final Finder scrollable = find.byType(Scrollable);

    // Scroll without onTap.
    await tester.pumpWidget(buildFrame(false));
    await tester.pumpAndSettle();
    expect(target, findsNothing);
    await tester.scrollUntilVisible(target, 20, scrollable: scrollable, continuous: true);
    expect(target, findsOneWidget);

    // Scroll with onTap.
    await tester.pumpWidget(buildFrame(true));
    await tester.pumpAndSettle();
    expect(target, findsNothing);
    await tester.scrollUntilVisible(target, 20, scrollable: scrollable, continuous: true);
    expect(target, findsOneWidget);
  });

  testWidgets('platformDispatcher exposes the platformDispatcher from binding', (
    WidgetTester tester,
  ) async {
    expect(tester.platformDispatcher, tester.binding.platformDispatcher);
  });

  testWidgets('view exposes the implicitView from platformDispatcher', (WidgetTester tester) async {
    expect(tester.view, tester.platformDispatcher.implicitView);
  });

  testWidgets('viewOf finds a view when the view is implicit', (WidgetTester tester) async {
    await tester.pumpWidget(const MaterialApp(home: Center(child: Text('Test'))));

    expect(() => tester.viewOf(find.text('Test')), isNot(throwsA(anything)));
    expect(tester.viewOf(find.text('Test')), isA<TestFlutterView>());
  });

  group('SemanticsController', () {
    group('find', () {
      testWidgets('throws when there are no semantics', (WidgetTester tester) async {
        await tester.pumpWidget(const MaterialApp(home: Scaffold(body: Text('hello'))));

        expect(() => tester.semantics.find(find.text('hello')), throwsStateError);
      }, semanticsEnabled: false);

      testWidgets('throws when there are multiple results from the finder', (
        WidgetTester tester,
      ) async {
        await tester.pumpWidget(
          const MaterialApp(
            home: Scaffold(body: Row(children: <Widget>[Text('hello'), Text('hello')])),
          ),
        );

        expect(() => tester.semantics.find(find.text('hello')), throwsStateError);
      });

      testWidgets('Returns the correct SemanticsData', (WidgetTester tester) async {
        await tester.pumpWidget(
          MaterialApp(
            home: Scaffold(
              body: OutlinedButton(onPressed: () {}, child: const Text('hello')),
            ),
          ),
        );

        final SemanticsNode node = tester.semantics.find(find.text('hello'));
        final SemanticsData semantics = node.getSemanticsData();
        expect(semantics.label, 'hello');
        expect(semantics.hasAction(SemanticsAction.tap), true);
        expect(semantics.hasFlag(SemanticsFlag.isButton), true);
      });

      testWidgets('Can enable semantics for tests via semanticsEnabled', (
        WidgetTester tester,
      ) async {
        await tester.pumpWidget(
          MaterialApp(
            home: Scaffold(
              body: OutlinedButton(onPressed: () {}, child: const Text('hello')),
            ),
          ),
        );

        final SemanticsNode node = tester.semantics.find(find.text('hello'));
        final SemanticsData semantics = node.getSemanticsData();
        expect(semantics.label, 'hello');
        expect(semantics.hasAction(SemanticsAction.tap), true);
        expect(semantics.hasFlag(SemanticsFlag.isButton), true);
      });

      testWidgets('Returns merged SemanticsData', (WidgetTester tester) async {
        const key = Key('test');
        await tester.pumpWidget(
          MaterialApp(
            home: Scaffold(
              body: Semantics(
                label: 'A',
                child: Semantics(
                  label: 'B',
                  child: Semantics(key: key, label: 'C', child: Container()),
                ),
              ),
            ),
          ),
        );

        final SemanticsNode node = tester.semantics.find(find.byKey(key));
        final SemanticsData semantics = node.getSemanticsData();
        expect(semantics.label, 'A\nB\nC');
      });

      testWidgets('Does not return partial semantics', (WidgetTester tester) async {
        final Key key = UniqueKey();
        await tester.pumpWidget(
          MaterialApp(
            home: Scaffold(
              body: MergeSemantics(
                child: Semantics(
                  container: true,
                  label: 'A',
                  child: Semantics(container: true, key: key, label: 'B', child: Container()),
                ),
              ),
            ),
          ),
        );

        final SemanticsNode node = tester.semantics.find(find.byKey(key));
        final SemanticsData semantics = node.getSemanticsData();
        expect(semantics.label, 'A\nB');
      });
    });

    group('simulatedTraversal', () {
      final fullTraversalMatchers = <Matcher>[
        isSemantics(isHeader: true, label: 'Semantics Test'),
        isSemantics(label: 'Text Field'),
        isSemantics(isTextField: true),
        isSemantics(label: 'Off Switch'),
        isSemantics(hasToggledState: true),
        isSemantics(label: 'On Switch'),
        isSemantics(hasToggledState: true, isToggled: true),
        isSemantics(label: "Multiline\nIt's a\nmultiline label!"),
        isSemantics(label: 'Slider'),
        isSemantics(isSlider: true, value: '50%'),
        isSemantics(label: 'Enabled Button'),
        isSemantics(isButton: true, label: 'Tap'),
        isSemantics(label: 'Disabled Button'),
        isSemantics(isButton: true, label: "Don't Tap"),
        isSemantics(label: 'Checked Radio'),
        isSemantics(hasCheckedState: true, isChecked: true),
        isSemantics(label: 'Unchecked Radio'),
        isSemantics(hasCheckedState: true, isChecked: false),
      ];

      testWidgets('produces expected traversal', (WidgetTester tester) async {
        await tester.pumpWidget(const MaterialApp(home: _SemanticsTestWidget()));

        expect(
          tester.semantics.simulatedAccessibilityTraversal(),
          orderedEquals(fullTraversalMatchers),
        );
      });

      testWidgets('starts traversal at semantics node for `start`', (WidgetTester tester) async {
        await tester.pumpWidget(const MaterialApp(home: _SemanticsTestWidget()));

        // We're expecting the traversal to start where the slider is.
        final expectedMatchers = <Matcher>[...fullTraversalMatchers]..removeRange(0, 8);

        expect(
          tester.semantics.simulatedAccessibilityTraversal(start: find.byType(Slider)),
          orderedEquals(expectedMatchers),
        );
      });

      testWidgets('simulatedAccessibilityTraversal end Index supports empty traversal', (
        WidgetTester tester,
      ) async {
        await tester.pumpWidget(
          const MaterialApp(
            home: Center(
              child: Column(), // No nodes!
            ),
          ),
        );
        expect(
          tester.semantics.simulatedAccessibilityTraversal().map(
            (SemanticsNode node) => node.label,
          ),
          <String>[],
        );
      });

      testWidgets('starts traversal at semantics node for `startNode`', (
        WidgetTester tester,
      ) async {
        await tester.pumpWidget(
          MaterialApp(
            home: Center(
              child: Column(
                children: <Widget>[
                  for (int c = 0; c < 5; c++) Semantics(container: true, child: Text('Child$c')),
                ],
              ),
            ),
          ),
        );
        expect(
          tester.semantics
              .simulatedAccessibilityTraversal(startNode: find.semantics.byLabel('Child1'))
              .map((SemanticsNode node) => node.label),
          <String>['Child1', 'Child2', 'Child3', 'Child4'],
        );
      });

      testWidgets('throws StateError if `start` not found in traversal', (
        WidgetTester tester,
      ) async {
        await tester.pumpWidget(const MaterialApp(home: _SemanticsTestWidget()));

        // We look for a SingleChildScrollView since the view itself isn't
        // important for accessibility, so it won't show up in the traversal
        expect(
          () => tester.semantics.simulatedAccessibilityTraversal(
            start: find.byType(SingleChildScrollView),
          ),
          throwsA(isA<StateError>()),
        );
      });

      testWidgets('throws StateError if `startNode` not found in traversal', (
        WidgetTester tester,
      ) async {
        await tester.pumpWidget(
          MaterialApp(
            home: Center(
              child: Column(
                children: <Widget>[
                  for (int c = 0; c < 5; c++) Semantics(container: true, child: Text('Child$c')),
                ],
              ),
            ),
          ),
        );
        expect(
          () => tester.semantics.simulatedAccessibilityTraversal(
            startNode: find.semantics.byLabel('Child20'),
          ),
          throwsA(isA<StateError>()),
        );
      });

      testWidgets('ends traversal at semantics node for `end`', (WidgetTester tester) async {
        await tester.pumpWidget(const MaterialApp(home: _SemanticsTestWidget()));

        // We're expecting the traversal to end where the slider is, inclusive.
        final Iterable<Matcher> expectedMatchers = <Matcher>[
          ...fullTraversalMatchers,
        ].getRange(0, 9);

        expect(
          tester.semantics.simulatedAccessibilityTraversal(end: find.byType(Slider)),
          orderedEquals(expectedMatchers),
        );
      });

      testWidgets('ends traversal at semantics node for `endNode`', (WidgetTester tester) async {
        await tester.pumpWidget(
          MaterialApp(
            home: Center(
              child: Column(
                children: <Widget>[
                  for (int c = 0; c < 5; c++) Semantics(container: true, child: Text('Child$c')),
                ],
              ),
            ),
          ),
        );
        expect(
          tester.semantics
              .simulatedAccessibilityTraversal(endNode: find.semantics.byLabel('Child1'))
              .map((SemanticsNode node) => node.label),
          <String>['Child0', 'Child1'],
        );
      });

      testWidgets('throws StateError if `end` not found in traversal', (WidgetTester tester) async {
        await tester.pumpWidget(const MaterialApp(home: _SemanticsTestWidget()));

        // We look for a SingleChildScrollView since the view itself isn't
        // important for semantics, so it won't show up in the traversal
        expect(
          () => tester.semantics.simulatedAccessibilityTraversal(
            end: find.byType(SingleChildScrollView),
          ),
          throwsA(isA<StateError>()),
        );
      });

      testWidgets('throws StateError if `endNode` not found in traversal', (
        WidgetTester tester,
      ) async {
        await tester.pumpWidget(
          MaterialApp(
            home: Center(
              child: Column(
                children: <Widget>[
                  for (int c = 0; c < 5; c++) Semantics(container: true, child: Text('Child$c')),
                ],
              ),
            ),
          ),
        );
        expect(
          () => tester.semantics.simulatedAccessibilityTraversal(
            endNode: find.semantics.byLabel('Child20'),
          ),
          throwsA(isA<StateError>()),
        );
      });

      testWidgets('returns traversal between `start` and `end` if both are provided', (
        WidgetTester tester,
      ) async {
        await tester.pumpWidget(const MaterialApp(home: _SemanticsTestWidget()));

        // We're expecting the traversal to start at the text field and end at the slider.
        final Iterable<Matcher> expectedMatchers = <Matcher>[
          ...fullTraversalMatchers,
        ].getRange(1, 9);

        expect(
          tester.semantics.simulatedAccessibilityTraversal(
            start: find.byType(TextField),
            end: find.byType(Slider),
          ),
          orderedEquals(expectedMatchers),
        );
      });

      testWidgets('returns traversal between `startNode` and `endNode` if both are provided', (
        WidgetTester tester,
      ) async {
        await tester.pumpWidget(
          MaterialApp(
            home: Center(
              child: Column(
                children: <Widget>[
                  for (int c = 0; c < 5; c++) Semantics(container: true, child: Text('Child$c')),
                ],
              ),
            ),
          ),
        );
        expect(
          tester.semantics
              .simulatedAccessibilityTraversal(
                startNode: find.semantics.byLabel('Child1'),
                endNode: find.semantics.byLabel('Child3'),
              )
              .map((SemanticsNode node) => node.label),
          <String>['Child1', 'Child2', 'Child3'],
        );
      });

      testWidgets('can do fuzzy traversal match with `containsAllInOrder`', (
        WidgetTester tester,
      ) async {
        await tester.pumpWidget(const MaterialApp(home: _SemanticsTestWidget()));

        // Grab a sample of the matchers to validate that not every matcher is
        // needed to validate a traversal when using `containsAllInOrder`.
        final Iterable<Matcher> expectedMatchers = <Matcher>[...fullTraversalMatchers]
          ..removeAt(0)
          ..removeLast()
          ..mapIndexed<Matcher?>((int i, Matcher element) => i.isEven ? element : null).nonNulls;

        expect(
          tester.semantics.simulatedAccessibilityTraversal(),
          containsAllInOrder(expectedMatchers),
        );
      });

      testWidgets('merging node should not be visited', (WidgetTester tester) async {
        await tester.pumpWidget(
          MaterialApp(
            home: MergeSemantics(
              child: Column(
                children: <Widget>[
                  Semantics(container: true, child: const Text('1')),
                  Semantics(container: true, child: const Text('2')),
                  Semantics(container: true, child: const Text('3')),
                ],
              ),
            ),
          ),
        );

        expect(
          tester.semantics.simulatedAccessibilityTraversal(),
          orderedEquals(<Matcher>[isSemantics(label: '1\n2\n3')]),
        );
      });
      testWidgets('a node with only a tooltip is important for accessibility', (
        WidgetTester tester,
      ) async {
        await tester.pumpWidget(
          const MaterialApp(
            home: Tooltip(message: 'My tooltip', child: SizedBox()),
          ),
        );
        expect(
          tester.semantics.simulatedAccessibilityTraversal(),
          contains(isSemantics(tooltip: 'My tooltip')),
        );
      });
    });

    group('actions', () {
      testWidgets('performAction with unsupported action throws StateError', (
        WidgetTester tester,
      ) async {
        await tester.pumpWidget(Semantics(onTap: () {}));

        expect(
          () => tester.semantics.performAction(
            find.semantics.byLabel('Test'),
            SemanticsAction.dismiss,
          ),
          throwsStateError,
        );
      });

      testWidgets('tap causes semantic tap', (WidgetTester tester) async {
        var invoked = false;
        await tester.pumpWidget(
          MaterialApp(
            home: TextButton(onPressed: () => invoked = true, child: const Text('Test Button')),
          ),
        );

        tester.semantics.tap(find.semantics.byAction(SemanticsAction.tap));
        expect(invoked, isTrue);
      });

      testWidgets('longPress causes semantic long press', (WidgetTester tester) async {
        var invoked = false;
        await tester.pumpWidget(
          MaterialApp(
            home: TextButton(
              onPressed: () {},
              onLongPress: () => invoked = true,
              child: const Text('Test Button'),
            ),
          ),
        );

        tester.semantics.longPress(find.semantics.byAction(SemanticsAction.longPress));
        expect(invoked, isTrue);
      });

      testWidgets('scrollLeft and scrollRight scroll left and right respectively', (
        WidgetTester tester,
      ) async {
        await tester.pumpWidget(
          MaterialApp(
            home: ListView(
              scrollDirection: Axis.horizontal,
              children: <Widget>[
                SizedBox(height: 40, width: tester.binding.window.physicalSize.width * 1.5),
              ],
            ),
          ),
        );

        expect(
          find.semantics.scrollable(),
          isSemantics(hasScrollLeftAction: true, hasScrollRightAction: false),
          reason:
              'When not yet scrolled, a scrollview should only be able to support left scrolls.',
        );

        tester.semantics.scrollLeft();
        await tester.pump();

        expect(
          find.semantics.scrollable(),
          isSemantics(hasScrollLeftAction: true, hasScrollRightAction: true),
          reason:
              'When partially scrolled, a scrollview should be able to support both left and right scrolls.',
        );

        // This will scroll the listview until it's completely scrolled to the right.
        final SemanticsFinder leftScrollable = find.semantics.byAction(SemanticsAction.scrollLeft);
        while (leftScrollable.tryEvaluate()) {
          tester.semantics.scrollLeft(scrollable: leftScrollable);
          await tester.pump();
        }

        expect(
          find.semantics.scrollable(),
          isSemantics(hasScrollLeftAction: false, hasScrollRightAction: true),
          reason: 'When fully scrolled, a scrollview should only support right scrolls.',
        );

        tester.semantics.scrollRight();
        await tester.pump();

        expect(
          find.semantics.scrollable(),
          isSemantics(hasScrollLeftAction: true, hasScrollRightAction: true),
          reason:
              'When partially scrolled, a scrollview should be able to support both left and right scrolls.',
        );
      });

      testWidgets('scrollUp and scrollDown scrolls up and down respectively', (
        WidgetTester tester,
      ) async {
        await tester.pumpWidget(
          MaterialApp(
            home: ListView(
              children: <Widget>[
                SizedBox(height: tester.binding.window.physicalSize.height * 1.5, width: 40),
              ],
            ),
          ),
        );

        expect(
          find.semantics.scrollable(),
          isSemantics(hasScrollUpAction: true, hasScrollDownAction: false),
          reason:
              'When not yet scrolled, a scrollview should only be able to support left scrolls.',
        );

        tester.semantics.scrollUp();
        await tester.pump();

        expect(
          find.semantics.scrollable(),
          isSemantics(hasScrollUpAction: true, hasScrollDownAction: true),
          reason:
              'When partially scrolled, a scrollview should be able to support both left and right scrolls.',
        );

        // This will scroll the listview until it's completely scrolled to the right.
        final SemanticsFinder upScrollable = find.semantics.byAction(SemanticsAction.scrollUp);
        while (upScrollable.tryEvaluate()) {
          tester.semantics.scrollUp(scrollable: upScrollable);
          await tester.pump();
        }

        expect(
          find.semantics.scrollable(),
          isSemantics(hasScrollUpAction: false, hasScrollDownAction: true),
          reason: 'When fully scrolled, a scrollview should only support right scrolls.',
        );

        tester.semantics.scrollDown();
        await tester.pump();

        expect(
          find.semantics.scrollable(),
          isSemantics(hasScrollUpAction: true, hasScrollDownAction: true),
          reason:
              'When partially scrolled, a scrollview should be able to support both left and right scrolls.',
        );
      });

      testWidgets('increase causes semantic increase', (WidgetTester tester) async {
        var invoked = false;
        await tester.pumpWidget(
          MaterialApp(
            home: Material(
              child: _StatefulSlider(
                initialValue: 0,
                onChanged: (double _) {
                  invoked = true;
                },
              ),
            ),
          ),
        );

        final SemanticsFinder sliderFinder = find.semantics.byFlag(SemanticsFlag.isSlider);
        final String expected = sliderFinder.evaluate().single.increasedValue;
        tester.semantics.increase(sliderFinder);
        await tester.pumpAndSettle();

        expect(invoked, isTrue);
        expect(
          find.semantics.byFlag(SemanticsFlag.isSlider).evaluate().single.value,
          equals(expected),
        );
      });

      testWidgets('decrease causes semantic decrease', (WidgetTester tester) async {
        var invoked = false;
        await tester.pumpWidget(
          MaterialApp(
            home: Material(
              child: _StatefulSlider(
                initialValue: 1,
                onChanged: (double _) {
                  invoked = true;
                },
              ),
            ),
          ),
        );

        final SemanticsFinder sliderFinder = find.semantics.byFlag(SemanticsFlag.isSlider);
        final String expected = sliderFinder.evaluate().single.decreasedValue;
        tester.semantics.decrease(sliderFinder);
        await tester.pumpAndSettle();

        expect(invoked, isTrue);
        expect(
          find.semantics.byFlag(SemanticsFlag.isSlider).evaluate().single.value,
          equals(expected),
        );
      });

      testWidgets('showOnScreen sends showOnScreen action', (WidgetTester tester) async {
        final controller = ScrollController(initialScrollOffset: 50);
        addTearDown(controller.dispose);
        await tester.pumpWidget(
          MaterialApp(
            home: ListView(
              controller: controller,
              children: <Widget>[
                const MergeSemantics(child: SizedBox(height: 40, child: Text('Test'))),
                SizedBox(width: 40, height: tester.binding.window.physicalSize.height * 1.5),
              ],
            ),
          ),
        );

        expect(find.semantics.byLabel('Test'), isSemantics(isHidden: true));

        tester.semantics.showOnScreen(find.semantics.byLabel('Test'));
        await tester.pump();

        expect(tester.semantics.find(find.text('Test')), isSemantics(isHidden: false));
      });

      testWidgets(
        'actions for moving the cursor without modifying selection can move the cursor forward and back by character and word',
        (WidgetTester tester) async {
          const text = 'This is some text.';
          int currentIndex = text.length;
          final controller = TextEditingController(text: text);
          addTearDown(controller.dispose);
          await tester.pumpWidget(
            MaterialApp(
              home: Material(child: TextField(controller: controller)),
            ),
          );

          void expectUnselectedIndex(int expectedIndex) {
            expect(controller.selection.start, equals(expectedIndex));
            expect(controller.selection.end, equals(expectedIndex));
          }

          final SemanticsFinder finder = find.semantics.byValue(text);

          // Get focus onto the text field
          tester.semantics.tap(finder);
          await tester.pump();

          tester.semantics.moveCursorBackwardByCharacter(finder);
          await tester.pump();
          expectUnselectedIndex(currentIndex - 1);
          currentIndex -= 1;

          tester.semantics.moveCursorBackwardByWord(finder);
          await tester.pump();
          expectUnselectedIndex(currentIndex - 4);
          currentIndex -= 4;

          tester.semantics.moveCursorBackwardByWord(finder);
          await tester.pump();
          expectUnselectedIndex(currentIndex - 5);
          currentIndex -= 5;

          tester.semantics.moveCursorForwardByCharacter(finder);
          await tester.pump();
          expectUnselectedIndex(currentIndex + 1);
          currentIndex += 1;

          tester.semantics.moveCursorForwardByWord(finder);
          await tester.pump();
          expectUnselectedIndex(currentIndex + 4);
          currentIndex += 4;
        },
      );

      testWidgets(
        'actions for moving the cursor with modifying selection can update the selection forward and back by character and word',
        (WidgetTester tester) async {
          const text = 'This is some text.';
          int currentIndex = text.length;
          final controller = TextEditingController(text: text);
          addTearDown(controller.dispose);
          await tester.pumpWidget(
            MaterialApp(
              home: Material(child: TextField(controller: controller)),
            ),
          );

          void expectSelectedIndex(int start) {
            expect(controller.selection.start, equals(start));
            expect(controller.selection.end, equals(text.length));
          }

          final SemanticsFinder finder = find.semantics.byValue(text);

          // Get focus onto the text field
          tester.semantics.tap(finder);
          await tester.pump();

          tester.semantics.moveCursorBackwardByCharacter(finder, shouldModifySelection: true);
          await tester.pump();
          expectSelectedIndex(currentIndex - 1);
          currentIndex -= 1;

          tester.semantics.moveCursorBackwardByWord(finder, shouldModifySelection: true);
          await tester.pump();
          expectSelectedIndex(currentIndex - 4);
          currentIndex -= 4;

          tester.semantics.moveCursorBackwardByWord(finder, shouldModifySelection: true);
          await tester.pump();
          expectSelectedIndex(currentIndex - 5);
          currentIndex -= 5;

          tester.semantics.moveCursorForwardByCharacter(finder, shouldModifySelection: true);
          await tester.pump();
          expectSelectedIndex(currentIndex + 1);
          currentIndex += 1;

          tester.semantics.moveCursorForwardByWord(finder, shouldModifySelection: true);
          await tester.pump();
          expectSelectedIndex(currentIndex + 4);
          currentIndex += 4;
        },
      );

      testWidgets('setText causes semantics to set the text', (WidgetTester tester) async {
        const expectedText = 'This is some text.';
        final controller = TextEditingController();
        addTearDown(controller.dispose);
        await tester.pumpWidget(
          MaterialApp(
            home: Material(child: TextField(controller: controller)),
          ),
        );

        final SemanticsFinder finder = find.semantics.byFlag(SemanticsFlag.isTextField);

        tester.semantics.tap(finder);
        await tester.pump();

        tester.semantics.setText(finder, expectedText);
        await tester.pump();

        expect(controller.text, equals(expectedText));
      });

      testWidgets('setSelection causes semantics to select text', (WidgetTester tester) async {
        const text = 'This is some text.';
        const int expectedStart = text.length - 8;
        const int expectedEnd = text.length - 4;
        final controller = TextEditingController(text: text);
        addTearDown(controller.dispose);
        await tester.pumpWidget(
          MaterialApp(
            home: Material(child: TextField(controller: controller)),
          ),
        );

        final SemanticsFinder finder = find.semantics.byFlag(SemanticsFlag.isTextField);

        tester.semantics.tap(finder);
        await tester.pump();

        tester.semantics.setSelection(finder, base: expectedStart, extent: expectedEnd);
        await tester.pump();

        expect(controller.selection.start, equals(expectedStart));
        expect(controller.selection.end, equals(expectedEnd));
      });

      testWidgets('copy sends semantic copy', (WidgetTester tester) async {
        var invoked = false;
        await tester.pumpWidget(
          MaterialApp(
            home: Semantics(label: 'test', onCopy: () => invoked = true),
          ),
        );

        tester.semantics.copy(find.semantics.byLabel('test'));
        expect(invoked, isTrue);
      });

      testWidgets('cut sends semantic cut', (WidgetTester tester) async {
        var invoked = false;
        await tester.pumpWidget(
          MaterialApp(
            home: Semantics(label: 'test', onCut: () => invoked = true),
          ),
        );

        tester.semantics.cut(find.semantics.byLabel('test'));
        expect(invoked, isTrue);
      });

      testWidgets('paste sends semantic paste', (WidgetTester tester) async {
        var invoked = false;
        await tester.pumpWidget(
          MaterialApp(
            home: Semantics(label: 'test', onPaste: () => invoked = true),
          ),
        );

        tester.semantics.paste(find.semantics.byLabel('test'));
        expect(invoked, isTrue);
      });

      testWidgets('didGainAccessibilityFocus causes semantic focus on node', (
        WidgetTester tester,
      ) async {
        var invoked = false;
        await tester.pumpWidget(
          MaterialApp(
            home: Semantics(label: 'test', onDidGainAccessibilityFocus: () => invoked = true),
          ),
        );

        tester.semantics.didGainAccessibilityFocus(find.semantics.byLabel('test'));
        expect(invoked, isTrue);
      });

      testWidgets('didLoseAccessibility causes semantic focus to be lost', (
        WidgetTester tester,
      ) async {
        var invoked = false;
        await tester.pumpWidget(
          MaterialApp(
            home: Semantics(label: 'test', onDidLoseAccessibilityFocus: () => invoked = true),
          ),
        );

        tester.semantics.didLoseAccessibilityFocus(find.semantics.byLabel('test'));
        expect(invoked, isTrue);
      });

      testWidgets('dismiss sends semantic dismiss', (WidgetTester tester) async {
        final GlobalKey key = GlobalKey();
        const duration = Duration(seconds: 3);
        final halfDuration = Duration(milliseconds: (duration.inMilliseconds / 2).floor());
        late SnackBarClosedReason reason;

        await tester.pumpWidget(MaterialApp(home: Scaffold(key: key)));

        final ScaffoldMessengerState messenger = ScaffoldMessenger.of(key.currentContext!);
        messenger
            .showSnackBar(
              const SnackBar(content: SizedBox(height: 40, width: 300), duration: duration),
            )
            .closed
            // ignore: unawaited_futures
            .then((SnackBarClosedReason result) => reason = result);
        await tester.pumpFrames(tester.widget(find.byType(MaterialApp)), halfDuration);

        tester.semantics.dismiss(find.semantics.byAction(SemanticsAction.dismiss));
        await tester.pumpAndSettle();

        expect(reason, equals(SnackBarClosedReason.dismiss));
      });

      testWidgets('customAction invokes appropriate custom action', (WidgetTester tester) async {
        const customAction = CustomSemanticsAction(label: 'test');
        var invoked = false;
        await tester.pumpWidget(
          MaterialApp(
            home: Semantics(
              label: 'test',
              customSemanticsActions: <CustomSemanticsAction, void Function()>{
                customAction: () => invoked = true,
              },
            ),
          ),
        );

        tester.semantics.customAction(find.semantics.byLabel('test'), customAction);
        await tester.pump();

        expect(invoked, isTrue);
      });
    });
  });

  group('WidgetTester.tapOnText', () {
    final tapLogs = <String>[];
    final tapA = TapGestureRecognizer()
      ..onTap = () {
        tapLogs.add('A');
      };
    final tapB = TapGestureRecognizer()
      ..onTap = () {
        tapLogs.add('B');
      };
    final tapC = TapGestureRecognizer()
      ..onTap = () {
        tapLogs.add('C');
      };
    tearDown(tapLogs.clear);
    tearDownAll(() {
      tapA.dispose();
      tapB.dispose();
      tapC.dispose();
    });

    testWidgets('basic test', (WidgetTester tester) async {
      await tester.pumpWidget(
        Directionality(
          textDirection: TextDirection.ltr,
          child: Text.rich(TextSpan(text: 'match', recognizer: tapA)),
        ),
      );

      await tester.tapOnText(find.textRange.ofSubstring('match'));
      expect(tapLogs, <String>['A']);
    });

    testWidgets('partially obstructed: find a hit-testable Offset', (WidgetTester tester) async {
      await tester.pumpWidget(
        Directionality(
          textDirection: TextDirection.ltr,
          child: Stack(
            fit: StackFit.expand,
            children: <Widget>[
              Positioned(
                left: 100.0 - 9 * 10.0, // Only the last character is visible.
                child: Text.rich(
                  TextSpan(
                    text: 'text match',
                    style: const TextStyle(fontSize: 10),
                    recognizer: tapA,
                  ),
                ),
              ),
              const Positioned(
                left: 0.0,
                right: 100.0,
                child: MetaData(behavior: HitTestBehavior.opaque),
              ),
            ],
          ),
        ),
      );

      await expectLater(
        () => tester.tapOnText(find.textRange.ofSubstring('text match')),
        returnsNormally,
      );
    });

    testWidgets('multiline text partially obstructed: find a hit-testable Offset', (
      WidgetTester tester,
    ) async {
      await tester.pumpWidget(
        Directionality(
          textDirection: TextDirection.ltr,
          child: Stack(
            fit: StackFit.expand,
            children: <Widget>[
              Positioned(
                width: 100.0,
                top: 23.0,
                left: 0.0,
                child: Text.rich(
                  TextSpan(
                    style: const TextStyle(fontSize: 10),
                    children: <InlineSpan>[
                      TextSpan(text: 'AAAAAAAAA ', recognizer: tapA),
                      TextSpan(text: 'BBBBBBBBB ', recognizer: tapB), // The only visible line
                      TextSpan(text: 'CCCCCCCCC ', recognizer: tapC),
                    ],
                  ),
                ),
              ),
              const Positioned(
                top: 23.0, // Some random offset to test the global to local Offset conversion
                left: 0.0,
                right: 0.0,
                height: 10.0,
                child: MetaData(behavior: HitTestBehavior.opaque, child: SizedBox.expand()),
              ),
              const Positioned(
                top: 43.0,
                left: 0.0,
                right: 0.0,
                height: 10.0,
                child: MetaData(behavior: HitTestBehavior.opaque, child: SizedBox.expand()),
              ),
            ],
          ),
        ),
      );

      await tester.tapOnText(find.textRange.ofSubstring('AAAAAAAAA BBBBBBBBB CCCCCCCCC '));
      expect(tapLogs, <String>['B']);
    });

    testWidgets('error message: no matching text', (WidgetTester tester) async {
      await tester.pumpWidget(const SizedBox());
      await expectLater(
        () => tester.tapOnText(find.textRange.ofSubstring('nonexistent')),
        throwsA(
          isFlutterError.having(
            (FlutterError error) => error.message,
            'message',
            contains('Found 0 non-overlapping TextRanges that match the Pattern "nonexistent": []'),
          ),
        ),
      );
    });

    testWidgets('error message: too many matches', (WidgetTester tester) async {
      await tester.pumpWidget(
        Directionality(
          textDirection: TextDirection.ltr,
          child: Text.rich(
            TextSpan(
              text: 'match',
              recognizer: tapA,
              children: <InlineSpan>[TextSpan(text: 'another match', recognizer: tapB)],
            ),
          ),
        ),
      );

      await expectLater(
        () => tester.tapOnText(find.textRange.ofSubstring('match')),
        throwsA(
          isFlutterError.having(
            (FlutterError error) => error.message,
            'message',
            stringContainsInOrder(<String>[
              'Found 2 non-overlapping TextRanges that match the Pattern "match"',
              'TextRange(start: 0, end: 5)',
              'TextRange(start: 13, end: 18)',
              'The "tapOnText" method needs a single non-empty TextRange.',
            ]),
          ),
        ),
      );
    });

    testWidgets('error message: not hit-testable', (WidgetTester tester) async {
      await tester.pumpWidget(
        Directionality(
          textDirection: TextDirection.ltr,
          child: Stack(
            fit: StackFit.expand,
            children: <Widget>[
              Text.rich(TextSpan(text: 'match', recognizer: tapA)),
              const MetaData(behavior: HitTestBehavior.opaque),
            ],
          ),
        ),
      );

      await expectLater(
        () => tester.tapOnText(find.textRange.ofSubstring('match')),
        throwsA(
          isFlutterError.having(
            (FlutterError error) => error.message,
            'message',
            stringContainsInOrder(<String>[
              'The finder used was: A finder that searches for non-overlapping TextRanges that match the Pattern "match".',
              'Found a matching substring in a static text widget, within TextRange(start: 0, end: 5).',
              'But the "tapOnText" method could not find a hit-testable Offset with in that text range.',
            ]),
          ),
        ),
      );
    });
  });
}

class _SemanticsTestWidget extends StatelessWidget {
  const _SemanticsTestWidget();

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Semantics Test')),
      body: SingleChildScrollView(
        child: Column(
          children: <Widget>[
            const _SemanticsTestCard(label: 'Text Field', widget: TextField()),
            _SemanticsTestCard(
              label: 'Off Switch',
              widget: Switch(value: false, onChanged: (bool value) {}),
            ),
            _SemanticsTestCard(
              label: 'On Switch',
              widget: Switch(value: true, onChanged: (bool value) {}),
            ),
            const _SemanticsTestCard(
              label: 'Multiline',
              widget: Text("It's a\nmultiline label!", maxLines: 2),
            ),
            _SemanticsTestCard(
              label: 'Slider',
              widget: Slider(value: .5, onChanged: (double value) {}),
            ),
            _SemanticsTestCard(
              label: 'Enabled Button',
              widget: TextButton(onPressed: () {}, child: const Text('Tap')),
            ),
            const _SemanticsTestCard(
              label: 'Disabled Button',
              widget: TextButton(onPressed: null, child: Text("Don't Tap")),
            ),
            _SemanticsTestCard(
              label: 'Checked Radio',
              widget: Radio<String>(
                value: 'checked',
                groupValue: 'checked',
                onChanged: (String? value) {},
              ),
            ),
            _SemanticsTestCard(
              label: 'Unchecked Radio',
              widget: Radio<String>(
                value: 'unchecked',
                groupValue: 'checked',
                onChanged: (String? value) {},
              ),
            ),
          ],
        ),
      ),
    );
  }
}

class _SemanticsTestCard extends StatelessWidget {
  const _SemanticsTestCard({required this.label, required this.widget});

  final String label;
  final Widget widget;

  @override
  Widget build(BuildContext context) {
    return Card(
      child: ListTile(
        title: Text(label),
        trailing: SizedBox(width: 200, child: widget),
      ),
    );
  }
}

class _StatefulSlider extends StatefulWidget {
  const _StatefulSlider({required this.initialValue, required this.onChanged});

  final double initialValue;
  final ValueChanged<double> onChanged;

  @override
  _StatefulSliderState createState() => _StatefulSliderState();
}

class _StatefulSliderState extends State<_StatefulSlider> {
  double _value = 0;

  @override
  void initState() {
    super.initState();
    _value = widget.initialValue;
  }

  @override
  Widget build(BuildContext context) {
    return Slider(
      value: _value,
      onChanged: (double value) {
        setState(() {
          _value = value;
        });
        widget.onChanged(value);
      },
    );
  }
}
