// 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 List<TestDragData> 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 List<Offset> dragOffsets = <Offset>[];

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

    for (int 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 (
        int 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 List<String> 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 String b = '$kSecondaryMouseButton';
    for (int 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 List<String> 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 String b = '$kSecondaryMouseButton';
    expect(logs, equals(<String>['down $b']));
  });

  testWidgets('WidgetTester.longPress must respect buttons', (WidgetTester tester) async {
    final List<String> 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 String b = '$kSecondaryMouseButton';
    for (int 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 List<String> 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 String b = '$kSecondaryMouseButton';
    for (int 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 List<String> 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 (int 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 List<String> 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 String b = '$kSecondaryMouseButton';
    for (int 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 List<Duration> 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 (int 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 List<String> 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 String b = '$kSecondaryMouseButton';
    for (int 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 List<String> 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 Divider(thickness: 5),
                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);
    });
  });

  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 = 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 List<Matcher> fullTraversalMatchers = <Matcher>[
        containsSemantics(isHeader: true, label: 'Semantics Test'),
        containsSemantics(label: 'Text Field'),
        containsSemantics(isTextField: true),
        containsSemantics(label: 'Off Switch'),
        containsSemantics(hasToggledState: true),
        containsSemantics(label: 'On Switch'),
        containsSemantics(hasToggledState: true, isToggled: true),
        containsSemantics(label: "Multiline\nIt's a\nmultiline label!"),
        containsSemantics(label: 'Slider'),
        containsSemantics(isSlider: true, value: '50%'),
        containsSemantics(label: 'Enabled Button'),
        containsSemantics(isButton: true, label: 'Tap'),
        containsSemantics(label: 'Disabled Button'),
        containsSemantics(isButton: true, label: "Don't Tap"),
        containsSemantics(label: 'Checked Radio'),
        containsSemantics(hasCheckedState: true, isChecked: true),
        containsSemantics(label: 'Unchecked Radio'),
        containsSemantics(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 List<Matcher> expectedMatchers = <Matcher>[...fullTraversalMatchers]
          ..removeRange(0, 9);

        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, 10);

        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, 10);

        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>[containsSemantics(label: '1\n2\n3')]),
        );
      });
    });

    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 {
        bool 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 {
        bool 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(),
          containsSemantics(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(),
          containsSemantics(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(),
          containsSemantics(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(),
          containsSemantics(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(),
          containsSemantics(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(),
          containsSemantics(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(),
          containsSemantics(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(),
          containsSemantics(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 {
        bool 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 {
        bool 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(tester.semantics.find(find.byType(Slider)).value, equals(expected));
      });

      testWidgets('showOnScreen sends showOnScreen action', (WidgetTester tester) async {
        await tester.pumpWidget(
          MaterialApp(
            home: ListView(
              controller: ScrollController(initialScrollOffset: 50),
              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'), containsSemantics(isHidden: true));

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

        expect(tester.semantics.find(find.text('Test')), containsSemantics(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 String text = 'This is some text.';
          int currentIndex = text.length;
          final TextEditingController controller = TextEditingController(text: text);
          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 String text = 'This is some text.';
          int currentIndex = text.length;
          final TextEditingController controller = TextEditingController(text: text);
          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 String expectedText = 'This is some text.';
        final TextEditingController controller = TextEditingController();
        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 String text = 'This is some text.';
        const int expectedStart = text.length - 8;
        const int expectedEnd = text.length - 4;
        final TextEditingController controller = TextEditingController(text: text);
        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 {
        bool 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 {
        bool 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 {
        bool 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 {
        bool 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 {
        bool 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 = Duration(seconds: 3);
        final Duration 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
            .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 CustomSemanticsAction customAction = CustomSemanticsAction(label: 'test');
        bool 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 List<String> tapLogs = <String>[];
    final TapGestureRecognizer tapA =
        TapGestureRecognizer()
          ..onTap = () {
            tapLogs.add('A');
          };
    final TapGestureRecognizer tapB =
        TapGestureRecognizer()
          ..onTap = () {
            tapLogs.add('B');
          };
    final TapGestureRecognizer 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);
      },
    );
  }
}
