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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

      testWidgets('Returns merged SemanticsData', (WidgetTester tester) async {
        const Key key = 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')]),
        );
      });
      testWidgets('a node with only a tooltip is important for accessibility', (
        WidgetTester tester,
      ) async {
        await tester.pumpWidget(
          const MaterialApp(
            home: Tooltip(message: 'My tooltip', child: SizedBox()),
          ),
        );
        expect(
          tester.semantics.simulatedAccessibilityTraversal(),
          contains(containsSemantics(tooltip: 'My tooltip')),
        );
      });
    });

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

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

      testWidgets('tap causes semantic tap', (WidgetTester tester) async {
        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);
      },
    );
  }
}
