// 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)
          .whereNotNull();

        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);
    });
  }
}
