// Copyright 2013 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 'dart:async';
import 'dart:typed_data';

import 'package:quiver/testing/async.dart';
import 'package:test/bootstrap/browser.dart';
import 'package:test/test.dart';

import 'package:ui/src/engine.dart';
import 'package:ui/ui.dart' as ui;
import 'package:ui/ui_web/src/ui_web.dart' as ui_web;

import '../../common/rendering.dart';
import '../../common/test_initialization.dart';
import 'semantics_tester.dart';

DateTime _testTime = DateTime(2018, 12, 17);

EngineSemantics semantics() => EngineSemantics.instance;
EngineSemanticsOwner owner() => EnginePlatformDispatcher.instance.implicitView!.semantics;

DomElement get platformViewsHost =>
    EnginePlatformDispatcher.instance.implicitView!.dom.platformViewsHost;

void main() {
  internalBootstrapBrowserTest(() {
    return testMain;
  });
}

Future<void> testMain() async {
  await bootstrapAndRunApp(withImplicitView: true);
  setUpRenderingForTests();
  runSemanticsTests();
}

void runSemanticsTests() {
  setUp(() {
    EngineSemantics.debugResetSemantics();
  });

  group(EngineSemanticsOwner, () {
    _testEngineSemanticsOwner();
  });
  group('longestIncreasingSubsequence', () {
    _testLongestIncreasingSubsequence();
  });
  group('Role managers', () {
    _testRoleManagerLifecycle();
  });
  group('Text', () {
    _testText();
  });
  group('labels', () {
    _testLabels();
  });
  group('container', () {
    _testContainer();
  });
  group('vertical scrolling', () {
    _testVerticalScrolling();
  });
  group('horizontal scrolling', () {
    _testHorizontalScrolling();
  });
  group('incrementable', () {
    _testIncrementables();
  });
  group('text field', () {
    _testTextField();
  });
  group('checkboxes, radio buttons and switches', () {
    _testCheckables();
  });
  group('tappable', () {
    _testTappable();
  });
  group('image', () {
    _testImage();
  });
  group('header', () {
    _testHeader();
  });
  group('live region', () {
    _testLiveRegion();
  });
  group('platform view', () {
    _testPlatformView();
  });
  group('accessibility builder', () {
    _testEngineAccessibilityBuilder();
  });
  group('group', () {
    _testGroup();
  });
  group('dialog', () {
    _testDialog();
  });
  group('focusable', () {
    _testFocusable();
  });
  group('link', () {
    _testLink();
  });
}

void _testRoleManagerLifecycle() {
  test('Secondary role managers are added upon node initialization', () {
    semantics()
      ..debugOverrideTimestampFunction(() => _testTime)
      ..semanticsEnabled = true;

    // Check that roles are initialized immediately
    {
      final SemanticsTester tester = SemanticsTester(owner());
      tester.updateNode(
        id: 0,
        isButton: true,
        rect: const ui.Rect.fromLTRB(0, 0, 100, 50),
      );
      tester.apply();

      tester.expectSemantics('<sem role="button" style="$rootSemanticStyle"></sem>');

      final SemanticsObject node = owner().debugSemanticsTree![0]!;
      expect(node.primaryRole?.role, PrimaryRole.button);
      expect(
        node.primaryRole?.debugSecondaryRoles,
        containsAll(<Role>[Role.focusable, Role.tappable, Role.labelAndValue]),
      );
      expect(tester.getSemanticsObject(0).element.tabIndex, -1);
    }

    // Check that roles apply their functionality upon update.
    {
      final SemanticsTester tester = SemanticsTester(owner());
      tester.updateNode(
        id: 0,
        label: 'a label',
        isFocusable: true,
        isButton: true,
        rect: const ui.Rect.fromLTRB(0, 0, 100, 50),
      );
      tester.apply();

      tester.expectSemantics('<sem role="button" style="$rootSemanticStyle">a label</sem>');

      final SemanticsObject node = owner().debugSemanticsTree![0]!;
      expect(node.primaryRole?.role, PrimaryRole.button);
      expect(
        node.primaryRole?.debugSecondaryRoles,
        containsAll(<Role>[Role.focusable, Role.tappable, Role.labelAndValue]),
      );
      expect(tester.getSemanticsObject(0).element.tabIndex, 0);
    }

    semantics().semanticsEnabled = false;
  });
}

void _testEngineAccessibilityBuilder() {
  final EngineAccessibilityFeaturesBuilder builder =
      EngineAccessibilityFeaturesBuilder(0);
  EngineAccessibilityFeatures features = builder.build();

  test('accessible navigation', () {
    expect(features.accessibleNavigation, isFalse);
    builder.accessibleNavigation = true;
    features = builder.build();
    expect(features.accessibleNavigation, isTrue);
  });

  test('bold text', () {
    expect(features.boldText, isFalse);
    builder.boldText = true;
    features = builder.build();
    expect(features.boldText, isTrue);
  });

  test('disable animations', () {
    expect(features.disableAnimations, isFalse);
    builder.disableAnimations = true;
    features = builder.build();
    expect(features.disableAnimations, isTrue);
  });

  test('high contrast', () {
    expect(features.highContrast, isFalse);
    builder.highContrast = true;
    features = builder.build();
    expect(features.highContrast, isTrue);
  });

  test('invert colors', () {
    expect(features.invertColors, isFalse);
    builder.invertColors = true;
    features = builder.build();
    expect(features.invertColors, isTrue);
  });

  test('on off switch labels', () {
    expect(features.onOffSwitchLabels, isFalse);
    builder.onOffSwitchLabels = true;
    features = builder.build();
    expect(features.onOffSwitchLabels, isTrue);
  });

  test('reduce motion', () {
    expect(features.reduceMotion, isFalse);
    builder.reduceMotion = true;
    features = builder.build();
    expect(features.reduceMotion, isTrue);
  });
}

void _testEngineSemanticsOwner() {
  test('instantiates a singleton', () {
    expect(semantics(), same(semantics()));
  });

  test('semantics is off by default', () {
    expect(semantics().semanticsEnabled, isFalse);
  });

  test('default mode is "unknown"', () {
    expect(semantics().mode, AccessibilityMode.unknown);
  });

  // Expecting the following DOM structure by default:
  //
  // <body>
  //   <flt-announcement-host>
  //     <flt-announcement-polite></flt-announcement-polite>
  //     <flt-announcement-assertive></flt-announcement-assertive>
  //   </flt-announcement-host>
  // </body>
  test('places accessibility announcements in the <body> tag', () {
    final AccessibilityAnnouncements accessibilityAnnouncements = semantics().accessibilityAnnouncements;
    final DomElement politeElement = accessibilityAnnouncements.ariaLiveElementFor(Assertiveness.polite);
    final DomElement assertiveElement = accessibilityAnnouncements.ariaLiveElementFor(Assertiveness.assertive);
    final DomElement announcementHost = politeElement.parent!;

    // Polite and assertive elements share the same host.
    expect(
      assertiveElement.parent,
      announcementHost,
    );

    // The host is a direct child of <body>
    expect(announcementHost.parent, domDocument.body);
  });

  test('accessibilityFeatures copyWith function works', () {
    const EngineAccessibilityFeatures original = EngineAccessibilityFeatures(0);
    EngineAccessibilityFeatures copy =
        original.copyWith(accessibleNavigation: true);
    expect(copy.accessibleNavigation, true);
    expect(copy.boldText, false);
    expect(copy.disableAnimations, false);
    expect(copy.highContrast, false);
    expect(copy.invertColors, false);
    expect(copy.onOffSwitchLabels, false);
    expect(copy.reduceMotion, false);

    copy = original.copyWith(boldText: true);
    expect(copy.accessibleNavigation, false);
    expect(copy.boldText, true);
    expect(copy.disableAnimations, false);
    expect(copy.highContrast, false);
    expect(copy.invertColors, false);
    expect(copy.onOffSwitchLabels, false);
    expect(copy.reduceMotion, false);

    copy = original.copyWith(disableAnimations: true);
    expect(copy.accessibleNavigation, false);
    expect(copy.boldText, false);
    expect(copy.disableAnimations, true);
    expect(copy.highContrast, false);
    expect(copy.invertColors, false);
    expect(copy.onOffSwitchLabels, false);
    expect(copy.reduceMotion, false);

    copy = original.copyWith(highContrast: true);
    expect(copy.accessibleNavigation, false);
    expect(copy.boldText, false);
    expect(copy.disableAnimations, false);
    expect(copy.highContrast, true);
    expect(copy.invertColors, false);
    expect(copy.onOffSwitchLabels, false);
    expect(copy.reduceMotion, false);

    copy = original.copyWith(invertColors: true);
    expect(copy.accessibleNavigation, false);
    expect(copy.boldText, false);
    expect(copy.disableAnimations, false);
    expect(copy.highContrast, false);
    expect(copy.invertColors, true);
    expect(copy.onOffSwitchLabels, false);
    expect(copy.reduceMotion, false);

    copy = original.copyWith(onOffSwitchLabels: true);
    expect(copy.accessibleNavigation, false);
    expect(copy.boldText, false);
    expect(copy.disableAnimations, false);
    expect(copy.highContrast, false);
    expect(copy.invertColors, false);
    expect(copy.onOffSwitchLabels, true);
    expect(copy.reduceMotion, false);

    copy = original.copyWith(reduceMotion: true);
    expect(copy.accessibleNavigation, false);
    expect(copy.boldText, false);
    expect(copy.disableAnimations, false);
    expect(copy.highContrast, false);
    expect(copy.invertColors, false);
    expect(copy.onOffSwitchLabels, false);
    expect(copy.reduceMotion, true);
  });

  void renderSemantics({String? label, String? tooltip, Set<ui.SemanticsFlag> flags = const <ui.SemanticsFlag>{}}) {
    int flagValues = 0;
    for (final ui.SemanticsFlag flag in flags) {
      flagValues = flagValues | flag.index;
    }
    final ui.SemanticsUpdateBuilder builder = ui.SemanticsUpdateBuilder();
    updateNode(
      builder,
      transform: Matrix4.identity().toFloat64(),
      rect: const ui.Rect.fromLTRB(0, 0, 20, 20),
      childrenInHitTestOrder: Int32List.fromList(<int>[1]),
      childrenInTraversalOrder: Int32List.fromList(<int>[1]),
    );
    updateNode(
      builder,
      id: 1,
      label: label ?? '',
      tooltip: tooltip ?? '',
      flags: flagValues,
      transform: Matrix4.identity().toFloat64(),
      rect: const ui.Rect.fromLTRB(0, 0, 20, 20),
    );
    owner().updateSemantics(builder.build());
  }

  void renderLabel(String label) {
    renderSemantics(label: label);
  }

  test('produces a label', () async {
    semantics().semanticsEnabled = true;

    // Create
    renderLabel('Hello');

    final Map<int, SemanticsObject> tree = owner().debugSemanticsTree!;
    expect(tree.length, 2);
    expect(tree[0]!.id, 0);
    expect(tree[0]!.element.tagName.toLowerCase(), 'flt-semantics');
    expect(tree[1]!.id, 1);
    expect(tree[1]!.label, 'Hello');

    expectSemanticsTree(owner(), '''
<sem style="$rootSemanticStyle">
  <sem-c>
    <sem role="text">Hello</sem>
  </sem-c>
</sem>''');

    // Update
    renderLabel('World');

    expectSemanticsTree(owner(), '''
<sem style="$rootSemanticStyle">
  <sem-c>
    <sem role="text">World</sem>
  </sem-c>
</sem>''');

    // Remove
    renderLabel('');

    expectSemanticsTree(owner(), '''
<sem style="$rootSemanticStyle">
  <sem-c>
    <sem role="text"></sem>
  </sem-c>
</sem>''');

    semantics().semanticsEnabled = false;
  });

  test('can switch role', () async {
    semantics().semanticsEnabled = true;

    // Create
    renderSemantics(label: 'Hello');

    Map<int, SemanticsObject> tree = owner().debugSemanticsTree!;
    expect(tree.length, 2);
    expect(tree[1]!.element.tagName.toLowerCase(), 'flt-semantics');
    expect(tree[1]!.id, 1);
    expect(tree[1]!.label, 'Hello');
    final DomElement existingParent = tree[1]!.element.parent!;

    expectSemanticsTree(owner(), '''
<sem style="$rootSemanticStyle">
  <sem-c>
    <sem role="text">Hello</sem>
  </sem-c>
</sem>''');

    // Update
    renderSemantics(label: 'Hello', flags: <ui.SemanticsFlag>{ ui.SemanticsFlag.isLink });

    tree = owner().debugSemanticsTree!;
    expect(tree.length, 2);
    expect(tree[1]!.id, 1);
    expect(tree[1]!.label, 'Hello');
    expect(tree[1]!.element.tagName.toLowerCase(), 'a');
    expectSemanticsTree(owner(), '''
<sem style="$rootSemanticStyle">
  <sem-c>
    <a style="display: block;">Hello</a>
  </sem-c>
</sem>''');
    expect(existingParent, tree[1]!.element.parent);

    semantics().semanticsEnabled = false;
  });

  test('tooltip is part of label', () async {
    semantics().semanticsEnabled = true;

    // Create
    renderSemantics(tooltip: 'tooltip');

    final Map<int, SemanticsObject> tree = owner().debugSemanticsTree!;
    expect(tree.length, 2);
    expect(tree[0]!.id, 0);
    expect(tree[0]!.element.tagName.toLowerCase(), 'flt-semantics');
    expect(tree[1]!.id, 1);
    expect(tree[1]!.tooltip, 'tooltip');

    expectSemanticsTree(owner(), '''
<sem style="$rootSemanticStyle">
  <sem-c>
    <sem>tooltip</sem>
  </sem-c>
</sem>''');

    // Update
    renderSemantics(label: 'Hello', tooltip: 'tooltip');

    expectSemanticsTree(owner(), '''
<sem style="$rootSemanticStyle">
  <sem-c>
    <sem role="text">tooltip\nHello</sem>
  </sem-c>
</sem>''');

    // Remove
    renderSemantics();

    expectSemanticsTree(owner(), '''
<sem style="$rootSemanticStyle">
  <sem-c>
    <sem role="text"></sem>
  </sem-c>
</sem>''');

    semantics().semanticsEnabled = false;
  });

  test('clears semantics tree when disabled', () {
    expect(owner().debugSemanticsTree, isEmpty);
    semantics().semanticsEnabled = true;
    renderLabel('Hello');
    expect(owner().debugSemanticsTree, isNotEmpty);
    semantics().semanticsEnabled = false;
    expect(owner().debugSemanticsTree, isEmpty);
  });

  test('accepts standalone browser gestures', () {
    semantics().semanticsEnabled = true;
    expect(semantics().shouldAcceptBrowserGesture('click'), isTrue);
    semantics().semanticsEnabled = false;
  });

  test('rejects browser gestures accompanied by pointer click', () {
    FakeAsync().run((FakeAsync fakeAsync) {
      semantics()
        ..debugOverrideTimestampFunction(fakeAsync.getClock(_testTime).now)
        ..semanticsEnabled = true;
      expect(semantics().shouldAcceptBrowserGesture('click'), isTrue);
      semantics().receiveGlobalEvent(createDomEvent('Event', 'pointermove'));
      expect(semantics().shouldAcceptBrowserGesture('click'), isFalse);

      // After 1 second of inactivity a browser gestures counts as standalone.
      fakeAsync.elapse(const Duration(seconds: 1));
      expect(semantics().shouldAcceptBrowserGesture('click'), isTrue);
      semantics().semanticsEnabled = false;
    });
  });
  test('checks shouldEnableSemantics for every global event', () {
    final MockSemanticsEnabler mockSemanticsEnabler = MockSemanticsEnabler();
    semantics().semanticsHelper.semanticsEnabler = mockSemanticsEnabler;
    final DomEvent pointerEvent = createDomEvent('Event', 'pointermove');

    semantics().receiveGlobalEvent(pointerEvent);

    // Verify the interactions.
    expect(
      mockSemanticsEnabler.shouldEnableSemanticsEvents,
      <DomEvent>[pointerEvent],
    );
  });

  test('forwards events to framework if shouldEnableSemantics returns true',
      () {
    final MockSemanticsEnabler mockSemanticsEnabler = MockSemanticsEnabler();
    semantics().semanticsHelper.semanticsEnabler = mockSemanticsEnabler;
    final DomEvent pointerEvent = createDomEvent('Event', 'pointermove');
    mockSemanticsEnabler.shouldEnableSemanticsReturnValue = true;
    expect(semantics().receiveGlobalEvent(pointerEvent), isTrue);
  });

  test('semantics owner update phases', () async {
    semantics()
      ..debugOverrideTimestampFunction(() => _testTime)
      ..semanticsEnabled = true;

    expect(
      reason: 'Should start in idle phase',
      owner().phase,
      SemanticsUpdatePhase.idle,
    );

    void pumpSemantics({ required String label }) {
      final SemanticsTester tester = SemanticsTester(owner());
      tester.updateNode(
        id: 0,
        children: <SemanticsNodeUpdate>[
          tester.updateNode(id: 1, label: label),
        ],
      );
      tester.apply();
    }

    SemanticsUpdatePhase? capturedPostUpdateCallbackPhase;
    owner().addOneTimePostUpdateCallback(() {
      capturedPostUpdateCallbackPhase = owner().phase;
    });

    pumpSemantics(label: 'Hello');

    final SemanticsObject semanticsObject = owner().debugSemanticsTree![1]!;

    expect(
      reason: 'Should be in postUpdate phase while calling post-update callbacks',
      capturedPostUpdateCallbackPhase,
      SemanticsUpdatePhase.postUpdate,
    );
    expect(
      reason: 'After the update is done, should go back to idle',
      owner().phase,
      SemanticsUpdatePhase.idle,
    );

    // Rudely replace the role manager with a mock, and trigger an update.
    final MockRoleManager mockRoleManager = MockRoleManager(PrimaryRole.generic, semanticsObject);
    semanticsObject.primaryRole = mockRoleManager;

    pumpSemantics(label: 'World');

    expect(
      reason: 'While updating must be in SemanticsUpdatePhase.updating phase',
      mockRoleManager.log,
      <MockRoleManagerLogEntry>[
        (method: 'update', phase: SemanticsUpdatePhase.updating),
      ],
    );

    semantics().semanticsEnabled = false;
  });
}

typedef MockRoleManagerLogEntry = ({
  String method,
  SemanticsUpdatePhase phase,
});

class MockRoleManager extends PrimaryRoleManager {
  MockRoleManager(super.role, super.semanticsObject) : super.blank();

  final List<MockRoleManagerLogEntry> log = <MockRoleManagerLogEntry>[];

  void _log(String method) {
    log.add((
      method: method,
      phase: semanticsObject.owner.phase,
    ));
  }

  @override
  void update() {
    super.update();
    _log('update');
  }

  @override
  bool focusAsRouteDefault() {
    throw UnimplementedError();
  }
}

class MockSemanticsEnabler implements SemanticsEnabler {
  @override
  void dispose() {}

  @override
  bool get isWaitingToEnableSemantics => throw UnimplementedError();

  @override
  DomElement prepareAccessibilityPlaceholder() {
    throw UnimplementedError();
  }

  bool shouldEnableSemanticsReturnValue = false;
  final List<DomEvent> shouldEnableSemanticsEvents = <DomEvent>[];

  @override
  bool shouldEnableSemantics(DomEvent event) {
    shouldEnableSemanticsEvents.add(event);
    return shouldEnableSemanticsReturnValue;
  }

  @override
  bool tryEnableSemantics(DomEvent event) {
    throw UnimplementedError();
  }
}

void _testHeader() {
  test('renders heading role for headers', () {
    semantics()
      ..debugOverrideTimestampFunction(() => _testTime)
      ..semanticsEnabled = true;

    final ui.SemanticsUpdateBuilder builder = ui.SemanticsUpdateBuilder();
    updateNode(
      builder,
      flags: 0 | ui.SemanticsFlag.isHeader.index,
      label: 'Header of the page',
      transform: Matrix4.identity().toFloat64(),
      rect: const ui.Rect.fromLTRB(0, 0, 100, 50),
    );

    owner().updateSemantics(builder.build());
    expectSemanticsTree(owner(), '''
<sem role="heading" style="$rootSemanticStyle">Header of the page</sem>
''');

    semantics().semanticsEnabled = false;
  });

  // When a header has child elements, role="heading" prevents AT from reaching
  // child elements. To fix that role="group" is used, even though that causes
  // the heading to not be announced as a heading. If the app really needs the
  // heading to be announced as a heading, the developer can restructure the UI
  // such that the heading is not a parent node, but a side-note, e.g. preceding
  // the child list.
  test('uses group role for headers when children are present', () {
    semantics()
      ..debugOverrideTimestampFunction(() => _testTime)
      ..semanticsEnabled = true;

    final ui.SemanticsUpdateBuilder builder = ui.SemanticsUpdateBuilder();
    updateNode(
      builder,
      flags: 0 | ui.SemanticsFlag.isHeader.index,
      label: 'Header of the page',
      transform: Matrix4.identity().toFloat64(),
      rect: const ui.Rect.fromLTRB(0, 0, 100, 50),
      childrenInHitTestOrder: Int32List.fromList(<int>[1]),
      childrenInTraversalOrder: Int32List.fromList(<int>[1]),
    );
    updateNode(
      builder,
      id: 1,
      transform: Matrix4.identity().toFloat64(),
      rect: const ui.Rect.fromLTRB(0, 0, 100, 50),
    );

    owner().updateSemantics(builder.build());
    expectSemanticsTree(owner(), '''
<sem role="group" aria-label="Header of the page" style="$rootSemanticStyle"><sem-c><sem></sem></sem-c></sem>
''');

    semantics().semanticsEnabled = false;
  });
}

void _testLongestIncreasingSubsequence() {
  void expectLis(List<int> list, List<int> seq) {
    expect(longestIncreasingSubsequence(list), seq);
  }

  test('trivial case', () {
    expectLis(<int>[], <int>[]);
  });

  test('longest in the middle', () {
    expectLis(<int>[10, 1, 2, 3, 0], <int>[1, 2, 3]);
  });

  test('longest at head', () {
    expectLis(<int>[1, 2, 3, 0], <int>[0, 1, 2]);
  });

  test('longest at tail', () {
    expectLis(<int>[10, 1, 2, 3], <int>[1, 2, 3]);
  });

  test('longest in a jagged pattern', () {
    expectLis(
        <int>[0, 1, -1, 2, -2, 3, -3, 4, -4, 5, -5], <int>[0, 1, 3, 5, 7, 9]);
  });

  test('fully sorted up', () {
    for (int count = 0; count < 100; count += 1) {
      expectLis(
        List<int>.generate(count, (int i) => 10 * i),
        List<int>.generate(count, (int i) => i),
      );
    }
  });

  test('fully sorted down', () {
    for (int count = 1; count < 100; count += 1) {
      expectLis(
        List<int>.generate(count, (int i) => 10 * (count - i)),
        <int>[count - 1],
      );
    }
  });
}

void _testText() {
  test('renders a piece of plain text', () async {
    semantics()
      ..debugOverrideTimestampFunction(() => _testTime)
      ..semanticsEnabled = true;

    final ui.SemanticsUpdateBuilder builder = ui.SemanticsUpdateBuilder();
    updateNode(
      builder,
      label: 'plain text',
      rect: const ui.Rect.fromLTRB(0, 0, 100, 50),
    );
    owner().updateSemantics(builder.build());

    expectSemanticsTree(
      owner(),
      '''<sem role="text" style="$rootSemanticStyle">plain text</sem>''',
    );

    final SemanticsObject node = owner().debugSemanticsTree![0]!;
    expect(node.primaryRole?.role, PrimaryRole.generic);
    expect(
      node.primaryRole!.secondaryRoleManagers!.map((RoleManager m) => m.runtimeType).toList(),
      <Type>[
        Focusable,
        LiveRegion,
        RouteName,
        LabelAndValue,
      ],
    );
    semantics().semanticsEnabled = false;
  });

  test('renders a tappable piece of text', () async {
    semantics()
      ..debugOverrideTimestampFunction(() => _testTime)
      ..semanticsEnabled = true;

    final SemanticsTester tester = SemanticsTester(owner());
    tester.updateNode(
      id: 0,
      hasTap: true,
      label: 'tappable text',
      rect: const ui.Rect.fromLTRB(0, 0, 100, 50),
    );
    tester.apply();

    expectSemanticsTree(
      owner(),
      '''<sem flt-tappable="" role="text" style="$rootSemanticStyle">tappable text</sem>''',
    );

    final SemanticsObject node = owner().debugSemanticsTree![0]!;
    expect(node.primaryRole?.role, PrimaryRole.generic);
    expect(
      node.primaryRole!.secondaryRoleManagers!.map((RoleManager m) => m.runtimeType).toList(),
      <Type>[
        Focusable,
        LiveRegion,
        RouteName,
        LabelAndValue,
        Tappable,
      ],
    );
    semantics().semanticsEnabled = false;
  });
}

void _testLabels() {
  test('computeDomSemanticsLabel combines tooltip, label, value, and hint', () {
    expect(
      computeDomSemanticsLabel(tooltip: 'tooltip'),
      'tooltip',
    );
    expect(
      computeDomSemanticsLabel(label: 'label'),
      'label',
    );
    expect(
      computeDomSemanticsLabel(value: 'value'),
      'value',
    );
    expect(
      computeDomSemanticsLabel(hint: 'hint'),
      'hint',
    );
    expect(
      computeDomSemanticsLabel(tooltip: 'tooltip', label: 'label', hint: 'hint', value: 'value'),
      '''
tooltip
label hint value'''
    );
    expect(
      computeDomSemanticsLabel(tooltip: 'tooltip', hint: 'hint', value: 'value'),
      '''
tooltip
hint value'''
    );
    expect(
      computeDomSemanticsLabel(tooltip: 'tooltip', label: 'label', value: 'value'),
      '''
tooltip
label value'''
    );
    expect(
      computeDomSemanticsLabel(tooltip: 'tooltip', label: 'label', hint: 'hint'),
      '''
tooltip
label hint'''
    );
  });

  test('computeDomSemanticsLabel collapses empty labels to null', () {
    expect(
      computeDomSemanticsLabel(),
      isNull,
    );
    expect(
      computeDomSemanticsLabel(tooltip: ''),
      isNull,
    );
    expect(
      computeDomSemanticsLabel(label: ''),
      isNull,
    );
    expect(
      computeDomSemanticsLabel(value: ''),
      isNull,
    );
    expect(
      computeDomSemanticsLabel(hint: ''),
      isNull,
    );
    expect(
      computeDomSemanticsLabel(tooltip: '', label: '', hint: '', value: ''),
      isNull,
    );
    expect(
      computeDomSemanticsLabel(tooltip: '', hint: '', value: ''),
      isNull,
    );
    expect(
      computeDomSemanticsLabel(tooltip: '', label: '', value: ''),
      isNull,
    );
    expect(
      computeDomSemanticsLabel(tooltip: '', label: '', hint: ''),
      isNull,
    );
  });
}

void _testContainer() {
  test('container node has no transform when there is no rect offset',
      () async {
    semantics()
      ..debugOverrideTimestampFunction(() => _testTime)
      ..semanticsEnabled = true;

    final ui.SemanticsUpdateBuilder builder = ui.SemanticsUpdateBuilder();
    const ui.Rect zeroOffsetRect = ui.Rect.fromLTRB(0, 0, 20, 20);
    updateNode(
      builder,
      transform: Matrix4.identity().toFloat64(),
      rect: zeroOffsetRect,
      childrenInHitTestOrder: Int32List.fromList(<int>[1]),
      childrenInTraversalOrder: Int32List.fromList(<int>[1]),
    );
    updateNode(
      builder,
      id: 1,
      transform: Matrix4.identity().toFloat64(),
      rect: zeroOffsetRect,
    );

    owner().updateSemantics(builder.build());
    expectSemanticsTree(owner(), '''
<sem style="$rootSemanticStyle">
  <sem-c>
    <sem></sem>
  </sem-c>
</sem>''');

    final DomElement parentElement =
        owner().semanticsHost.querySelector('flt-semantics')!;
    final DomElement container =
        owner().semanticsHost.querySelector('flt-semantics-container')!;

    if (isMacOrIOS) {
      expect(parentElement.style.top, '0px');
      expect(parentElement.style.left, '0px');
      expect(container.style.top, '0px');
      expect(container.style.left, '0px');
    } else {
      expect(parentElement.style.top, '');
      expect(parentElement.style.left, '');
      expect(container.style.top, '');
      expect(container.style.left, '');
    }
    expect(parentElement.style.transform, '');
    expect(parentElement.style.transformOrigin, '');
    expect(container.style.transform, '');
    expect(container.style.transformOrigin, '');
    semantics().semanticsEnabled = false;
  });

  test('container node compensates for rect offset', () async {
    semantics()
      ..debugOverrideTimestampFunction(() => _testTime)
      ..semanticsEnabled = true;

    final ui.SemanticsUpdateBuilder builder = ui.SemanticsUpdateBuilder();
    updateNode(
      builder,
      transform: Matrix4.identity().toFloat64(),
      rect: const ui.Rect.fromLTRB(10, 10, 20, 20),
      childrenInHitTestOrder: Int32List.fromList(<int>[1]),
      childrenInTraversalOrder: Int32List.fromList(<int>[1]),
    );
    updateNode(
      builder,
      id: 1,
      transform: Matrix4.identity().toFloat64(),
      rect: const ui.Rect.fromLTRB(10, 10, 20, 20),
    );

    owner().updateSemantics(builder.build());
    expectSemanticsTree(owner(), '''
<sem style="$rootSemanticStyle">
  <sem-c>
    <sem></sem>
  </sem-c>
</sem>''');

    final DomElement parentElement =
        owner().semanticsHost.querySelector('flt-semantics')!;
    final DomElement container =
        owner().semanticsHost.querySelector('flt-semantics-container')!;

    expect(parentElement.style.transform, 'matrix(1, 0, 0, 1, 10, 10)');
    if (isSafari) {
      // macOS 13 returns different values than macOS 12.
      expect(parentElement.style.transformOrigin, anyOf(contains('0px 0px 0px'), contains('0px 0px')));
    } else {
      expect(parentElement.style.transformOrigin, '0px 0px 0px');
    }
    expect(container.style.top, '-10px');
    expect(container.style.left, '-10px');
    semantics().semanticsEnabled = false;
  });

  test('0 offsets are not removed for voiceover', () async {
    semantics()
      ..debugOverrideTimestampFunction(() => _testTime)
      ..semanticsEnabled = true;

    final ui.SemanticsUpdateBuilder builder = ui.SemanticsUpdateBuilder();
    updateNode(
      builder,
      transform: Matrix4.identity().toFloat64(),
      rect: const ui.Rect.fromLTRB(0, 0, 20, 20),
      childrenInHitTestOrder: Int32List.fromList(<int>[1]),
      childrenInTraversalOrder: Int32List.fromList(<int>[1]),
    );
    updateNode(
      builder,
      id: 1,
      transform: Matrix4.identity().toFloat64(),
      rect: const ui.Rect.fromLTRB(10, 10, 20, 20),
    );

    owner().updateSemantics(builder.build());
    expectSemanticsTree(owner(), '''
<sem style="$rootSemanticStyle">
  <sem-c>
    <sem></sem>
  </sem-c>
</sem>''');

    final DomElement parentElement =
        owner().semanticsHost.querySelector('flt-semantics')!;
    final DomElement container =
        owner().semanticsHost.querySelector('flt-semantics-container')!;

    if (isMacOrIOS) {
      expect(parentElement.style.top, '0px');
      expect(parentElement.style.left, '0px');
      expect(container.style.top, '0px');
      expect(container.style.left, '0px');
    } else {
      expect(parentElement.style.top, '');
      expect(parentElement.style.left, '');
      expect(container.style.top, '');
      expect(container.style.left, '');
    }
    expect(parentElement.style.transform, '');
    expect(parentElement.style.transformOrigin, '');
    expect(container.style.transform, '');
    expect(container.style.transformOrigin, '');

    semantics().semanticsEnabled = false;
  });

  test('renders in traversal order, hit-tests in reverse z-index order',
      () async {
    semantics()
      ..debugOverrideTimestampFunction(() => _testTime)
      ..semanticsEnabled = true;

    // State 1: render initial tree with middle elements swapped hit-test wise
    {
      final ui.SemanticsUpdateBuilder builder = ui.SemanticsUpdateBuilder();
      updateNode(
        builder,
        childrenInTraversalOrder: Int32List.fromList(<int>[1, 2, 3, 4]),
        childrenInHitTestOrder: Int32List.fromList(<int>[1, 3, 2, 4]),
      );

      for (int id = 1; id <= 4; id++) {
        updateNode(builder, id: id);
      }

      owner().updateSemantics(builder.build());
      expectSemanticsTree(owner(), '''
<sem style="$rootSemanticStyle">
  <sem-c>
    <sem style="z-index: 4"></sem>
    <sem style="z-index: 2"></sem>
    <sem style="z-index: 3"></sem>
    <sem style="z-index: 1"></sem>
  </sem-c>
</sem>''');
    }

    // State 2: update z-index
    {
      final ui.SemanticsUpdateBuilder builder = ui.SemanticsUpdateBuilder();
      updateNode(
        builder,
        childrenInTraversalOrder: Int32List.fromList(<int>[1, 2, 3, 4]),
        childrenInHitTestOrder: Int32List.fromList(<int>[1, 2, 3, 4]),
      );
      owner().updateSemantics(builder.build());
      expectSemanticsTree(owner(), '''
<sem style="$rootSemanticStyle">
  <sem-c>
    <sem style="z-index: 4"></sem>
    <sem style="z-index: 3"></sem>
    <sem style="z-index: 2"></sem>
    <sem style="z-index: 1"></sem>
  </sem-c>
</sem>''');
    }

    // State 3: update traversal order
    {
      final ui.SemanticsUpdateBuilder builder = ui.SemanticsUpdateBuilder();
      updateNode(
        builder,
        childrenInTraversalOrder: Int32List.fromList(<int>[4, 2, 3, 1]),
        childrenInHitTestOrder: Int32List.fromList(<int>[1, 2, 3, 4]),
      );
      owner().updateSemantics(builder.build());
      expectSemanticsTree(owner(), '''
<sem style="$rootSemanticStyle">
  <sem-c>
    <sem style="z-index: 1"></sem>
    <sem style="z-index: 3"></sem>
    <sem style="z-index: 2"></sem>
    <sem style="z-index: 4"></sem>
  </sem-c>
</sem>''');
    }

    // State 3: update both orders
    {
      final ui.SemanticsUpdateBuilder builder = ui.SemanticsUpdateBuilder();
      updateNode(
        builder,
        childrenInTraversalOrder: Int32List.fromList(<int>[1, 3, 2, 4]),
        childrenInHitTestOrder: Int32List.fromList(<int>[3, 4, 1, 2]),
      );
      owner().updateSemantics(builder.build());
      expectSemanticsTree(owner(), '''
<sem style="$rootSemanticStyle">
  <sem-c>
    <sem style="z-index: 2"></sem>
    <sem style="z-index: 4"></sem>
    <sem style="z-index: 1"></sem>
    <sem style="z-index: 3"></sem>
  </sem-c>
</sem>''');
    }

    semantics().semanticsEnabled = false;
  });

  test(
      'container nodes are transparent and leaf children are opaque hit-test wise',
      () async {
    semantics()
      ..debugOverrideTimestampFunction(() => _testTime)
      ..semanticsEnabled = true;

    final ui.SemanticsUpdateBuilder builder = ui.SemanticsUpdateBuilder();
    updateNode(
      builder,
      childrenInTraversalOrder: Int32List.fromList(<int>[1, 2]),
      childrenInHitTestOrder: Int32List.fromList(<int>[1, 2]),
    );
    updateNode(builder, id: 1);
    updateNode(builder, id: 2);

    owner().updateSemantics(builder.build());
    expectSemanticsTree(owner(), '''
<sem style="$rootSemanticStyle">
  <sem-c>
    <sem style="z-index: 2"></sem>
    <sem style="z-index: 1"></sem>
  </sem-c>
</sem>''');

    final DomElement root = owner().semanticsHost.querySelector('#flt-semantic-node-0')!;
    expect(root.style.pointerEvents, 'none');

    final DomElement child1 =
        owner().semanticsHost.querySelector('#flt-semantic-node-1')!;
    expect(child1.style.pointerEvents, 'all');

    final DomElement child2 =
        owner().semanticsHost.querySelector('#flt-semantic-node-2')!;
    expect(child2.style.pointerEvents, 'all');

    semantics().semanticsEnabled = false;
  });

  test('descendant nodes are removed from the node map, unless reparented', () async {
    semantics()
      ..debugOverrideTimestampFunction(() => _testTime)
      ..semanticsEnabled = true;

    {
      final ui.SemanticsUpdateBuilder builder = ui.SemanticsUpdateBuilder();
      updateNode(
        builder,
        childrenInTraversalOrder: Int32List.fromList(<int>[1, 2]),
        childrenInHitTestOrder: Int32List.fromList(<int>[1, 2]),
      );
      updateNode(
        builder,
        id: 1,
        childrenInTraversalOrder: Int32List.fromList(<int>[3, 4]),
        childrenInHitTestOrder: Int32List.fromList(<int>[3, 4]),
      );
      updateNode(
        builder,
        id: 2,
        childrenInTraversalOrder: Int32List.fromList(<int>[5, 6]),
        childrenInHitTestOrder: Int32List.fromList(<int>[5, 6]),
      );
      updateNode(builder, id: 3);
      updateNode(builder, id: 4);
      updateNode(builder, id: 5);
      updateNode(builder, id: 6);

      owner().updateSemantics(builder.build());
      expectSemanticsTree(owner(), '''
  <sem style="$rootSemanticStyle">
    <sem-c>
      <sem style="z-index: 2">
        <sem-c>
          <sem style="z-index: 2"></sem>
          <sem style="z-index: 1"></sem>
        </sem-c>
      </sem>
      <sem style="z-index: 1">
        <sem-c>
          <sem style="z-index: 2"></sem>
          <sem style="z-index: 1"></sem>
        </sem-c>
      </sem>
    </sem-c>
  </sem>''');

      expect(owner().debugSemanticsTree!.keys.toList(), unorderedEquals(<int>[0, 1, 2, 3, 4, 5, 6]));
    }

    // Remove node #2 => expect nodes #2 and #5 to be removed and #6 reparented.
    {
      final ui.SemanticsUpdateBuilder builder = ui.SemanticsUpdateBuilder();
      updateNode(
        builder,
        childrenInTraversalOrder: Int32List.fromList(<int>[1]),
        childrenInHitTestOrder: Int32List.fromList(<int>[1]),
      );
      updateNode(
        builder,
        id: 1,
        childrenInTraversalOrder: Int32List.fromList(<int>[3, 4, 6]),
        childrenInHitTestOrder: Int32List.fromList(<int>[3, 4, 6]),
      );

      owner().updateSemantics(builder.build());
      expectSemanticsTree(owner(), '''
  <sem style="$rootSemanticStyle">
    <sem-c>
      <sem style="z-index: 2">
        <sem-c>
          <sem style="z-index: 3"></sem>
          <sem style="z-index: 2"></sem>
          <sem style="z-index: 1"></sem>
        </sem-c>
      </sem>
    </sem-c>
  </sem>''');

      expect(owner().debugSemanticsTree!.keys.toList(), unorderedEquals(<int>[0, 1, 3, 4, 6]));
    }

    semantics().semanticsEnabled = false;
  });
}

void _testVerticalScrolling() {
  test('renders an empty scrollable node', () async {
    semantics()
      ..debugOverrideTimestampFunction(() => _testTime)
      ..semanticsEnabled = true;

    final ui.SemanticsUpdateBuilder builder = ui.SemanticsUpdateBuilder();
    updateNode(
      builder,
      actions: 0 | ui.SemanticsAction.scrollUp.index,
      transform: Matrix4.identity().toFloat64(),
      rect: const ui.Rect.fromLTRB(0, 0, 50, 100),
    );

    owner().updateSemantics(builder.build());
    expectSemanticsTree(owner(), '''
<sem style="$rootSemanticStyle; touch-action: none; overflow-y: scroll">
<flt-semantics-scroll-overflow></flt-semantics-scroll-overflow>
</sem>''');

    final DomElement scrollable = findScrollable(owner());
    expect(scrollable.scrollTop, isPositive);
    semantics().semanticsEnabled = false;
  });

  test('scrollable node with children has a container node', () async {
    semantics()
      ..debugOverrideTimestampFunction(() => _testTime)
      ..semanticsEnabled = true;

    final ui.SemanticsUpdateBuilder builder = ui.SemanticsUpdateBuilder();
    updateNode(
      builder,
      actions: 0 | ui.SemanticsAction.scrollUp.index,
      transform: Matrix4.identity().toFloat64(),
      rect: const ui.Rect.fromLTRB(0, 0, 50, 100),
      childrenInHitTestOrder: Int32List.fromList(<int>[1]),
      childrenInTraversalOrder: Int32List.fromList(<int>[1]),
    );
    updateNode(
      builder,
      id: 1,
      transform: Matrix4.identity().toFloat64(),
      rect: const ui.Rect.fromLTRB(10, 10, 20, 20),
    );

    owner().updateSemantics(builder.build());
    expectSemanticsTree(owner(), '''
<sem style="$rootSemanticStyle; touch-action: none; overflow-y: scroll">
<flt-semantics-scroll-overflow></flt-semantics-scroll-overflow>
  <sem-c>
    <sem></sem>
  </sem-c>
</sem>''');

    final DomElement scrollable = findScrollable(owner());
    expect(scrollable, isNotNull);

    // When there's less content than the available size the neutral scrollTop
    // is still a positive number.
    expect(scrollable.scrollTop, isPositive);

    semantics().semanticsEnabled = false;
  });

  test('scrollable node dispatches scroll events', () async {
    Future<ui.SemanticsActionEvent> captureSemanticsEvent() {
      final Completer<ui.SemanticsActionEvent> completer = Completer<ui.SemanticsActionEvent>();
      ui.PlatformDispatcher.instance.onSemanticsActionEvent = (ui.SemanticsActionEvent event) {
        completer.complete(event);
      };
      return completer.future;
    }

    semantics()
      ..debugOverrideTimestampFunction(() => _testTime)
      ..semanticsEnabled = true;

    addTearDown(() async {
      semantics().semanticsEnabled = false;
    });

    final ui.SemanticsUpdateBuilder builder = ui.SemanticsUpdateBuilder();
    updateNode(
      builder,
      actions: 0 |
          ui.SemanticsAction.scrollUp.index |
          ui.SemanticsAction.scrollDown.index,
      transform: Matrix4.identity().toFloat64(),
      rect: const ui.Rect.fromLTRB(0, 0, 50, 100),
      childrenInHitTestOrder: Int32List.fromList(<int>[1, 2, 3]),
      childrenInTraversalOrder: Int32List.fromList(<int>[1, 2, 3]),
    );

    for (int id = 1; id <= 3; id++) {
      updateNode(
        builder,
        id: id,
        transform: Matrix4.translationValues(0, 50.0 * id, 0).toFloat64(),
        rect: const ui.Rect.fromLTRB(0, 0, 50, 50),
      );
    }

    owner().updateSemantics(builder.build());
    expectSemanticsTree(owner(), '''
<sem style="$rootSemanticStyle; touch-action: none; overflow-y: scroll">
  <flt-semantics-scroll-overflow></flt-semantics-scroll-overflow>
  <sem-c>
    <sem style="z-index: 3"></sem>
    <sem style="z-index: 2"></sem>
    <sem style="z-index: 1"></sem>
  </sem-c>
</sem>''');

    final DomElement scrollable = owner().debugSemanticsTree![0]!.element;
    expect(scrollable, isNotNull);

    // When there's more content than the available size the neutral scrollTop
    // is greater than 0 with a maximum of 10 or 9.
    int browserMaxScrollDiff = 0;
    // The max scroll value varies between `9` and `10` for Safari desktop
    // browsers.
    if (browserEngine == BrowserEngine.webkit &&
        operatingSystem == OperatingSystem.macOs) {
      browserMaxScrollDiff = 1;
    }

    expect(scrollable.scrollTop >= (10 - browserMaxScrollDiff), isTrue);

    Future<ui.SemanticsActionEvent> capturedEventFuture = captureSemanticsEvent();
    scrollable.scrollTop = 20;
    expect(scrollable.scrollTop, 20);
    ui.SemanticsActionEvent capturedEvent = await capturedEventFuture;

    expect(capturedEvent.nodeId, 0);
    expect(capturedEvent.type, ui.SemanticsAction.scrollUp);
    expect(capturedEvent.arguments, isNull);
    // Engine semantics returns scroll top back to neutral.
    expect(scrollable.scrollTop >= (10 - browserMaxScrollDiff), isTrue);

    capturedEventFuture = captureSemanticsEvent();
    scrollable.scrollTop = 5;
    capturedEvent = await capturedEventFuture;

    expect(scrollable.scrollTop >= (5 - browserMaxScrollDiff), isTrue);
    expect(capturedEvent.nodeId, 0);
    expect(capturedEvent.type, ui.SemanticsAction.scrollDown);
    expect(capturedEvent.arguments, isNull);
    // Engine semantics returns scroll top back to neutral.
    expect(scrollable.scrollTop >= (10 - browserMaxScrollDiff), isTrue);
  });
}

void _testHorizontalScrolling() {
  test('renders an empty scrollable node', () async {
    semantics()
      ..debugOverrideTimestampFunction(() => _testTime)
      ..semanticsEnabled = true;

    final ui.SemanticsUpdateBuilder builder = ui.SemanticsUpdateBuilder();
    updateNode(
      builder,
      actions: 0 | ui.SemanticsAction.scrollLeft.index,
      transform: Matrix4.identity().toFloat64(),
      rect: const ui.Rect.fromLTRB(0, 0, 100, 50),
    );

    owner().updateSemantics(builder.build());
    expectSemanticsTree(owner(), '''
<sem style="$rootSemanticStyle; touch-action: none; overflow-x: scroll">
<flt-semantics-scroll-overflow></flt-semantics-scroll-overflow>
</sem>''');

    semantics().semanticsEnabled = false;
  });

  test('scrollable node with children has a container node', () async {
    semantics()
      ..debugOverrideTimestampFunction(() => _testTime)
      ..semanticsEnabled = true;

    final ui.SemanticsUpdateBuilder builder = ui.SemanticsUpdateBuilder();
    updateNode(
      builder,
      actions: 0 | ui.SemanticsAction.scrollLeft.index,
      transform: Matrix4.identity().toFloat64(),
      rect: const ui.Rect.fromLTRB(0, 0, 100, 50),
      childrenInHitTestOrder: Int32List.fromList(<int>[1]),
      childrenInTraversalOrder: Int32List.fromList(<int>[1]),
    );
    updateNode(
      builder,
      id: 1,
      transform: Matrix4.identity().toFloat64(),
      rect: const ui.Rect.fromLTRB(10, 10, 20, 20),
    );

    owner().updateSemantics(builder.build());
    expectSemanticsTree(owner(), '''
<sem style="$rootSemanticStyle; touch-action: none; overflow-x: scroll">
<flt-semantics-scroll-overflow></flt-semantics-scroll-overflow>
  <sem-c>
    <sem></sem>
  </sem-c>
</sem>''');

    final DomElement scrollable = findScrollable(owner());
    expect(scrollable, isNotNull);

    // When there's less content than the available size the neutral
    // scrollLeft is still a positive number.
    expect(scrollable.scrollLeft, isPositive);

    semantics().semanticsEnabled = false;
  });

  test('scrollable node dispatches scroll events', () async {
    Future<ui.SemanticsActionEvent> captureSemanticsEvent() {
      final Completer<ui.SemanticsActionEvent> completer = Completer<ui.SemanticsActionEvent>();
      ui.PlatformDispatcher.instance.onSemanticsActionEvent = (ui.SemanticsActionEvent event) {
        completer.complete(event);
      };
      return completer.future;
    }

    semantics()
      ..debugOverrideTimestampFunction(() => _testTime)
      ..semanticsEnabled = true;

    addTearDown(() async {
      semantics().semanticsEnabled = false;
    });

    final ui.SemanticsUpdateBuilder builder = ui.SemanticsUpdateBuilder();
    updateNode(
      builder,
      actions: 0 |
          ui.SemanticsAction.scrollLeft.index |
          ui.SemanticsAction.scrollRight.index,
      transform: Matrix4.identity().toFloat64(),
      rect: const ui.Rect.fromLTRB(0, 0, 100, 50),
      childrenInHitTestOrder: Int32List.fromList(<int>[1, 2, 3]),
      childrenInTraversalOrder: Int32List.fromList(<int>[1, 2, 3]),
    );

    for (int id = 1; id <= 3; id++) {
      updateNode(
        builder,
        id: id,
        transform: Matrix4.translationValues(50.0 * id, 0, 0).toFloat64(),
        rect: const ui.Rect.fromLTRB(0, 0, 50, 50),
      );
    }

    owner().updateSemantics(builder.build());
    expectSemanticsTree(owner(), '''
<sem style="$rootSemanticStyle; touch-action: none; overflow-x: scroll">
  <flt-semantics-scroll-overflow></flt-semantics-scroll-overflow>
  <sem-c>
    <sem style="z-index: 3"></sem>
    <sem style="z-index: 2"></sem>
    <sem style="z-index: 1"></sem>
  </sem-c>
</sem>''');

    final DomElement scrollable = findScrollable(owner());
    expect(scrollable, isNotNull);

    // When there's more content than the available size the neutral scrollTop
    // is greater than 0 with a maximum of 10.
    int browserMaxScrollDiff = 0;
    // The max scroll value varies between `9` and `10` for Safari desktop
    // browsers.
    if (browserEngine == BrowserEngine.webkit &&
        operatingSystem == OperatingSystem.macOs) {
      browserMaxScrollDiff = 1;
    }
    expect(scrollable.scrollLeft >= (10 - browserMaxScrollDiff), isTrue);

    Future<ui.SemanticsActionEvent> capturedEventFuture = captureSemanticsEvent();
    scrollable.scrollLeft = 20;
    expect(scrollable.scrollLeft, 20);
    ui.SemanticsActionEvent capturedEvent = await capturedEventFuture;

    expect(capturedEvent.nodeId, 0);
    expect(capturedEvent.type, ui.SemanticsAction.scrollLeft);
    expect(capturedEvent.arguments, isNull);
    // Engine semantics returns scroll position back to neutral.
    expect(scrollable.scrollLeft >= (10 - browserMaxScrollDiff), isTrue);

    capturedEventFuture = captureSemanticsEvent();
    scrollable.scrollLeft = 5;
    capturedEvent = await capturedEventFuture;

    expect(scrollable.scrollLeft >= (5 - browserMaxScrollDiff), isTrue);
    expect(capturedEvent.nodeId, 0);
    expect(capturedEvent.type, ui.SemanticsAction.scrollRight);
    expect(capturedEvent.arguments, isNull);
    // Engine semantics returns scroll top back to neutral.
    expect(scrollable.scrollLeft >= (10 - browserMaxScrollDiff), isTrue);
  });
}

void _testIncrementables() {
  test('renders a trivial incrementable node', () async {
    semantics()
      ..debugOverrideTimestampFunction(() => _testTime)
      ..semanticsEnabled = true;

    final ui.SemanticsUpdateBuilder builder = ui.SemanticsUpdateBuilder();
    updateNode(
      builder,
      actions: 0 | ui.SemanticsAction.increase.index,
      value: 'd',
      transform: Matrix4.identity().toFloat64(),
      rect: const ui.Rect.fromLTRB(0, 0, 100, 50),
    );

    owner().updateSemantics(builder.build());
    expectSemanticsTree(owner(), '''
<sem style="$rootSemanticStyle">
  <input role="slider" aria-valuenow="1" aria-valuetext="d" aria-valuemax="1" aria-valuemin="1">
</sem>''');

    final SemanticsObject node = owner().debugSemanticsTree![0]!;
    expect(node.primaryRole?.role, PrimaryRole.incrementable);
    expect(
      reason: 'Incrementables use custom focus management',
      node.primaryRole!.debugSecondaryRoles,
      isNot(contains(Role.focusable)),
    );

    semantics().semanticsEnabled = false;
  });

  test('increments', () async {
    final SemanticsActionLogger logger = SemanticsActionLogger();
    semantics()
      ..debugOverrideTimestampFunction(() => _testTime)
      ..semanticsEnabled = true;

    final ui.SemanticsUpdateBuilder builder = ui.SemanticsUpdateBuilder();
    updateNode(
      builder,
      actions: 0 | ui.SemanticsAction.increase.index,
      value: 'd',
      increasedValue: 'e',
      transform: Matrix4.identity().toFloat64(),
      rect: const ui.Rect.fromLTRB(0, 0, 100, 50),
    );

    owner().updateSemantics(builder.build());
    expectSemanticsTree(owner(), '''
<sem style="$rootSemanticStyle">
  <input role="slider" aria-valuenow="1" aria-valuetext="d" aria-valuemax="2" aria-valuemin="1">
</sem>''');

    final DomHTMLInputElement input =
        owner().semanticsHost.querySelector('input')! as DomHTMLInputElement;
    input.value = '2';
    input.dispatchEvent(createDomEvent('Event', 'change'));

    expect(await logger.idLog.first, 0);
    expect(await logger.actionLog.first, ui.SemanticsAction.increase);

    semantics().semanticsEnabled = false;
  });

  test('decrements', () async {
    final SemanticsActionLogger logger = SemanticsActionLogger();
    semantics()
      ..debugOverrideTimestampFunction(() => _testTime)
      ..semanticsEnabled = true;

    final ui.SemanticsUpdateBuilder builder = ui.SemanticsUpdateBuilder();
    updateNode(
      builder,
      actions: 0 | ui.SemanticsAction.decrease.index,
      value: 'd',
      decreasedValue: 'c',
      transform: Matrix4.identity().toFloat64(),
      rect: const ui.Rect.fromLTRB(0, 0, 100, 50),
    );

    owner().updateSemantics(builder.build());
    expectSemanticsTree(owner(), '''
<sem style="$rootSemanticStyle">
  <input role="slider" aria-valuenow="1" aria-valuetext="d" aria-valuemax="1" aria-valuemin="0">
</sem>''');

    final DomHTMLInputElement input =
        owner().semanticsHost.querySelector('input')! as DomHTMLInputElement;
    input.value = '0';
    input.dispatchEvent(createDomEvent('Event', 'change'));

    expect(await logger.idLog.first, 0);
    expect(await logger.actionLog.first, ui.SemanticsAction.decrease);

    semantics().semanticsEnabled = false;
  });

  test('renders a node that can both increment and decrement', () async {
    semantics()
      ..debugOverrideTimestampFunction(() => _testTime)
      ..semanticsEnabled = true;

    final ui.SemanticsUpdateBuilder builder = ui.SemanticsUpdateBuilder();
    updateNode(
      builder,
      actions: 0 |
          ui.SemanticsAction.decrease.index |
          ui.SemanticsAction.increase.index,
      value: 'd',
      increasedValue: 'e',
      decreasedValue: 'c',
      transform: Matrix4.identity().toFloat64(),
      rect: const ui.Rect.fromLTRB(0, 0, 100, 50),
    );

    owner().updateSemantics(builder.build());
    expectSemanticsTree(owner(), '''
<sem style="$rootSemanticStyle">
  <input role="slider" aria-valuenow="1" aria-valuetext="d" aria-valuemax="2" aria-valuemin="0">
</sem>''');

    semantics().semanticsEnabled = false;
  });

  test('sends focus events', () async {
    semantics()
      ..debugOverrideTimestampFunction(() => _testTime)
      ..semanticsEnabled = true;

    void pumpSemantics({ required bool isFocused }) {
      final SemanticsTester tester = SemanticsTester(owner());
      tester.updateNode(
        id: 0,
        hasIncrease: true,
        isFocusable: true,
        isFocused: isFocused,
        hasEnabledState: true,
        isEnabled: true,
        value: 'd',
        transform: Matrix4.identity().toFloat64(),
        rect: const ui.Rect.fromLTRB(0, 0, 100, 50),
      );
      tester.apply();
    }

    final List<CapturedAction> capturedActions = <CapturedAction>[];
    EnginePlatformDispatcher.instance.onSemanticsActionEvent = (ui.SemanticsActionEvent event) {
      capturedActions.add((event.nodeId, event.type, event.arguments));
    };

    pumpSemantics(isFocused: false);
    final DomElement element = owner().debugSemanticsTree![0]!.element.querySelector('input')!;
    expect(capturedActions, isEmpty);

    pumpSemantics(isFocused: true);
    expect(capturedActions, <CapturedAction>[
      (0, ui.SemanticsAction.didGainAccessibilityFocus, null),
    ]);
    capturedActions.clear();

    pumpSemantics(isFocused: false);
    expect(
      reason: 'The engine never calls blur() explicitly.',
      capturedActions,
      isEmpty,
    );

    element.blur();
    expect(capturedActions, <CapturedAction>[
      (0, ui.SemanticsAction.didLoseAccessibilityFocus, null),
    ]);

    semantics().semanticsEnabled = false;
  });
}

void _testTextField() {
  test('renders a text field', () async {
    semantics()
      ..debugOverrideTimestampFunction(() => _testTime)
      ..semanticsEnabled = true;

    final ui.SemanticsUpdateBuilder builder = ui.SemanticsUpdateBuilder();
    updateNode(
      builder,
      actions: 0 | ui.SemanticsAction.tap.index,
      flags: 0 | ui.SemanticsFlag.isTextField.index,
      value: 'hello',
      transform: Matrix4.identity().toFloat64(),
      rect: const ui.Rect.fromLTRB(0, 0, 100, 50),
    );

    owner().updateSemantics(builder.build());
    expectSemanticsTree(owner(), '''
<sem style="$rootSemanticStyle">
  <input value="hello" />
</sem>''');

    final SemanticsObject node = owner().debugSemanticsTree![0]!;
    expect(node.primaryRole?.role, PrimaryRole.textField);
    expect(
      reason: 'Text fields use custom focus management',
      node.primaryRole!.debugSecondaryRoles,
      isNot(contains(Role.focusable)),
    );

    semantics().semanticsEnabled = false;
  });

  // TODO(yjbanov): this test will need to be adjusted for Safari when we add
  //                Safari testing.
  test('sends a focus action when text field is activated', () async {
    final SemanticsActionLogger logger = SemanticsActionLogger();
    semantics()
      ..debugOverrideTimestampFunction(() => _testTime)
      ..semanticsEnabled = true;

    final ui.SemanticsUpdateBuilder builder = ui.SemanticsUpdateBuilder();
    updateNode(
      builder,
      actions: 0 | ui.SemanticsAction.didGainAccessibilityFocus.index,
      flags: 0 | ui.SemanticsFlag.isTextField.index,
      value: 'hello',
      transform: Matrix4.identity().toFloat64(),
      rect: const ui.Rect.fromLTRB(0, 0, 100, 50),
    );

    owner().updateSemantics(builder.build());

    final DomElement textField =
        owner().semanticsHost.querySelector('input[data-semantics-role="text-field"]')!;

    expect(owner().semanticsHost.ownerDocument?.activeElement, isNot(textField));

    textField.focus();

    expect(owner().semanticsHost.ownerDocument?.activeElement, textField);
    expect(await logger.idLog.first, 0);
    expect(await logger.actionLog.first, ui.SemanticsAction.didGainAccessibilityFocus);

    semantics().semanticsEnabled = false;
  }, // TODO(yjbanov): https://github.com/flutter/flutter/issues/46638
      // TODO(yjbanov): https://github.com/flutter/flutter/issues/50590
      skip: browserEngine != BrowserEngine.blink);
}

void _testCheckables() {
  test('renders a switched on switch element', () async {
    semantics()
      ..debugOverrideTimestampFunction(() => _testTime)
      ..semanticsEnabled = true;

    final ui.SemanticsUpdateBuilder builder = ui.SemanticsUpdateBuilder();
    updateNode(
      builder,
      actions: 0 | ui.SemanticsAction.tap.index,
      label: 'test label',
      flags: 0 |
          ui.SemanticsFlag.isEnabled.index |
          ui.SemanticsFlag.hasEnabledState.index |
          ui.SemanticsFlag.hasToggledState.index |
          ui.SemanticsFlag.isToggled.index |
          ui.SemanticsFlag.isFocusable.index,
      transform: Matrix4.identity().toFloat64(),
      rect: const ui.Rect.fromLTRB(0, 0, 100, 50),
    );

    owner().updateSemantics(builder.build());
    expectSemanticsTree(owner(), '''
<sem aria-label="test label" flt-tappable role="switch" aria-checked="true" style="$rootSemanticStyle"></sem>
''');

    final SemanticsObject node = owner().debugSemanticsTree![0]!;
    expect(node.primaryRole?.role, PrimaryRole.checkable);
    expect(
      reason: 'Checkables use generic secondary roles',
      node.primaryRole!.debugSecondaryRoles,
      containsAll(<Role>[Role.focusable, Role.tappable]),
    );

    semantics().semanticsEnabled = false;
  });

  test('renders a switched on disabled switch element', () async {
    semantics()
      ..debugOverrideTimestampFunction(() => _testTime)
      ..semanticsEnabled = true;

    final ui.SemanticsUpdateBuilder builder = ui.SemanticsUpdateBuilder();
    updateNode(
      builder,
      actions: 0 | ui.SemanticsAction.tap.index,
      flags: 0 |
          ui.SemanticsFlag.hasToggledState.index |
          ui.SemanticsFlag.isToggled.index |
          ui.SemanticsFlag.hasEnabledState.index,
      transform: Matrix4.identity().toFloat64(),
      rect: const ui.Rect.fromLTRB(0, 0, 100, 50),
    );

    owner().updateSemantics(builder.build());
    expectSemanticsTree(owner(), '''
<sem role="switch" aria-disabled="true" aria-checked="true" style="$rootSemanticStyle"></sem>
''');

    semantics().semanticsEnabled = false;
  });

  test('renders a switched off switch element', () async {
    semantics()
      ..debugOverrideTimestampFunction(() => _testTime)
      ..semanticsEnabled = true;

    final ui.SemanticsUpdateBuilder builder = ui.SemanticsUpdateBuilder();
    updateNode(
      builder,
      actions: 0 | ui.SemanticsAction.tap.index,
      flags: 0 |
          ui.SemanticsFlag.hasToggledState.index |
          ui.SemanticsFlag.isEnabled.index |
          ui.SemanticsFlag.hasEnabledState.index,
      transform: Matrix4.identity().toFloat64(),
      rect: const ui.Rect.fromLTRB(0, 0, 100, 50),
    );

    owner().updateSemantics(builder.build());
    expectSemanticsTree(owner(), '''
<sem role="switch" flt-tappable aria-checked="false" style="$rootSemanticStyle"></sem>
''');

    semantics().semanticsEnabled = false;
  });

  test('renders a checked checkbox', () async {
    semantics()
      ..debugOverrideTimestampFunction(() => _testTime)
      ..semanticsEnabled = true;

    final ui.SemanticsUpdateBuilder builder = ui.SemanticsUpdateBuilder();
    updateNode(
      builder,
      actions: 0 | ui.SemanticsAction.tap.index,
      flags: 0 |
          ui.SemanticsFlag.isEnabled.index |
          ui.SemanticsFlag.hasEnabledState.index |
          ui.SemanticsFlag.hasCheckedState.index |
          ui.SemanticsFlag.isChecked.index,
      transform: Matrix4.identity().toFloat64(),
      rect: const ui.Rect.fromLTRB(0, 0, 100, 50),
    );

    owner().updateSemantics(builder.build());
    expectSemanticsTree(owner(), '''
<sem role="checkbox" flt-tappable aria-checked="true" style="$rootSemanticStyle"></sem>
''');

    semantics().semanticsEnabled = false;
  });

  test('renders a checked disabled checkbox', () async {
    semantics()
      ..debugOverrideTimestampFunction(() => _testTime)
      ..semanticsEnabled = true;

    final ui.SemanticsUpdateBuilder builder = ui.SemanticsUpdateBuilder();
    updateNode(
      builder,
      actions: 0 | ui.SemanticsAction.tap.index,
      flags: 0 |
          ui.SemanticsFlag.hasCheckedState.index |
          ui.SemanticsFlag.hasEnabledState.index |
          ui.SemanticsFlag.isChecked.index,
      transform: Matrix4.identity().toFloat64(),
      rect: const ui.Rect.fromLTRB(0, 0, 100, 50),
    );

    owner().updateSemantics(builder.build());
    expectSemanticsTree(owner(), '''
<sem role="checkbox" aria-disabled="true" aria-checked="true" style="$rootSemanticStyle"></sem>
''');

    semantics().semanticsEnabled = false;
  });

  test('renders an unchecked checkbox', () async {
    semantics()
      ..debugOverrideTimestampFunction(() => _testTime)
      ..semanticsEnabled = true;

    final ui.SemanticsUpdateBuilder builder = ui.SemanticsUpdateBuilder();
    updateNode(
      builder,
      actions: 0 | ui.SemanticsAction.tap.index,
      flags: 0 |
          ui.SemanticsFlag.hasCheckedState.index |
          ui.SemanticsFlag.isEnabled.index |
          ui.SemanticsFlag.hasEnabledState.index,
      transform: Matrix4.identity().toFloat64(),
      rect: const ui.Rect.fromLTRB(0, 0, 100, 50),
    );

    owner().updateSemantics(builder.build());
    expectSemanticsTree(owner(), '''
<sem role="checkbox" flt-tappable aria-checked="false" style="$rootSemanticStyle"></sem>
''');

    semantics().semanticsEnabled = false;
  });

  test('renders a checked radio button', () async {
    semantics()
      ..debugOverrideTimestampFunction(() => _testTime)
      ..semanticsEnabled = true;

    final ui.SemanticsUpdateBuilder builder = ui.SemanticsUpdateBuilder();
    updateNode(
      builder,
      actions: 0 | ui.SemanticsAction.tap.index,
      flags: 0 |
          ui.SemanticsFlag.isEnabled.index |
          ui.SemanticsFlag.hasEnabledState.index |
          ui.SemanticsFlag.hasCheckedState.index |
          ui.SemanticsFlag.isInMutuallyExclusiveGroup.index |
          ui.SemanticsFlag.isChecked.index,
      transform: Matrix4.identity().toFloat64(),
      rect: const ui.Rect.fromLTRB(0, 0, 100, 50),
    );

    owner().updateSemantics(builder.build());
    expectSemanticsTree(owner(), '''
<sem role="radio" flt-tappable aria-checked="true" style="$rootSemanticStyle"></sem>
''');

    semantics().semanticsEnabled = false;
  });

  test('renders a checked disabled radio button', () async {
    semantics()
      ..debugOverrideTimestampFunction(() => _testTime)
      ..semanticsEnabled = true;

    final ui.SemanticsUpdateBuilder builder = ui.SemanticsUpdateBuilder();
    updateNode(
      builder,
      actions: 0 | ui.SemanticsAction.tap.index,
      flags: 0 |
          ui.SemanticsFlag.hasEnabledState.index |
          ui.SemanticsFlag.hasCheckedState.index |
          ui.SemanticsFlag.isInMutuallyExclusiveGroup.index |
          ui.SemanticsFlag.isChecked.index,
      transform: Matrix4.identity().toFloat64(),
      rect: const ui.Rect.fromLTRB(0, 0, 100, 50),
    );

    owner().updateSemantics(builder.build());
    expectSemanticsTree(owner(), '''
<sem role="radio" aria-disabled="true" aria-checked="true" style="$rootSemanticStyle"></sem>
''');

    semantics().semanticsEnabled = false;
  });

  test('renders an unchecked checkbox', () async {
    semantics()
      ..debugOverrideTimestampFunction(() => _testTime)
      ..semanticsEnabled = true;

    final ui.SemanticsUpdateBuilder builder = ui.SemanticsUpdateBuilder();
    updateNode(
      builder,
      actions: 0 | ui.SemanticsAction.tap.index,
      flags: 0 |
          ui.SemanticsFlag.isEnabled.index |
          ui.SemanticsFlag.hasEnabledState.index |
          ui.SemanticsFlag.hasCheckedState.index |
          ui.SemanticsFlag.isInMutuallyExclusiveGroup.index,
      transform: Matrix4.identity().toFloat64(),
      rect: const ui.Rect.fromLTRB(0, 0, 100, 50),
    );

    owner().updateSemantics(builder.build());
    expectSemanticsTree(owner(), '''
<sem role="radio" flt-tappable aria-checked="false" style="$rootSemanticStyle"></sem>
''');

    semantics().semanticsEnabled = false;
  });

  test('sends focus events', () async {
    semantics()
      ..debugOverrideTimestampFunction(() => _testTime)
      ..semanticsEnabled = true;

    void pumpSemantics({ required bool isFocused }) {
      final SemanticsTester tester = SemanticsTester(owner());
      tester.updateNode(
        id: 0,

        // The following combination of actions and flags describe a checkbox.
        hasTap: true,
        hasEnabledState: true,
        isEnabled: true,
        hasCheckedState: true,
        isFocusable: true,
        isFocused: isFocused,

        value: 'd',
        transform: Matrix4.identity().toFloat64(),
        rect: const ui.Rect.fromLTRB(0, 0, 100, 50),
      );
      tester.apply();
    }

    final List<CapturedAction> capturedActions = <CapturedAction>[];
    EnginePlatformDispatcher.instance.onSemanticsActionEvent = (ui.SemanticsActionEvent event) {
      capturedActions.add((event.nodeId, event.type, event.arguments));
    };

    pumpSemantics(isFocused: false);
    final DomElement element = owner().debugSemanticsTree![0]!.element;
    expect(capturedActions, isEmpty);

    pumpSemantics(isFocused: true);
    expect(capturedActions, <CapturedAction>[
      (0, ui.SemanticsAction.didGainAccessibilityFocus, null),
    ]);
    capturedActions.clear();

    // The framework removes focus from the widget (i.e. "blurs" it). Since the
    // blurring is initiated by the framework, there's no need to send any
    // notifications back to the framework about it.
    pumpSemantics(isFocused: false);
    expect(capturedActions, isEmpty);

    // If the element is blurred by the browser, then we do want to notify the
    // framework. This is because screen reader can be focused on something
    // other than what the framework is focused on, and notifying the framework
    // about the loss of focus on a node is information that the framework did
    // not have before.
    element.blur();
    expect(capturedActions, <CapturedAction>[
      (0, ui.SemanticsAction.didLoseAccessibilityFocus, null),
    ]);

    semantics().semanticsEnabled = false;
  });
}

void _testTappable() {
  test('renders an enabled tappable widget', () async {
    semantics()
      ..debugOverrideTimestampFunction(() => _testTime)
      ..semanticsEnabled = true;

    final SemanticsTester tester = SemanticsTester(owner());
    tester.updateNode(
      id: 0,
      isFocusable: true,
      hasTap: true,
      hasEnabledState: true,
      isEnabled: true,
      isButton: true,
      rect: const ui.Rect.fromLTRB(0, 0, 100, 50),
    );
    tester.apply();

    expectSemanticsTree(owner(), '''
<sem role="button" flt-tappable style="$rootSemanticStyle"></sem>
''');

    final SemanticsObject node = owner().debugSemanticsTree![0]!;
    expect(node.primaryRole?.role, PrimaryRole.button);
    expect(
      node.primaryRole?.debugSecondaryRoles,
      containsAll(<Role>[Role.focusable, Role.tappable]),
    );
    expect(tester.getSemanticsObject(0).element.tabIndex, 0);

    semantics().semanticsEnabled = false;
  });

  test('renders a disabled tappable widget', () async {
    semantics()
      ..debugOverrideTimestampFunction(() => _testTime)
      ..semanticsEnabled = true;

    final ui.SemanticsUpdateBuilder builder = ui.SemanticsUpdateBuilder();
    updateNode(
      builder,
      actions: 0 | ui.SemanticsAction.tap.index,
      flags: 0 |
          ui.SemanticsFlag.hasEnabledState.index |
          ui.SemanticsFlag.isButton.index,
      transform: Matrix4.identity().toFloat64(),
      rect: const ui.Rect.fromLTRB(0, 0, 100, 50),
    );

    owner().updateSemantics(builder.build());
    expectSemanticsTree(owner(), '''
<sem role="button" aria-disabled="true" style="$rootSemanticStyle"></sem>
''');

    semantics().semanticsEnabled = false;
  });

  test('can switch tappable between enabled and disabled', () async {
    semantics()
      ..debugOverrideTimestampFunction(() => _testTime)
      ..semanticsEnabled = true;

    void updateTappable({required bool enabled}) {
      final SemanticsTester tester = SemanticsTester(owner());
      tester.updateNode(
        id: 0,
        hasTap: true,
        hasEnabledState: true,
        isEnabled: enabled,
        isButton: true,
        rect: const ui.Rect.fromLTRB(0, 0, 100, 50),
      );
      tester.apply();
    }

    updateTappable(enabled: false);
    expectSemanticsTree(
      owner(),
      '<sem role="button" aria-disabled="true" style="$rootSemanticStyle"></sem>'
    );

    updateTappable(enabled: true);
    expectSemanticsTree(
      owner(),
      '<sem role="button" flt-tappable style="$rootSemanticStyle"></sem>',
    );

    updateTappable(enabled: false);
    expectSemanticsTree(
      owner(),
      '<sem role="button" aria-disabled="true" style="$rootSemanticStyle"></sem>',
    );

    updateTappable(enabled: true);
    expectSemanticsTree(
      owner(),
      '<sem role="button" flt-tappable style="$rootSemanticStyle"></sem>',
    );

    semantics().semanticsEnabled = false;
  });

  test('focuses on tappable after element has been attached', () async {
    semantics()
      ..debugOverrideTimestampFunction(() => _testTime)
      ..semanticsEnabled = true;

    final SemanticsTester tester = SemanticsTester(owner());
    tester.updateNode(
      id: 0,
      hasTap: true,
      hasEnabledState: true,
      isEnabled: true,
      isButton: true,
      isFocusable: true,
      isFocused: true,
      rect: const ui.Rect.fromLTRB(0, 0, 100, 50),
    );
    tester.apply();

    expect(domDocument.activeElement, tester.getSemanticsObject(0).element);
    semantics().semanticsEnabled = false;
  });

  test('sends focus events', () async {
    semantics()
      ..debugOverrideTimestampFunction(() => _testTime)
      ..semanticsEnabled = true;

    void pumpSemantics({ required bool isFocused }) {
      final SemanticsTester tester = SemanticsTester(owner());
      tester.updateNode(
        id: 0,

        // The following combination of actions and flags describe a button.
        hasTap: true,
        hasEnabledState: true,
        isEnabled: true,
        isButton: true,
        isFocusable: true,
        isFocused: isFocused,

        value: 'd',
        transform: Matrix4.identity().toFloat64(),
        rect: const ui.Rect.fromLTRB(0, 0, 100, 50),
      );
      tester.apply();
    }

    final List<CapturedAction> capturedActions = <CapturedAction>[];
    EnginePlatformDispatcher.instance.onSemanticsActionEvent = (ui.SemanticsActionEvent event) {
      capturedActions.add((event.nodeId, event.type, event.arguments));
    };

    pumpSemantics(isFocused: false);
    final DomElement element = owner().debugSemanticsTree![0]!.element;
    expect(capturedActions, isEmpty);

    pumpSemantics(isFocused: true);
    expect(capturedActions, <CapturedAction>[
      (0, ui.SemanticsAction.didGainAccessibilityFocus, null),
    ]);
    capturedActions.clear();

    pumpSemantics(isFocused: false);
    expect(capturedActions, isEmpty);

    element.blur();
    expect(capturedActions, <CapturedAction>[
      (0, ui.SemanticsAction.didLoseAccessibilityFocus, null),
    ]);

    semantics().semanticsEnabled = false;
  });

  // Regression test for: https://github.com/flutter/flutter/issues/134842
  //
  // If the click event is allowed to propagate through the hierarchy, then both
  // the descendant and the parent will generate a SemanticsAction.tap, causing
  // a double-tap to happen on the framework side.
  test('inner tappable overrides ancestor tappable', () async {
    semantics()
      ..debugOverrideTimestampFunction(() => _testTime)
      ..semanticsEnabled = true;

    final List<CapturedAction> capturedActions = <CapturedAction>[];
    EnginePlatformDispatcher.instance.onSemanticsActionEvent = (ui.SemanticsActionEvent event) {
      capturedActions.add((event.nodeId, event.type, event.arguments));
    };

    final SemanticsTester tester = SemanticsTester(owner());
    tester.updateNode(
      id: 0,
      isFocusable: true,
      hasTap: true,
      hasEnabledState: true,
      isEnabled: true,
      isButton: true,
      rect: const ui.Rect.fromLTRB(0, 0, 100, 50),
      children: <SemanticsNodeUpdate>[
        tester.updateNode(
          id: 1,
          isFocusable: true,
          hasTap: true,
          hasEnabledState: true,
          isEnabled: true,
          isButton: true,
          rect: const ui.Rect.fromLTRB(0, 0, 100, 50),
        ),
      ],
    );
    tester.apply();

    expectSemanticsTree(owner(), '''
<sem flt-tappable role="button" style="$rootSemanticStyle">
  <sem-c>
    <sem flt-tappable role="button"></sem>
  </sem-c>
</sem>
''');

    // Tap on the outer element
    {
      final DomElement element = tester.getSemanticsObject(0).element;
      final DomRect rect = element.getBoundingClientRect();

      element.dispatchEvent(createDomMouseEvent('click', <Object?, Object?>{
        'clientX': (rect.left + (rect.right - rect.left) / 2).floor(),
        'clientY': (rect.top + (rect.bottom - rect.top) / 2).floor(),
      }));

      expect(capturedActions, <CapturedAction>[
        (0, ui.SemanticsAction.tap, null),
      ]);
    }

    // Tap on the inner element
    {
      capturedActions.clear();
      final DomElement element = tester.getSemanticsObject(1).element;
      final DomRect rect = element.getBoundingClientRect();

      element.dispatchEvent(createDomMouseEvent('click', <Object?, Object?>{
        'bubbles': true,
        'clientX': (rect.left + (rect.right - rect.left) / 2).floor(),
        'clientY': (rect.top + (rect.bottom - rect.top) / 2).floor(),
      }));

      // The click on the inner element should not propagate to the parent to
      // avoid sending a second SemanticsAction.tap action to the framework.
      expect(capturedActions, <CapturedAction>[
        (1, ui.SemanticsAction.tap, null),
      ]);
    }

    semantics().semanticsEnabled = false;
  });
}

void _testImage() {
  test('renders an image with no child nodes and with a label', () async {
    semantics()
      ..debugOverrideTimestampFunction(() => _testTime)
      ..semanticsEnabled = true;

    final ui.SemanticsUpdateBuilder builder = ui.SemanticsUpdateBuilder();
    updateNode(
      builder,
      flags: 0 | ui.SemanticsFlag.isImage.index,
      label: 'Test Image Label',
      transform: Matrix4.identity().toFloat64(),
      rect: const ui.Rect.fromLTRB(0, 0, 100, 50),
    );

    owner().updateSemantics(builder.build());
    expectSemanticsTree(owner(), '''
<sem role="img" aria-label="Test Image Label" style="$rootSemanticStyle"></sem>
''');

    semantics().semanticsEnabled = false;
  });

  test('renders an image with a child node and with a label', () async {
    semantics()
      ..debugOverrideTimestampFunction(() => _testTime)
      ..semanticsEnabled = true;

    final ui.SemanticsUpdateBuilder builder = ui.SemanticsUpdateBuilder();
    updateNode(
      builder,
      flags: 0 | ui.SemanticsFlag.isImage.index,
      label: 'Test Image Label',
      transform: Matrix4.identity().toFloat64(),
      rect: const ui.Rect.fromLTRB(0, 0, 100, 50),
      childrenInHitTestOrder: Int32List.fromList(<int>[1]),
      childrenInTraversalOrder: Int32List.fromList(<int>[1]),
    );
    updateNode(
      builder,
      id: 1,
      transform: Matrix4.identity().toFloat64(),
      rect: const ui.Rect.fromLTRB(10, 10, 20, 20),
    );

    owner().updateSemantics(builder.build());
    expectSemanticsTree(owner(), '''
<sem style="$rootSemanticStyle">
  <sem-img role="img" aria-label="Test Image Label">
  </sem-img>
  <sem-c>
    <sem></sem>
  </sem-c>
</sem>''');

    semantics().semanticsEnabled = false;
  });

  test('renders an image with no child nodes without a label', () async {
    semantics()
      ..debugOverrideTimestampFunction(() => _testTime)
      ..semanticsEnabled = true;

    final ui.SemanticsUpdateBuilder builder = ui.SemanticsUpdateBuilder();
    updateNode(
      builder,
      flags: 0 | ui.SemanticsFlag.isImage.index,
      transform: Matrix4.identity().toFloat64(),
      rect: const ui.Rect.fromLTRB(0, 0, 100, 50),
    );

    owner().updateSemantics(builder.build());
    expectSemanticsTree(
      owner(),
      '<sem role="img" style="$rootSemanticStyle"></sem>',
    );

    semantics().semanticsEnabled = false;
  });

  test('renders an image with a child node and without a label', () async {
    semantics()
      ..debugOverrideTimestampFunction(() => _testTime)
      ..semanticsEnabled = true;

    final ui.SemanticsUpdateBuilder builder = ui.SemanticsUpdateBuilder();
    updateNode(
      builder,
      flags: 0 | ui.SemanticsFlag.isImage.index,
      transform: Matrix4.identity().toFloat64(),
      rect: const ui.Rect.fromLTRB(0, 0, 100, 50),
      childrenInHitTestOrder: Int32List.fromList(<int>[1]),
      childrenInTraversalOrder: Int32List.fromList(<int>[1]),
    );
    updateNode(
      builder,
      id: 1,
      transform: Matrix4.identity().toFloat64(),
      rect: const ui.Rect.fromLTRB(10, 10, 20, 20),
    );

    owner().updateSemantics(builder.build());
    expectSemanticsTree(owner(), '''
<sem style="$rootSemanticStyle">
  <sem-img role="img">
  </sem-img>
  <sem-c>
    <sem></sem>
  </sem-c>
</sem>''');

    semantics().semanticsEnabled = false;
  });
}

class MockAccessibilityAnnouncements implements AccessibilityAnnouncements {
  int announceInvoked = 0;

  @override
  void announce(String message, Assertiveness assertiveness) {
    announceInvoked += 1;
  }

  @override
  DomHTMLElement ariaLiveElementFor(Assertiveness assertiveness) {
    throw UnsupportedError(
        'ariaLiveElementFor is not supported in MockAccessibilityAnnouncements');
  }

  @override
  void handleMessage(StandardMessageCodec codec, ByteData? data) {
    throw UnsupportedError(
        'handleMessage is not supported in MockAccessibilityAnnouncements!');
  }
}

void _testLiveRegion() {
  tearDown(() {
    LiveRegion.debugOverrideAccessibilityAnnouncements(null);
  });

  test('announces the label after an update', () async {
    semantics()
      ..debugOverrideTimestampFunction(() => _testTime)
      ..semanticsEnabled = true;

    final MockAccessibilityAnnouncements mockAccessibilityAnnouncements =
        MockAccessibilityAnnouncements();
    LiveRegion.debugOverrideAccessibilityAnnouncements(mockAccessibilityAnnouncements);

    final ui.SemanticsUpdateBuilder builder = ui.SemanticsUpdateBuilder();
    updateNode(
      builder,
      label: 'This is a snackbar',
      flags: 0 | ui.SemanticsFlag.isLiveRegion.index,
      transform: Matrix4.identity().toFloat64(),
      rect: const ui.Rect.fromLTRB(0, 0, 100, 50),
    );
    owner().updateSemantics(builder.build());
    expect(mockAccessibilityAnnouncements.announceInvoked, 1);

    semantics().semanticsEnabled = false;
  });

  test('does not announce anything if there is no label', () async {
    semantics()
      ..debugOverrideTimestampFunction(() => _testTime)
      ..semanticsEnabled = true;

    final MockAccessibilityAnnouncements mockAccessibilityAnnouncements =
        MockAccessibilityAnnouncements();
    LiveRegion.debugOverrideAccessibilityAnnouncements(mockAccessibilityAnnouncements);

    final ui.SemanticsUpdateBuilder builder = ui.SemanticsUpdateBuilder();
    updateNode(
      builder,
      flags: 0 | ui.SemanticsFlag.isLiveRegion.index,
      transform: Matrix4.identity().toFloat64(),
      rect: const ui.Rect.fromLTRB(0, 0, 100, 50),
    );
    owner().updateSemantics(builder.build());
    expect(mockAccessibilityAnnouncements.announceInvoked, 0);

    semantics().semanticsEnabled = false;
  });

  test('does not announce the same label over and over', () async {
    semantics()
      ..debugOverrideTimestampFunction(() => _testTime)
      ..semanticsEnabled = true;

    final MockAccessibilityAnnouncements mockAccessibilityAnnouncements =
        MockAccessibilityAnnouncements();
    LiveRegion.debugOverrideAccessibilityAnnouncements(mockAccessibilityAnnouncements);

    ui.SemanticsUpdateBuilder builder = ui.SemanticsUpdateBuilder();
    updateNode(
      builder,
      label: 'This is a snackbar',
      flags: 0 | ui.SemanticsFlag.isLiveRegion.index,
      transform: Matrix4.identity().toFloat64(),
      rect: const ui.Rect.fromLTRB(0, 0, 100, 50),
    );
    owner().updateSemantics(builder.build());
    expect(mockAccessibilityAnnouncements.announceInvoked, 1);

    builder = ui.SemanticsUpdateBuilder();
    updateNode(
      builder,
      label: 'This is a snackbar',
      flags: 0 | ui.SemanticsFlag.isLiveRegion.index,
      transform: Matrix4.identity().toFloat64(),
      rect: const ui.Rect.fromLTRB(0, 0, 100, 50),
    );
    owner().updateSemantics(builder.build());
    expect(mockAccessibilityAnnouncements.announceInvoked, 1);

    semantics().semanticsEnabled = false;
  });
}

void _testPlatformView() {
  test('sets and updates aria-owns', () async {
    semantics()
      ..debugOverrideTimestampFunction(() => _testTime)
      ..semanticsEnabled = true;

    // Set.
    {
      final ui.SemanticsUpdateBuilder builder = ui.SemanticsUpdateBuilder();
      updateNode(
        builder,
        platformViewId: 5,
        rect: const ui.Rect.fromLTRB(0, 0, 100, 50),
      );
      owner().updateSemantics(builder.build());
      expectSemanticsTree(
        owner(),
        '<sem aria-owns="flt-pv-5" style="$rootSemanticStyle"></sem>',
      );
    }

    // Update.
    {
      final ui.SemanticsUpdateBuilder builder = ui.SemanticsUpdateBuilder();
      updateNode(
        builder,
        platformViewId: 42,
        rect: const ui.Rect.fromLTRB(0, 0, 100, 50),
      );
      owner().updateSemantics(builder.build());
      expectSemanticsTree(
        owner(),
        '<sem aria-owns="flt-pv-42" style="$rootSemanticStyle"></sem>',
      );
    }

    semantics().semanticsEnabled = false;
  });

  test('is transparent w.r.t. hit testing', () async {
    semantics()
      ..debugOverrideTimestampFunction(() => _testTime)
      ..semanticsEnabled = true;

    final ui.SemanticsUpdateBuilder builder = ui.SemanticsUpdateBuilder();
    updateNode(
      builder,
      platformViewId: 5,
      rect: const ui.Rect.fromLTRB(0, 0, 100, 50),
    );
    owner().updateSemantics(builder.build());

    expectSemanticsTree(
      owner(),
      '<sem aria-owns="flt-pv-5" style="$rootSemanticStyle"></sem>',
    );
    final DomElement element = owner().semanticsHost.querySelector('flt-semantics')!;
    expect(element.style.pointerEvents, 'none');

    semantics().semanticsEnabled = false;
  });

  // This test simulates the scenario of three child semantic nodes contained by
  // a common parent. The first and the last nodes are plain leaf nodes. The
  // middle node is a platform view node. Nodes overlap. The test hit tests
  // various points and verifies that the correct DOM element receives the
  // event. The test does this using `documentOrShadow.elementFromPoint`, which,
  // if browsers are to be trusted, should do the same thing as if a pointer
  // event landed at the given location.
  //
  // 0px   -------------
  //       |           |
  //       |           | <- plain semantic node
  //       |     1     |
  // 15px  | -------------
  //       | |           |
  // 25px  --|           |
  //         |     2     |  <- platform view
  //         |           |
  // 35px    | -------------
  //         | |           |
  // 45px    --|           |
  //           |     3     |  <- plain semantic node
  //           |           |
  //           |           |
  // 60px      -------------
  test('is reachable via a hit test', () async {
    semantics()
      ..debugOverrideTimestampFunction(() => _testTime)
      ..semanticsEnabled = true;

    ui_web.platformViewRegistry.registerViewFactory(
      'test-platform-view',
      (int viewId) => createDomHTMLDivElement()
        ..id = 'view-0'
        ..style.width = '100%'
        ..style.height = '100%',
    );
    await createPlatformView(0, 'test-platform-view');

    final ui.SceneBuilder sceneBuilder = ui.SceneBuilder();
    sceneBuilder.addPlatformView(
      0,
      offset: const ui.Offset(0, 15),
      width: 20,
      height: 30,
    );
    await renderScene(sceneBuilder.build());

    final ui.SemanticsUpdateBuilder builder = ui.SemanticsUpdateBuilder();
    final double dpr = EngineFlutterDisplay.instance.devicePixelRatio;
    updateNode(builder,
        rect: const ui.Rect.fromLTRB(0, 0, 20, 60),
        childrenInTraversalOrder: Int32List.fromList(<int>[1, 2, 3]),
        childrenInHitTestOrder: Int32List.fromList(<int>[1, 2, 3]),
        transform: Float64List.fromList(Matrix4.diagonal3Values(dpr, dpr, 1).storage));
    updateNode(
      builder,
      id: 1,
      rect: const ui.Rect.fromLTRB(0, 0, 20, 25),
    );
    updateNode(
      builder,
      id: 2,
      // This has to match the values passed to `addPlatformView` above.
      rect: const ui.Rect.fromLTRB(0, 15, 20, 45),
      platformViewId: 0,
    );
    updateNode(
      builder,
      id: 3,
      rect: const ui.Rect.fromLTRB(0, 35, 20, 60),
    );

    owner().updateSemantics(builder.build());
    expectSemanticsTree(owner(), '''
<sem style="$rootSemanticStyle">
  <sem-c>
    <sem style="z-index: 3"></sem>
    <sem style="z-index: 2" aria-owns="flt-pv-0"></sem>
    <sem style="z-index: 1"></sem>
  </sem-c>
</sem>''');

    final DomElement root = owner().semanticsHost.querySelector('#flt-semantic-node-0')!;
    expect(root.style.pointerEvents, 'none');

    final DomElement child1 =
        owner().semanticsHost.querySelector('#flt-semantic-node-1')!;
    expect(child1.style.pointerEvents, 'all');
    final DomRect child1Rect = child1.getBoundingClientRect();
    expect(child1Rect.left, 0);
    expect(child1Rect.top, 0);
    expect(child1Rect.right, 20);
    expect(child1Rect.bottom, 25);

    final DomElement child2 =
        owner().semanticsHost.querySelector('#flt-semantic-node-2')!;
    expect(child2.style.pointerEvents, 'none');
    final DomRect child2Rect = child2.getBoundingClientRect();
    expect(child2Rect.left, 0);
    expect(child2Rect.top, 15);
    expect(child2Rect.right, 20);
    expect(child2Rect.bottom, 45);

    final DomElement child3 =
        owner().semanticsHost.querySelector('#flt-semantic-node-3')!;
    expect(child3.style.pointerEvents, 'all');
    final DomRect child3Rect = child3.getBoundingClientRect();
    expect(child3Rect.left, 0);
    expect(child3Rect.top, 35);
    expect(child3Rect.right, 20);
    expect(child3Rect.bottom, 60);

    final DomElement platformViewElement =
        platformViewsHost.querySelector('#view-0')!;
    final DomRect platformViewRect =
        platformViewElement.getBoundingClientRect();
    expect(platformViewRect.left, 0);
    expect(platformViewRect.top, 15);
    expect(platformViewRect.right, 20);
    expect(platformViewRect.bottom, 45);

    // Hit test child 1
    expect(domDocument.elementFromPoint(10, 10), child1);

    // Hit test overlap between child 1 and 2
    // TODO(yjbanov): this is a known limitation, see https://github.com/flutter/flutter/issues/101439
    expect(domDocument.elementFromPoint(10, 20), child1);

    // Hit test child 2
    // Clicking at the location of the middle semantics node should allow the
    // event to go through the semantic tree and hit the platform view. Since
    // platform views are projected into the shadow DOM from outside the shadow
    // root, it would be reachable both from the shadow root (by hitting the
    // corresponding <slot> tag) and from the document (by hitting the platform
    // view element itself).

    // Browsers disagree about which element should be returned when hit testing
    // a shadow root. However, they do agree when hit testing `document`.
    //
    // See:
    //   * https://github.com/w3c/csswg-drafts/issues/556
    //   * https://bugzilla.mozilla.org/show_bug.cgi?id=1502369
    expect(domDocument.elementFromPoint(10, 30), platformViewElement);

    // Hit test overlap between child 2 and 3
    expect(domDocument.elementFromPoint(10, 40), child3);

    // Hit test child 3
    expect(domDocument.elementFromPoint(10, 50), child3);

    semantics().semanticsEnabled = false;
  });
}

void _testGroup() {
  test('nodes with children and labels use group role with aria label', () {
    semantics()
      ..debugOverrideTimestampFunction(() => _testTime)
      ..semanticsEnabled = true;

    final ui.SemanticsUpdateBuilder builder = ui.SemanticsUpdateBuilder();
    updateNode(
      builder,
      label: 'this is a label for a group of elements',
      transform: Matrix4.identity().toFloat64(),
      rect: const ui.Rect.fromLTRB(0, 0, 100, 50),
      childrenInHitTestOrder: Int32List.fromList(<int>[1]),
      childrenInTraversalOrder: Int32List.fromList(<int>[1]),
    );
    updateNode(
      builder,
      id: 1,
      transform: Matrix4.identity().toFloat64(),
      rect: const ui.Rect.fromLTRB(0, 0, 100, 50),
    );

    owner().updateSemantics(builder.build());
    expectSemanticsTree(owner(), '''
<sem role="group" aria-label="this is a label for a group of elements" style="$rootSemanticStyle"><sem-c><sem></sem></sem-c></sem>
''');

    semantics().semanticsEnabled = false;
  });
}

void _testDialog() {
  test('renders named and labeled routes', () {
    semantics()
      ..debugOverrideTimestampFunction(() => _testTime)
      ..semanticsEnabled = true;

    final ui.SemanticsUpdateBuilder builder = ui.SemanticsUpdateBuilder();
    updateNode(
      builder,
      label: 'this is a dialog label',
      flags: 0 | ui.SemanticsFlag.scopesRoute.index | ui.SemanticsFlag.namesRoute.index,
      transform: Matrix4.identity().toFloat64(),
      rect: const ui.Rect.fromLTRB(0, 0, 100, 50),
      childrenInHitTestOrder: Int32List.fromList(<int>[1]),
      childrenInTraversalOrder: Int32List.fromList(<int>[1]),
    );
    updateNode(
      builder,
      id: 1,
      transform: Matrix4.identity().toFloat64(),
      rect: const ui.Rect.fromLTRB(0, 0, 100, 50),
    );

    owner().updateSemantics(builder.build());
    expectSemanticsTree(owner(), '''
      <sem role="dialog" aria-label="this is a dialog label" style="$rootSemanticStyle"><sem-c><sem></sem></sem-c></sem>
    ''');

    expect(
      owner().debugSemanticsTree![0]!.primaryRole?.role,
      PrimaryRole.dialog,
    );

    semantics().semanticsEnabled = false;
  });

  test('warns about missing label', () {
    final List<String> warnings = <String>[];
    printWarning = warnings.add;

    semantics()
      ..debugOverrideTimestampFunction(() => _testTime)
      ..semanticsEnabled = true;

    final ui.SemanticsUpdateBuilder builder = ui.SemanticsUpdateBuilder();
    updateNode(
      builder,
      flags: 0 | ui.SemanticsFlag.scopesRoute.index | ui.SemanticsFlag.namesRoute.index,
      transform: Matrix4.identity().toFloat64(),
      rect: const ui.Rect.fromLTRB(0, 0, 100, 50),
      childrenInHitTestOrder: Int32List.fromList(<int>[1]),
      childrenInTraversalOrder: Int32List.fromList(<int>[1]),
    );
    updateNode(
      builder,
      id: 1,
      transform: Matrix4.identity().toFloat64(),
      rect: const ui.Rect.fromLTRB(0, 0, 100, 50),
    );

    owner().updateSemantics(builder.build());
    expect(
      warnings,
      <String>[
        'Semantic node 0 had both scopesRoute and namesRoute set, indicating a self-labelled dialog, but it is missing the label. A dialog should be labelled either by setting namesRoute on itself and providing a label, or by containing a child node with namesRoute that can describe it with its content.',
      ],
    );

    // But still sets the dialog role.
    expectSemanticsTree(owner(), '''
      <sem role="dialog" aria-label="" style="$rootSemanticStyle"><sem-c><sem></sem></sem-c></sem>
    ''');

    expect(
      owner().debugSemanticsTree![0]!.primaryRole?.role,
      PrimaryRole.dialog,
    );

    semantics().semanticsEnabled = false;
  });

  test('dialog can be described by a descendant', () {
    semantics()
      ..debugOverrideTimestampFunction(() => _testTime)
      ..semanticsEnabled = true;

    void pumpSemantics({ required String label }) {
      final SemanticsTester tester = SemanticsTester(owner());
      tester.updateNode(
        id: 0,
        scopesRoute: true,
        transform: Matrix4.identity().toFloat64(),
        children: <SemanticsNodeUpdate>[
          tester.updateNode(
            id: 1,
            children: <SemanticsNodeUpdate>[
              tester.updateNode(
                id: 2,
                namesRoute: true,
                label: label,
              ),
            ],
          ),
        ],
      );
      tester.apply();

      expectSemanticsTree(owner(), '''
        <sem role="dialog" aria-describedby="flt-semantic-node-2" style="$rootSemanticStyle">
          <sem-c>
            <sem>
              <sem-c>
                <sem role="text">$label</sem>
              </sem-c>
            </sem>
          </sem-c>
        </sem>
      ''');
    }

    pumpSemantics(label: 'Dialog label');

    expect(
      owner().debugSemanticsTree![0]!.primaryRole?.role,
      PrimaryRole.dialog,
    );
    expect(
      owner().debugSemanticsTree![2]!.primaryRole?.role,
      PrimaryRole.generic,
    );
    expect(
      owner().debugSemanticsTree![2]!.primaryRole?.debugSecondaryRoles,
      contains(Role.routeName),
    );

    pumpSemantics(label: 'Updated dialog label');

    semantics().semanticsEnabled = false;
  });

  test('scopesRoute alone sets the dialog role with no label', () {
    final List<String> warnings = <String>[];
    printWarning = warnings.add;

    semantics()
      ..debugOverrideTimestampFunction(() => _testTime)
      ..semanticsEnabled = true;

    final SemanticsTester tester = SemanticsTester(owner());
    tester.updateNode(
      id: 0,
      scopesRoute: true,
      transform: Matrix4.identity().toFloat64(),
    );
    tester.apply();

    expectSemanticsTree(owner(), '''
      <sem style="$rootSemanticStyle"></sem>
    ''');

    expect(
      owner().debugSemanticsTree![0]!.primaryRole?.role,
      PrimaryRole.dialog,
    );
    expect(
      owner().debugSemanticsTree![0]!.primaryRole?.secondaryRoleManagers,
      isNot(contains(Role.routeName)),
    );

    semantics().semanticsEnabled = false;
  });

  test('namesRoute alone has no effect', () {
    semantics()
      ..debugOverrideTimestampFunction(() => _testTime)
      ..semanticsEnabled = true;

    final SemanticsTester tester = SemanticsTester(owner());
    tester.updateNode(
      id: 0,
      transform: Matrix4.identity().toFloat64(),
      children: <SemanticsNodeUpdate>[
        tester.updateNode(
          id: 1,
          children: <SemanticsNodeUpdate>[
            tester.updateNode(
              id: 2,
              namesRoute: true,
              label: 'Hello',
            ),
          ],
        ),
      ],
    );
    tester.apply();

    expectSemanticsTree(owner(), '''
      <sem style="$rootSemanticStyle">
        <sem-c>
          <sem>
            <sem-c>
              <sem role="text">Hello</sem>
            </sem-c>
          </sem>
        </sem-c>
      </sem>
    ''');

    expect(
      owner().debugSemanticsTree![0]!.primaryRole?.role,
      PrimaryRole.generic,
    );
    expect(
      owner().debugSemanticsTree![2]!.primaryRole?.debugSecondaryRoles,
      contains(Role.routeName),
    );

    semantics().semanticsEnabled = false;
  });

  // Test the simple scenario of a dialog coming up and containing focusable
  // descendants that are not initially focused. The expectation is that the
  // first descendant will be auto-focused.
  test('focuses on the first unfocused Focusable', () async {
    semantics()
      ..debugOverrideTimestampFunction(() => _testTime)
      ..semanticsEnabled = true;

    final List<CapturedAction> capturedActions = <CapturedAction>[];
    EnginePlatformDispatcher.instance.onSemanticsActionEvent = (ui.SemanticsActionEvent event) {
      capturedActions.add((event.nodeId, event.type, event.arguments));
    };

    final SemanticsTester tester = SemanticsTester(owner());
    tester.updateNode(
      id: 0,
      scopesRoute: true,
      transform: Matrix4.identity().toFloat64(),
      children: <SemanticsNodeUpdate>[
        tester.updateNode(
          id: 1,
          // None of the children should have isFocused set to `true` to make
          // sure that the auto-focus logic kicks in.
          children: <SemanticsNodeUpdate>[
            tester.updateNode(
              id: 2,
              label: 'Button 1',
              hasTap: true,
              hasEnabledState: true,
              isEnabled: true,
              isButton: true,
              isFocusable: true,
              isFocused: false,
              rect: const ui.Rect.fromLTRB(0, 0, 100, 50),
            ),
            tester.updateNode(
              id: 3,
              label: 'Button 2',
              hasTap: true,
              hasEnabledState: true,
              isEnabled: true,
              isButton: true,
              isFocusable: true,
              isFocused: false,
              rect: const ui.Rect.fromLTRB(0, 0, 100, 50),
            ),
          ],
        ),
      ],
    );
    tester.apply();

    expect(
      capturedActions,
      <CapturedAction>[
        (2, ui.SemanticsAction.didGainAccessibilityFocus, null),
      ],
    );

    semantics().semanticsEnabled = false;
  });

  // Test the scenario of a dialog coming up and containing focusable
  // descendants with one of them explicitly requesting focus. The expectation
  // is that the dialog will not attempt to auto-focus on anything and let the
  // respective descendant take focus.
  test('does nothing if a descendant asks for focus explicitly', () async {
    semantics()
      ..debugOverrideTimestampFunction(() => _testTime)
      ..semanticsEnabled = true;

    final List<CapturedAction> capturedActions = <CapturedAction>[];
    EnginePlatformDispatcher.instance.onSemanticsActionEvent = (ui.SemanticsActionEvent event) {
      capturedActions.add((event.nodeId, event.type, event.arguments));
    };

    final SemanticsTester tester = SemanticsTester(owner());
    tester.updateNode(
      id: 0,
      scopesRoute: true,
      transform: Matrix4.identity().toFloat64(),
      children: <SemanticsNodeUpdate>[
        tester.updateNode(
          id: 1,
          children: <SemanticsNodeUpdate>[
            tester.updateNode(
              id: 2,
              label: 'Button 1',
              hasTap: true,
              hasEnabledState: true,
              isEnabled: true,
              isButton: true,
              isFocusable: true,
              isFocused: false,
              rect: const ui.Rect.fromLTRB(0, 0, 100, 50),
            ),
            tester.updateNode(
              id: 3,
              label: 'Button 2',
              hasTap: true,
              hasEnabledState: true,
              isEnabled: true,
              isButton: true,
              isFocusable: true,
              // Asked for focus explicitly.
              isFocused: true,
              rect: const ui.Rect.fromLTRB(0, 0, 100, 50),
            ),
          ],
        ),
      ],
    );
    tester.apply();

    expect(
      capturedActions,
      <CapturedAction>[
        (3, ui.SemanticsAction.didGainAccessibilityFocus, null),
      ],
    );

    semantics().semanticsEnabled = false;
  });

  // Test the scenario of a dialog coming up and containing non-focusable
  // descendants that can have a11y focus. The expectation is that the first
  // descendant will be auto-focused, even if it's not input-focusable.
  test('focuses on the first non-focusable descedant', () async {
    semantics()
      ..debugOverrideTimestampFunction(() => _testTime)
      ..semanticsEnabled = true;

    final List<CapturedAction> capturedActions = <CapturedAction>[];
    EnginePlatformDispatcher.instance.onSemanticsActionEvent = (ui.SemanticsActionEvent event) {
      capturedActions.add((event.nodeId, event.type, event.arguments));
    };

    final SemanticsTester tester = SemanticsTester(owner());
    tester.updateNode(
      id: 0,
      scopesRoute: true,
      transform: Matrix4.identity().toFloat64(),
      children: <SemanticsNodeUpdate>[
        tester.updateNode(
          id: 1,
          children: <SemanticsNodeUpdate>[
            tester.updateNode(
              id: 2,
              label: 'Heading',
              rect: const ui.Rect.fromLTRB(0, 0, 100, 50),
            ),
            tester.updateNode(
              id: 3,
              label: 'Click me!',
              hasTap: true,
              hasEnabledState: true,
              isEnabled: true,
              isButton: true,
              isFocusable: true,
              isFocused: false,
              rect: const ui.Rect.fromLTRB(0, 0, 100, 50),
            ),
          ],
        ),
      ],
    );
    tester.apply();

    // The focused node is not focusable, so no notification is sent to the
    // framework.
    expect(capturedActions, isEmpty);

    // However, the element should have gotten the focus.
    final DomElement element = owner().debugSemanticsTree![2]!.element;
    expect(element.tabIndex, -1);
    expect(domDocument.activeElement, element);

    semantics().semanticsEnabled = false;
  });

  // This mostly makes sure the engine doesn't crash if given a completely empty
  // dialog trying to find something to focus on.
  test('does nothing if nothing is focusable inside the dialog', () async {
    semantics()
      ..debugOverrideTimestampFunction(() => _testTime)
      ..semanticsEnabled = true;

    final List<CapturedAction> capturedActions = <CapturedAction>[];
    EnginePlatformDispatcher.instance.onSemanticsActionEvent = (ui.SemanticsActionEvent event) {
      capturedActions.add((event.nodeId, event.type, event.arguments));
    };

    final SemanticsTester tester = SemanticsTester(owner());
    tester.updateNode(
      id: 0,
      scopesRoute: true,
      transform: Matrix4.identity().toFloat64(),
    );
    tester.apply();

    expect(capturedActions, isEmpty);
    expect(domDocument.activeElement, domDocument.body);

    semantics().semanticsEnabled = false;
  });
}

typedef CapturedAction = (int nodeId, ui.SemanticsAction action, Object? args);

void _testFocusable() {
  test('AccessibilityFocusManager can manage element focus', () async {
    semantics()
      ..debugOverrideTimestampFunction(() => _testTime)
      ..semanticsEnabled = true;

    void pumpSemantics() {
      final ui.SemanticsUpdateBuilder builder = ui.SemanticsUpdateBuilder();
      updateNode(
        builder,
        label: 'Dummy root element',
        transform: Matrix4.identity().toFloat64(),
        rect: const ui.Rect.fromLTRB(0, 0, 100, 50),
        childrenInHitTestOrder: Int32List.fromList(<int>[]),
        childrenInTraversalOrder: Int32List.fromList(<int>[]),
      );
      owner().updateSemantics(builder.build());
    }

    final List<CapturedAction> capturedActions = <CapturedAction>[];
    EnginePlatformDispatcher.instance.onSemanticsActionEvent = (ui.SemanticsActionEvent event) {
      capturedActions.add((event.nodeId, event.type, event.arguments));
    };
    expect(capturedActions, isEmpty);

    final AccessibilityFocusManager manager = AccessibilityFocusManager(owner());
    expect(capturedActions, isEmpty);

    final DomElement element = createDomElement('test-element');
    expect(element.tabIndex, -1);
    domDocument.body!.append(element);

    // Start managing element
    manager.manage(1, element);
    expect(element.tabIndex, 0);
    expect(capturedActions, isEmpty);
    expect(domDocument.activeElement, isNot(element));

    // Request focus
    manager.changeFocus(true);
    pumpSemantics(); // triggers post-update callbacks
    expect(domDocument.activeElement, element);
    expect(capturedActions, <CapturedAction>[
      (1, ui.SemanticsAction.didGainAccessibilityFocus, null),
    ]);
    capturedActions.clear();

    // Give up focus
    manager.changeFocus(false);
    pumpSemantics(); // triggers post-update callbacks
    expect(capturedActions, isEmpty);
    expect(domDocument.activeElement, element);

    // Browser blurs the element
    element.blur();
    expect(domDocument.activeElement, isNot(element));
    expect(capturedActions, <CapturedAction>[
      (1, ui.SemanticsAction.didLoseAccessibilityFocus, null),
    ]);
    capturedActions.clear();

    // Request focus again
    manager.changeFocus(true);
    pumpSemantics(); // triggers post-update callbacks
    expect(domDocument.activeElement, element);
    expect(capturedActions, <CapturedAction>[
      (1, ui.SemanticsAction.didGainAccessibilityFocus, null),
    ]);
    capturedActions.clear();

    // Double-request focus
    manager.changeFocus(true);
    pumpSemantics(); // triggers post-update callbacks
    expect(domDocument.activeElement, element);
    expect(
      reason: 'Nothing should be sent to the framework on focus re-request.',
      capturedActions, isEmpty);
    capturedActions.clear();

    // Stop managing
    manager.stopManaging();
    pumpSemantics(); // triggers post-update callbacks
    expect(
      reason: 'There should be no notification to the framework because the '
              'framework should already know. Otherwise, it would not have '
              'asked to stop managing the node.',
      capturedActions,
      isEmpty,
    );
    expect(domDocument.activeElement, element);

    // Attempt to request focus when not managing an element.
    element.blur();
    manager.changeFocus(true);
    pumpSemantics(); // triggers post-update callbacks
    expect(
      reason: 'Attempting to request focus on a node that is not managed should '
              'not result in any notifications to the framework.',
      capturedActions,
      isEmpty,
    );
    expect(domDocument.activeElement, isNot(element));

    semantics().semanticsEnabled = false;
  });

  test('applies generic Focusable role', () {
    semantics()
      ..debugOverrideTimestampFunction(() => _testTime)
      ..semanticsEnabled = true;

    {
      final SemanticsTester tester = SemanticsTester(owner());
      tester.updateNode(
        id: 0,
        transform: Matrix4.identity().toFloat64(),
        children: <SemanticsNodeUpdate>[
          tester.updateNode(
            id: 1,
            label: 'focusable text',
            isFocusable: true,
            rect: const ui.Rect.fromLTRB(0, 0, 100, 50),
          ),
        ],
      );
      tester.apply();
    }

    expectSemanticsTree(owner(), '''
<sem style="$rootSemanticStyle">
  <sem-c>
    <sem role="text">focusable text</sem>
  </sem-c>
</sem>
''');

    final SemanticsObject node = owner().debugSemanticsTree![1]!;
    expect(node.isFocusable, isTrue);
    expect(
      node.primaryRole?.role,
      PrimaryRole.generic,
    );
    expect(
      node.primaryRole?.debugSecondaryRoles,
      contains(Role.focusable),
    );

    final DomElement element = node.element;
    expect(domDocument.activeElement, isNot(element));

    {
      final SemanticsTester tester = SemanticsTester(owner());
      tester.updateNode(
        id: 1,
        label: 'test focusable',
        isFocusable: true,
        isFocused: true,
        transform: Matrix4.identity().toFloat64(),
        rect: const ui.Rect.fromLTRB(0, 0, 100, 50),
      );
      tester.apply();
    }
    expect(domDocument.activeElement, element);

    semantics().semanticsEnabled = false;
  });
}

void _testLink() {
  test('nodes with link: true creates anchor tag', () {
    semantics()
      ..debugOverrideTimestampFunction(() => _testTime)
      ..semanticsEnabled = true;

    SemanticsObject pumpSemantics() {
      final SemanticsTester tester = SemanticsTester(owner());
      tester.updateNode(
        id: 0,
        isLink: true,
        rect: const ui.Rect.fromLTRB(0, 0, 100, 50),
      );
      tester.apply();
      return tester.getSemanticsObject(0);
    }

    final SemanticsObject object = pumpSemantics();
    expect(object.element.tagName.toLowerCase(), 'a');
  });
}

/// A facade in front of [ui.SemanticsUpdateBuilder.updateNode] that
/// supplies default values for semantics attributes.
void updateNode(
  ui.SemanticsUpdateBuilder builder, {
  int id = 0,
  int flags = 0,
  int actions = 0,
  int maxValueLength = 0,
  int currentValueLength = 0,
  int textSelectionBase = 0,
  int textSelectionExtent = 0,
  int platformViewId = -1, // -1 means not a platform view
  int scrollChildren = 0,
  int scrollIndex = 0,
  double scrollPosition = 0.0,
  double scrollExtentMax = 0.0,
  double scrollExtentMin = 0.0,
  double elevation = 0.0,
  double thickness = 0.0,
  ui.Rect rect = ui.Rect.zero,
  String identifier = '',
  String label = '',
  List<ui.StringAttribute> labelAttributes = const <ui.StringAttribute>[],
  String hint = '',
  List<ui.StringAttribute> hintAttributes = const <ui.StringAttribute>[],
  String value = '',
  List<ui.StringAttribute> valueAttributes = const <ui.StringAttribute>[],
  String increasedValue = '',
  List<ui.StringAttribute> increasedValueAttributes =
      const <ui.StringAttribute>[],
  String decreasedValue = '',
  List<ui.StringAttribute> decreasedValueAttributes =
      const <ui.StringAttribute>[],
  String tooltip = '',
  ui.TextDirection textDirection = ui.TextDirection.ltr,
  Float64List? transform,
  Int32List? childrenInTraversalOrder,
  Int32List? childrenInHitTestOrder,
  Int32List? additionalActions,
}) {
  transform ??= Float64List.fromList(Matrix4.identity().storage);
  childrenInTraversalOrder ??= Int32List(0);
  childrenInHitTestOrder ??= Int32List(0);
  additionalActions ??= Int32List(0);
  builder.updateNode(
    id: id,
    flags: flags,
    actions: actions,
    maxValueLength: maxValueLength,
    currentValueLength: currentValueLength,
    textSelectionBase: textSelectionBase,
    textSelectionExtent: textSelectionExtent,
    platformViewId: platformViewId,
    scrollChildren: scrollChildren,
    scrollIndex: scrollIndex,
    scrollPosition: scrollPosition,
    scrollExtentMax: scrollExtentMax,
    scrollExtentMin: scrollExtentMin,
    elevation: elevation,
    thickness: thickness,
    rect: rect,
    identifier: identifier,
    label: label,
    labelAttributes: labelAttributes,
    hint: hint,
    hintAttributes: hintAttributes,
    value: value,
    valueAttributes: valueAttributes,
    increasedValue: increasedValue,
    increasedValueAttributes: increasedValueAttributes,
    decreasedValue: decreasedValue,
    decreasedValueAttributes: decreasedValueAttributes,
    tooltip: tooltip,
    textDirection: textDirection,
    transform: transform,
    childrenInTraversalOrder: childrenInTraversalOrder,
    childrenInHitTestOrder: childrenInHitTestOrder,
    additionalActions: additionalActions,
  );
}

const MethodCodec codec = StandardMethodCodec();

/// Sends a platform message to create a Platform View with the given id and viewType.
Future<void> createPlatformView(int id, String viewType) {
  final Completer<void> completer = Completer<void>();
  ui.PlatformDispatcher.instance.sendPlatformMessage(
    'flutter/platform_views',
    codec.encodeMethodCall(MethodCall(
      'create',
      <String, dynamic>{
        'id': id,
        'viewType': viewType,
      },
    )),
    (dynamic _) => completer.complete(),
  );
  return completer.future;
}
