// 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:js_util' as js_util;

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 'keyboard_converter_test.dart';

const int _kNoButtonChange = -1;
const PointerSupportDetector _defaultSupportDetector = PointerSupportDetector();

List<ui.PointerData> _allPointerData(List<ui.PointerDataPacket> packets) {
  return packets.expand((ui.PointerDataPacket packet) => packet.data).toList();
}

typedef _ContextTestBody<T> = void Function(T);

void _testEach<T extends _BasicEventContext>(
  Iterable<T> contexts,
  String description,
  _ContextTestBody<T> body, {
    Object? skip,
  }
) {
  for (final T context in contexts) {
    if (context.isSupported) {
      test('${context.name} $description', () {
        body(context);
      }, skip: skip);
    }
  }
}

void main() {
  internalBootstrapBrowserTest(() => testMain);
}

void testMain() {
  ensureFlutterViewEmbedderInitialized();
  final DomElement glassPane = flutterViewEmbedder.glassPaneElement;
  late double dpi;

  setUp(() {
    ui.window.onPointerDataPacket = null;
    dpi = window.devicePixelRatio;
  });

  KeyboardConverter createKeyboardConverter(List<ui.KeyData> keyDataList) {
    return KeyboardConverter((ui.KeyData key) {
      keyDataList.add(key);
      return true;
    }, OperatingSystem.linux);
  }

  test('ios workaround', () {
    debugEmulateIosSafari = true;
    addTearDown(() {
      debugEmulateIosSafari = false;
    });

    final MockSafariPointerEventWorkaround mockSafariPointer =
        MockSafariPointerEventWorkaround();
    SafariPointerEventWorkaround.instance = mockSafariPointer;
    final List<ui.KeyData> keyDataList = <ui.KeyData>[];
    final KeyboardConverter keyboardConverter = createKeyboardConverter(keyDataList);
    final PointerBinding instance = PointerBinding(createDomHTMLDivElement(), keyboardConverter);
    expect(mockSafariPointer.workAroundInvoked, isIosSafari);
    instance.dispose();
  }, skip: !isSafari);

  test('_PointerEventContext generates expected events', () {
    if (!_PointerEventContext().isSupported) {
      return;
    }

    DomPointerEvent expectCorrectType(DomEvent e) {
      expect(domInstanceOfString(e, 'PointerEvent'), isTrue);
      return e as DomPointerEvent;
    }

    List<DomPointerEvent> expectCorrectTypes(List<DomEvent> events) {
      return events.map(expectCorrectType).toList();
    }

    final _PointerEventContext context = _PointerEventContext();
    DomPointerEvent event;
    List<DomPointerEvent> events;

    event = expectCorrectType(context.primaryDown(clientX: 100, clientY: 101));
    expect(event.type, equals('pointerdown'));
    expect(event.pointerId, equals(1));
    expect(event.button, equals(0));
    expect(event.buttons, equals(1));
    expect(event.client.x, equals(100));
    expect(event.client.y, equals(101));

    event = expectCorrectType(
        context.mouseDown(clientX: 110, clientY: 111, button: 2, buttons: 2));
    expect(event.type, equals('pointerdown'));
    expect(event.pointerId, equals(1));
    expect(event.button, equals(2));
    expect(event.buttons, equals(2));
    expect(event.client.x, equals(110));
    expect(event.client.y, equals(111));

    events = expectCorrectTypes(context.multiTouchDown(const <_TouchDetails>[
      _TouchDetails(pointer: 100, clientX: 120, clientY: 121),
      _TouchDetails(pointer: 101, clientX: 122, clientY: 123),
    ]));
    expect(events.length, equals(2));
    expect(events[0].type, equals('pointerdown'));
    expect(events[0].pointerId, equals(100));
    expect(events[0].button, equals(0));
    expect(events[0].buttons, equals(1));
    expect(events[0].client.x, equals(120));
    expect(events[0].client.y, equals(121));
    expect(events[1].type, equals('pointerdown'));
    expect(events[1].pointerId, equals(101));
    expect(events[1].button, equals(0));
    expect(events[1].buttons, equals(1));
    expect(events[1].client.x, equals(122));
    expect(events[1].client.y, equals(123));

    event = expectCorrectType(context.primaryMove(clientX: 200, clientY: 201));
    expect(event.type, equals('pointermove'));
    expect(event.pointerId, equals(1));
    expect(event.button, equals(-1));
    expect(event.buttons, equals(1));
    expect(event.client.x, equals(200));
    expect(event.client.y, equals(201));

    event = expectCorrectType(context.mouseMove(
        clientX: 210, clientY: 211, button: _kNoButtonChange, buttons: 6));
    expect(event.type, equals('pointermove'));
    expect(event.pointerId, equals(1));
    expect(event.button, equals(-1));
    expect(event.buttons, equals(6));
    expect(event.client.x, equals(210));
    expect(event.client.y, equals(211));

    event = expectCorrectType(
        context.mouseMove(clientX: 212, clientY: 213, button: 2, buttons: 6));
    expect(event.type, equals('pointermove'));
    expect(event.pointerId, equals(1));
    expect(event.button, equals(2));
    expect(event.buttons, equals(6));
    expect(event.client.x, equals(212));
    expect(event.client.y, equals(213));

    event = expectCorrectType(
        context.mouseMove(clientX: 214, clientY: 215, button: 2, buttons: 1));
    expect(event.type, equals('pointermove'));
    expect(event.pointerId, equals(1));
    expect(event.button, equals(2));
    expect(event.buttons, equals(1));
    expect(event.client.x, equals(214));
    expect(event.client.y, equals(215));

    events = expectCorrectTypes(context.multiTouchMove(const <_TouchDetails>[
      _TouchDetails(pointer: 102, clientX: 220, clientY: 221),
      _TouchDetails(pointer: 103, clientX: 222, clientY: 223),
    ]));
    expect(events.length, equals(2));
    expect(events[0].type, equals('pointermove'));
    expect(events[0].pointerId, equals(102));
    expect(events[0].button, equals(-1));
    expect(events[0].buttons, equals(1));
    expect(events[0].client.x, equals(220));
    expect(events[0].client.y, equals(221));
    expect(events[1].type, equals('pointermove'));
    expect(events[1].pointerId, equals(103));
    expect(events[1].button, equals(-1));
    expect(events[1].buttons, equals(1));
    expect(events[1].client.x, equals(222));
    expect(events[1].client.y, equals(223));

    event = expectCorrectType(context.mouseLeave(clientX: 1000, clientY: 2000, buttons: 6));
    expect(event.type, equals('pointerleave'));
    expect(event.pointerId, equals(1));
    expect(event.button, equals(0));
    expect(event.buttons, equals(6));
    expect(event.client.x, equals(1000));
    expect(event.client.y, equals(2000));

    event = expectCorrectType(context.primaryUp(clientX: 300, clientY: 301));
    expect(event.type, equals('pointerup'));
    expect(event.pointerId, equals(1));
    expect(event.button, equals(0));
    expect(event.buttons, equals(0));
    expect(event.client.x, equals(300));
    expect(event.client.y, equals(301));

    event = expectCorrectType(
        context.mouseUp(clientX: 310, clientY: 311, button: 2));
    expect(event.type, equals('pointerup'));
    expect(event.pointerId, equals(1));
    expect(event.button, equals(2));
    expect(event.buttons, equals(0));
    expect(event.client.x, equals(310));
    expect(event.client.y, equals(311));

    events = expectCorrectTypes(context.multiTouchUp(const <_TouchDetails>[
      _TouchDetails(pointer: 104, clientX: 320, clientY: 321),
      _TouchDetails(pointer: 105, clientX: 322, clientY: 323),
    ]));
    expect(events.length, equals(2));
    expect(events[0].type, equals('pointerup'));
    expect(events[0].pointerId, equals(104));
    expect(events[0].button, equals(0));
    expect(events[0].buttons, equals(0));
    expect(events[0].client.x, equals(320));
    expect(events[0].client.y, equals(321));
    expect(events[1].type, equals('pointerup'));
    expect(events[1].pointerId, equals(105));
    expect(events[1].button, equals(0));
    expect(events[1].buttons, equals(0));
    expect(events[1].client.x, equals(322));
    expect(events[1].client.y, equals(323));

    event = expectCorrectType(context.hover(clientX: 400, clientY: 401));
    expect(event.type, equals('pointermove'));
    expect(event.pointerId, equals(1));
    expect(event.button, equals(-1));
    expect(event.buttons, equals(0));
    expect(event.client.x, equals(400));
    expect(event.client.y, equals(401));

    events = expectCorrectTypes(context.multiTouchCancel(const <_TouchDetails>[
      _TouchDetails(pointer: 106, clientX: 500, clientY: 501),
      _TouchDetails(pointer: 107, clientX: 502, clientY: 503),
    ]));
    expect(events.length, equals(2));
    expect(events[0].type, equals('pointercancel'));
    expect(events[0].pointerId, equals(106));
    expect(events[0].button, equals(0));
    expect(events[0].buttons, equals(0));
    expect(events[0].client.x, equals(0));
    expect(events[0].client.y, equals(0));
    expect(events[1].type, equals('pointercancel'));
    expect(events[1].pointerId, equals(107));
    expect(events[1].button, equals(0));
    expect(events[1].buttons, equals(0));
    expect(events[1].client.x, equals(0));
    expect(events[1].client.y, equals(0));

    context.pressAllModifiers();
    event = expectCorrectType(context.primaryDown(clientX: 100, clientY: 101));
    expect(event.getModifierState('Alt'), true);
    expect(event.getModifierState('Control'), true);
    expect(event.getModifierState('Meta'), true);
    expect(event.getModifierState('Shift'), true);
    context.unpressAllModifiers();
    event = expectCorrectType(context.primaryDown(clientX: 100, clientY: 101));
    expect(event.getModifierState('Alt'), false);
    expect(event.getModifierState('Control'), false);
    expect(event.getModifierState('Meta'), false);
    expect(event.getModifierState('Shift'), false);
  });

  test('_TouchEventContext generates expected events', () {
    if (!_TouchEventContext().isSupported) {
      return;
    }

    DomTouchEvent expectCorrectType(DomEvent e) {
      expect(domInstanceOfString(e, 'TouchEvent'), isTrue);
      return e as DomTouchEvent;
    }

    List<DomTouchEvent> expectCorrectTypes(List<DomEvent> events) {
      return events.map(expectCorrectType).toList();
    }

    final _TouchEventContext context = _TouchEventContext();
    DomTouchEvent event;
    List<DomTouchEvent> events;

    event = expectCorrectType(context.primaryDown(clientX: 100, clientY: 101));
    expect(event.type, equals('touchstart'));
    expect(event.changedTouches.length, equals(1));
    expect(event.changedTouches.first.identifier, equals(1));
    expect(event.changedTouches.first.client.x, equals(100));
    expect(event.changedTouches.first.client.y, equals(101));

    events = expectCorrectTypes(context.multiTouchDown(const <_TouchDetails>[
      _TouchDetails(pointer: 100, clientX: 120, clientY: 121),
      _TouchDetails(pointer: 101, clientX: 122, clientY: 123),
    ]));
    expect(events.length, equals(1));
    expect(events[0].type, equals('touchstart'));
    expect(events[0].changedTouches.length, equals(2));
    expect(events[0].changedTouches.first.identifier, equals(100));
    expect(events[0].changedTouches.first.client.x, equals(120));
    expect(events[0].changedTouches.first.client.y, equals(121));
    expect(events[0].changedTouches.elementAt(1).identifier, equals(101));
    expect(events[0].changedTouches.elementAt(1).client.x, equals(122));
    expect(events[0].changedTouches.elementAt(1).client.y, equals(123));

    event = expectCorrectType(context.primaryMove(clientX: 200, clientY: 201));
    expect(event.type, equals('touchmove'));
    expect(event.changedTouches.length, equals(1));
    expect(event.changedTouches.first.identifier, equals(1));
    expect(event.changedTouches.first.client.x, equals(200));
    expect(event.changedTouches.first.client.y, equals(201));

    events = expectCorrectTypes(context.multiTouchMove(const <_TouchDetails>[
      _TouchDetails(pointer: 102, clientX: 220, clientY: 221),
      _TouchDetails(pointer: 103, clientX: 222, clientY: 223),
    ]));
    expect(events.length, equals(1));
    expect(events[0].type, equals('touchmove'));
    expect(events[0].changedTouches.length, equals(2));
    expect(events[0].changedTouches.first.identifier, equals(102));
    expect(events[0].changedTouches.first.client.x, equals(220));
    expect(events[0].changedTouches.first.client.y, equals(221));
    expect(events[0].changedTouches.elementAt(1).identifier, equals(103));
    expect(events[0].changedTouches.elementAt(1).client.x, equals(222));
    expect(events[0].changedTouches.elementAt(1).client.y, equals(223));

    event = expectCorrectType(context.primaryUp(clientX: 300, clientY: 301));
    expect(event.type, equals('touchend'));
    expect(event.changedTouches.length, equals(1));
    expect(event.changedTouches.first.identifier, equals(1));
    expect(event.changedTouches.first.client.x, equals(300));
    expect(event.changedTouches.first.client.y, equals(301));

    events = expectCorrectTypes(context.multiTouchUp(const <_TouchDetails>[
      _TouchDetails(pointer: 104, clientX: 320, clientY: 321),
      _TouchDetails(pointer: 105, clientX: 322, clientY: 323),
    ]));
    expect(events.length, equals(1));
    expect(events[0].type, equals('touchend'));
    expect(events[0].changedTouches.length, equals(2));
    expect(events[0].changedTouches.first.identifier, equals(104));
    expect(events[0].changedTouches.first.client.x, equals(320));
    expect(events[0].changedTouches.first.client.y, equals(321));
    expect(events[0].changedTouches.elementAt(1).identifier, equals(105));
    expect(events[0].changedTouches.elementAt(1).client.x, equals(322));
    expect(events[0].changedTouches.elementAt(1).client.y, equals(323));

    events = expectCorrectTypes(context.multiTouchCancel(const <_TouchDetails>[
      _TouchDetails(pointer: 104, clientX: 320, clientY: 321),
      _TouchDetails(pointer: 105, clientX: 322, clientY: 323),
    ]));
    expect(events.length, equals(1));
    expect(events[0].type, equals('touchcancel'));
    expect(events[0].changedTouches.length, equals(2));
    expect(events[0].changedTouches.first.identifier, equals(104));
    expect(events[0].changedTouches.first.client.x, equals(320));
    expect(events[0].changedTouches.first.client.y, equals(321));
    expect(events[0].changedTouches.elementAt(1).identifier, equals(105));
    expect(events[0].changedTouches.elementAt(1).client.x, equals(322));
    expect(events[0].changedTouches.elementAt(1).client.y, equals(323));

    context.pressAllModifiers();
    event = expectCorrectType(context.primaryDown(clientX: 100, clientY: 101));
    expect(event.altKey, true);
    expect(event.ctrlKey, true);
    expect(event.metaKey, true);
    expect(event.shiftKey, true);
    context.unpressAllModifiers();
    event = expectCorrectType(context.primaryDown(clientX: 100, clientY: 101));
    expect(event.altKey, false);
    expect(event.ctrlKey, false);
    expect(event.metaKey, false);
    expect(event.shiftKey, false);
  });

  test('_MouseEventContext generates expected events', () {
    if (!_MouseEventContext().isSupported) {
      return;
    }

    DomMouseEvent expectCorrectType(DomEvent e) {
      expect(domInstanceOfString(e, 'MouseEvent'), isTrue);
      return e as DomMouseEvent;
    }

    final _MouseEventContext context = _MouseEventContext();
    DomMouseEvent event;

    event = expectCorrectType(context.primaryDown(clientX: 100, clientY: 101));
    expect(event.type, equals('mousedown'));
    expect(event.button, equals(0));
    expect(event.buttons, equals(1));
    expect(event.client.x, equals(100));
    expect(event.client.y, equals(101));
    expect(event.offset.x, equals(100));
    expect(event.offset.y, equals(101));

    event = expectCorrectType(
        context.mouseDown(clientX: 110, clientY: 111, button: 2, buttons: 2));
    expect(event.type, equals('mousedown'));
    expect(event.button, equals(2));
    expect(event.buttons, equals(2));
    expect(event.client.x, equals(110));
    expect(event.client.y, equals(111));

    event = expectCorrectType(context.primaryMove(clientX: 200, clientY: 201));
    expect(event.type, equals('mousemove'));
    expect(event.button, equals(0));
    expect(event.buttons, equals(1));
    expect(event.client.x, equals(200));
    expect(event.client.y, equals(201));

    event = expectCorrectType(context.mouseMove(
        clientX: 210, clientY: 211, button: _kNoButtonChange, buttons: 6));
    expect(event.type, equals('mousemove'));
    expect(event.button, equals(0));
    expect(event.buttons, equals(6));
    expect(event.client.x, equals(210));
    expect(event.client.y, equals(211));

    event = expectCorrectType(
        context.mouseMove(clientX: 212, clientY: 213, button: 2, buttons: 6));
    expect(event.type, equals('mousedown'));
    expect(event.button, equals(2));
    expect(event.buttons, equals(6));
    expect(event.client.x, equals(212));
    expect(event.client.y, equals(213));

    event = expectCorrectType(
        context.mouseMove(clientX: 214, clientY: 215, button: 2, buttons: 1));
    expect(event.type, equals('mouseup'));
    expect(event.button, equals(2));
    expect(event.buttons, equals(1));
    expect(event.client.x, equals(214));
    expect(event.client.y, equals(215));

    event = expectCorrectType(context.mouseLeave(clientX: 1000, clientY: 2000, buttons: 6));
    expect(event.type, equals('mouseleave'));
    expect(event.button, equals(0));
    expect(event.buttons, equals(6));
    expect(event.client.x, equals(1000));
    expect(event.client.y, equals(2000));

    event = expectCorrectType(context.primaryUp(clientX: 300, clientY: 301));
    expect(event.type, equals('mouseup'));
    expect(event.button, equals(0));
    expect(event.buttons, equals(0));
    expect(event.client.x, equals(300));
    expect(event.client.y, equals(301));

    event = expectCorrectType(
        context.mouseUp(clientX: 310, clientY: 311, button: 2));
    expect(event.type, equals('mouseup'));
    expect(event.button, equals(2));
    expect(event.buttons, equals(0));
    expect(event.client.x, equals(310));
    expect(event.client.y, equals(311));

    event = expectCorrectType(context.hover(clientX: 400, clientY: 401));
    expect(event.type, equals('mousemove'));
    expect(event.button, equals(0));
    expect(event.buttons, equals(0));
    expect(event.client.x, equals(400));
    expect(event.client.y, equals(401));

    context.pressAllModifiers();
    event = expectCorrectType(context.primaryDown(clientX: 100, clientY: 101));
    expect(event.getModifierState('Alt'), true);
    expect(event.getModifierState('Control'), true);
    expect(event.getModifierState('Meta'), true);
    expect(event.getModifierState('Shift'), true);
    context.unpressAllModifiers();
    event = expectCorrectType(context.primaryDown(clientX: 100, clientY: 101));
    expect(event.getModifierState('Alt'), false);
    expect(event.getModifierState('Control'), false);
    expect(event.getModifierState('Meta'), false);
    expect(event.getModifierState('Shift'), false);
  });

  // ALL ADAPTERS

  _testEach<_BasicEventContext>(
    <_BasicEventContext>[
      _PointerEventContext(),
      _MouseEventContext(),
      _TouchEventContext(),
    ],
    'can receive pointer events on the glass pane',
    (_BasicEventContext context) {
      PointerBinding.instance!.debugOverrideDetector(context);
      ui.PointerDataPacket? receivedPacket;
      ui.window.onPointerDataPacket = (ui.PointerDataPacket packet) {
        receivedPacket = packet;
      };

      glassPane.dispatchEvent(context.primaryDown());

      expect(receivedPacket, isNotNull);
      expect(receivedPacket!.data[0].buttons, equals(1));
    },
  );

  _testEach<_BasicEventContext>(
    <_BasicEventContext>[
      _PointerEventContext(),
      _MouseEventContext(),
      _TouchEventContext(),
    ],
    'does create an add event if got a pointerdown',
    (_BasicEventContext context) {
      PointerBinding.instance!.debugOverrideDetector(context);
      final List<ui.PointerDataPacket> packets = <ui.PointerDataPacket>[];
      ui.window.onPointerDataPacket = (ui.PointerDataPacket packet) {
        packets.add(packet);
      };

      glassPane.dispatchEvent(context.primaryDown());

      expect(packets, hasLength(1));
      expect(packets.single.data, hasLength(2));

      expect(packets.single.data[0].change, equals(ui.PointerChange.add));
      expect(packets.single.data[1].change, equals(ui.PointerChange.down));
    },
  );

  _testEach<_BasicEventContext>(
    <_BasicEventContext>[
      _PointerEventContext(),
      _MouseEventContext(),
      _TouchEventContext(),
    ],
    'synthesize modifier keys left down event if left or right are not pressed',
    (_BasicEventContext context) {
      PointerBinding.instance!.debugOverrideDetector(context);

      // Should synthesize a modifier left key down event when DOM event indicates
      // that the modifier key is pressed and known pressing state doesn't contain
      // the modifier left key nor the modifier right key.
      void shouldSynthesizeLeftDownIfNotPressed(String key) {
        final int physicalLeft = kWebToPhysicalKey['${key}Left']!;
        final int physicalRight = kWebToPhysicalKey['${key}Right']!;
        final int logicalLeft = kWebLogicalLocationMap[key]![kLocationLeft]!;

        final List<ui.KeyData> keyDataList = <ui.KeyData>[];
        final KeyboardConverter keyboardConverter = createKeyboardConverter(keyDataList);
        PointerBinding.instance!.debugOverrideKeyboardConverter(keyboardConverter);

        expect(keyboardConverter.keyIsPressed(physicalLeft), false);
        expect(keyboardConverter.keyIsPressed(physicalRight), false);
        glassPane.dispatchEvent(context.primaryDown());
        expect(keyDataList.length, 1);
        expectKeyData(keyDataList.last,
          type: ui.KeyEventType.down,
          physical: physicalLeft,
          logical: logicalLeft,
          character: null,
          synthesized: true,
        );
      }

      context.altPressed = true;
      shouldSynthesizeLeftDownIfNotPressed('Alt');
      context.unpressAllModifiers();
      context.ctrlPressed = true;
      shouldSynthesizeLeftDownIfNotPressed('Control');
      context.unpressAllModifiers();
      context.metaPressed = true;
      shouldSynthesizeLeftDownIfNotPressed('Meta');
      context.unpressAllModifiers();
      context.shiftPressed = true;
      shouldSynthesizeLeftDownIfNotPressed('Shift');
      context.unpressAllModifiers();
    },
  );

  _testEach<_BasicEventContext>(
    <_BasicEventContext>[
      _PointerEventContext(),
      _MouseEventContext(),
      _TouchEventContext(),
    ],
    'should not synthesize modifier keys down event if left or right are pressed',
    (_BasicEventContext context) {
      PointerBinding.instance!.debugOverrideDetector(context);

      // Should not synthesize a modifier down event when DOM event indicates
      // that the modifier key is pressed and known pressing state contains
      // the modifier left key.
      void shouldNotSynthesizeDownIfLeftPressed(String key, int modifiers) {
        final int physicalLeft = kWebToPhysicalKey['${key}Left']!;
        final int physicalRight = kWebToPhysicalKey['${key}Right']!;

        final List<ui.KeyData> keyDataList = <ui.KeyData>[];
        final KeyboardConverter keyboardConverter = createKeyboardConverter(keyDataList);
        PointerBinding.instance!.debugOverrideKeyboardConverter(keyboardConverter);

        keyboardConverter.handleEvent(keyDownEvent('${key}Left', key, modifiers, kLocationLeft));
        expect(keyboardConverter.keyIsPressed(physicalLeft), true);
        expect(keyboardConverter.keyIsPressed(physicalRight), false);
        keyDataList.clear(); // Remove key data generated by handleEvent

        glassPane.dispatchEvent(context.primaryDown());
        expect(keyDataList.length, 0);
      }

      // Should not synthesize a modifier down event when DOM event indicates
      // that the modifier key is pressed and known pressing state contains
      // the modifier right key.
      void shouldNotSynthesizeDownIfRightPressed(String key, int modifiers) {
        final int physicalLeft = kWebToPhysicalKey['${key}Left']!;
        final int physicalRight = kWebToPhysicalKey['${key}Right']!;

        final List<ui.KeyData> keyDataList = <ui.KeyData>[];
        final KeyboardConverter keyboardConverter = createKeyboardConverter(keyDataList);
        PointerBinding.instance!.debugOverrideKeyboardConverter(keyboardConverter);

        keyboardConverter.handleEvent(keyDownEvent('${key}Right', key, modifiers, kLocationRight));
        expect(keyboardConverter.keyIsPressed(physicalLeft), false);
        expect(keyboardConverter.keyIsPressed(physicalRight), true);
        keyDataList.clear(); // Remove key data generated by handleEvent

        glassPane.dispatchEvent(context.primaryDown());
        expect(keyDataList.length, 0);
      }

      context.altPressed = true;
      shouldNotSynthesizeDownIfLeftPressed('Alt', kAlt);
      shouldNotSynthesizeDownIfRightPressed('Alt', kAlt);
      context.unpressAllModifiers();
      context.ctrlPressed = true;
      shouldNotSynthesizeDownIfLeftPressed('Control', kCtrl);
      shouldNotSynthesizeDownIfRightPressed('Control', kCtrl);
      context.unpressAllModifiers();
      context.metaPressed = true;
      shouldNotSynthesizeDownIfLeftPressed('Meta', kMeta);
      shouldNotSynthesizeDownIfRightPressed('Meta', kMeta);
      context.unpressAllModifiers();
      context.shiftPressed = true;
      shouldNotSynthesizeDownIfLeftPressed('Shift', kShift);
      shouldNotSynthesizeDownIfRightPressed('Shift', kShift);
      context.unpressAllModifiers();
    },
  );

  _testEach<_BasicEventContext>(
    <_BasicEventContext>[
      _PointerEventContext(),
      _MouseEventContext(),
      _TouchEventContext(),
    ],
    'synthesize modifier keys up event if left or right are pressed',
    (_BasicEventContext context) {
      PointerBinding.instance!.debugOverrideDetector(context);

      // Should synthesize a modifier left key up event when DOM event indicates
      // that the modifier key is not pressed and known pressing state contains
      // the modifier left key.
      void shouldSynthesizeLeftUpIfLeftPressed(String key, int modifiers) {
        final int physicalLeft = kWebToPhysicalKey['${key}Left']!;
        final int physicalRight = kWebToPhysicalKey['${key}Right']!;
        final int logicalLeft = kWebLogicalLocationMap[key]![kLocationLeft]!;

        final List<ui.KeyData> keyDataList = <ui.KeyData>[];
        final KeyboardConverter keyboardConverter = createKeyboardConverter(keyDataList);
        PointerBinding.instance!.debugOverrideKeyboardConverter(keyboardConverter);

        keyboardConverter.handleEvent(keyDownEvent('${key}Left', key, modifiers, kLocationLeft));
        expect(keyboardConverter.keyIsPressed(physicalLeft), true);
        expect(keyboardConverter.keyIsPressed(physicalRight), false);
        keyDataList.clear(); // Remove key data generated by handleEvent

        glassPane.dispatchEvent(context.primaryDown());
        expect(keyDataList.length, 1);
        expectKeyData(keyDataList.last,
          type: ui.KeyEventType.up,
          physical: physicalLeft,
          logical: logicalLeft,
          character: null,
          synthesized: true,
        );
        expect(keyboardConverter.keyIsPressed(physicalLeft), false);
      }

      // Should synthesize a modifier right key up event when DOM event indicates
      // that the modifier key is not pressed and known pressing state contains
      // the modifier right key.
      void shouldSynthesizeRightUpIfRightPressed(String key, int modifiers) {
        final int physicalLeft = kWebToPhysicalKey['${key}Left']!;
        final int physicalRight = kWebToPhysicalKey['${key}Right']!;
        final int logicalRight = kWebLogicalLocationMap[key]![kLocationRight]!;

        final List<ui.KeyData> keyDataList = <ui.KeyData>[];
        final KeyboardConverter keyboardConverter = createKeyboardConverter(keyDataList);
        PointerBinding.instance!.debugOverrideKeyboardConverter(keyboardConverter);

        keyboardConverter.handleEvent(keyDownEvent('${key}Right', key, modifiers, kLocationRight));
        expect(keyboardConverter.keyIsPressed(physicalLeft), false);
        expect(keyboardConverter.keyIsPressed(physicalRight), true);
        keyDataList.clear(); // Remove key data generated by handleEvent

        glassPane.dispatchEvent(context.primaryDown());
        expect(keyDataList.length, 1);
        expectKeyData(keyDataList.last,
          type: ui.KeyEventType.up,
          physical: physicalRight,
          logical: logicalRight,
          character: null,
          synthesized: true,
        );
        expect(keyboardConverter.keyIsPressed(physicalRight), false);
      }

      context.altPressed = false;
      shouldSynthesizeLeftUpIfLeftPressed('Alt', kAlt);
      shouldSynthesizeRightUpIfRightPressed('Alt', kAlt);
      context.ctrlPressed = false;
      shouldSynthesizeLeftUpIfLeftPressed('Control', kCtrl);
      shouldSynthesizeRightUpIfRightPressed('Control', kCtrl);
      context.metaPressed = false;
      shouldSynthesizeLeftUpIfLeftPressed('Meta', kMeta);
      shouldSynthesizeRightUpIfRightPressed('Meta', kMeta);
      context.shiftPressed = false;
      shouldSynthesizeLeftUpIfLeftPressed('Shift', kShift);
      shouldSynthesizeRightUpIfRightPressed('Shift', kShift);
    },
  );

  _testEach<_BasicEventContext>(
    <_BasicEventContext>[
      _PointerEventContext(),
      _MouseEventContext(),
      _TouchEventContext(),
    ],
    'should not synthesize modifier keys up event if left or right are not pressed',
    (_BasicEventContext context) {
      PointerBinding.instance!.debugOverrideDetector(context);

      // Should not synthesize a modifier up event when DOM event indicates
      // that the modifier key is not pressed and known pressing state does
      // not contain the modifier left key nor the modifier right key.
      void shouldNotSynthesizeUpIfNotPressed(String key) {
        final int physicalLeft = kWebToPhysicalKey['${key}Left']!;
        final int physicalRight = kWebToPhysicalKey['${key}Right']!;

        final List<ui.KeyData> keyDataList = <ui.KeyData>[];
        final KeyboardConverter keyboardConverter = createKeyboardConverter(keyDataList);
        PointerBinding.instance!.debugOverrideKeyboardConverter(keyboardConverter);

        expect(keyboardConverter.keyIsPressed(physicalLeft), false);
        expect(keyboardConverter.keyIsPressed(physicalRight), false);
        keyDataList.clear(); // Remove key data generated by handleEvent

        glassPane.dispatchEvent(context.primaryDown());
        expect(keyDataList.length, 0);
      }

      context.altPressed = false;
      shouldNotSynthesizeUpIfNotPressed('Alt');
      context.ctrlPressed = false;
      shouldNotSynthesizeUpIfNotPressed('Control');
      context.metaPressed = false;
      shouldNotSynthesizeUpIfNotPressed('Meta');
      context.shiftPressed = false;
      shouldNotSynthesizeUpIfNotPressed('Shift');
    },
  );

  _testEach<_BasicEventContext>(
    <_BasicEventContext>[
      _PointerEventContext(),
      _MouseEventContext(),
      _TouchEventContext(),
    ],
    'should synthesize modifier keys up event for AltGraph',
    (_BasicEventContext context) {
      PointerBinding.instance!.debugOverrideDetector(context);

      final List<ui.KeyData> keyDataList = <ui.KeyData>[];
      final KeyboardConverter keyboardConverter = createKeyboardConverter(keyDataList);
      PointerBinding.instance!.debugOverrideKeyboardConverter(keyboardConverter);

      final int physicalAltRight = kWebToPhysicalKey['AltRight']!;
      final int logicalAltGraph = kWebLogicalLocationMap['AltGraph']![0]!;

      // Simulate pressing `AltGr` key.
      keyboardConverter.handleEvent(keyDownEvent('AltRight', 'AltGraph'));
      expect(keyboardConverter.keyIsPressed(physicalAltRight), true);
      keyDataList.clear(); // Remove key data generated by handleEvent.

      glassPane.dispatchEvent(context.primaryDown());
      expect(keyDataList.length, 1);
      expectKeyData(keyDataList.last,
        type: ui.KeyEventType.up,
        physical: physicalAltRight,
        logical: logicalAltGraph,
        character: null,
        synthesized: true,
      );
      expect(keyboardConverter.keyIsPressed(physicalAltRight), false);
    },
  );

  _testEach<_ButtonedEventMixin>(
    <_ButtonedEventMixin>[
      if (!isIosSafari) _PointerEventContext(),
      if (!isIosSafari) _MouseEventContext(),
    ],
    'correctly detects events on the semantics placeholder',
    (_ButtonedEventMixin context) {
      PointerBinding.instance!.debugOverrideDetector(context);
      final List<ui.PointerDataPacket> packets = <ui.PointerDataPacket>[];
      ui.window.onPointerDataPacket = (ui.PointerDataPacket packet) {
        packets.add(packet);
      };

      final DomElement semanticsPlaceholder =
          createDomElement('flt-semantics-placeholder');
      glassPane.append(semanticsPlaceholder);

      // Press on the semantics placeholder.
      semanticsPlaceholder.dispatchEvent(context.primaryDown(
        clientX: 10.0,
        clientY: 10.0,
      ));
      expect(packets, hasLength(1));
      expect(packets[0].data, hasLength(2));
      expect(packets[0].data[0].change, equals(ui.PointerChange.add));
      expect(packets[0].data[1].change, equals(ui.PointerChange.down));
      expect(packets[0].data[1].physicalX, equals(10.0 * dpi));
      expect(packets[0].data[1].physicalY, equals(10.0 * dpi));
      packets.clear();

      // Drag on the semantics placeholder.
      semanticsPlaceholder.dispatchEvent(context.primaryMove(
        clientX: 12.0,
        clientY: 10.0,
      ));
      expect(packets, hasLength(1));
      expect(packets[0].data, hasLength(1));
      expect(packets[0].data[0].change, equals(ui.PointerChange.move));
      expect(packets[0].data[0].physicalX, equals(12.0 * dpi));
      expect(packets[0].data[0].physicalY, equals(10.0 * dpi));
      packets.clear();

      // Keep dragging.
      semanticsPlaceholder.dispatchEvent(context.primaryMove(
        clientX: 15.0,
        clientY: 10.0,
      ));
      expect(packets[0].data, hasLength(1));
      expect(packets[0].data[0].change, equals(ui.PointerChange.move));
      expect(packets[0].data[0].physicalX, equals(15.0 * dpi));
      expect(packets[0].data[0].physicalY, equals(10.0 * dpi));
      packets.clear();

      // Release the pointer on the semantics placeholder.
      glassPane.dispatchEvent(context.primaryUp(
        clientX: 100.0,
        clientY: 200.0,
      ));
      expect(packets, hasLength(1));
      expect(packets[0].data, hasLength(2));
      expect(packets[0].data[0].change, equals(ui.PointerChange.move));
      expect(packets[0].data[0].physicalX, equals(100.0 * dpi));
      expect(packets[0].data[0].physicalY, equals(200.0 * dpi));
      expect(packets[0].data[1].change, equals(ui.PointerChange.up));
      expect(packets[0].data[1].physicalX, equals(100.0 * dpi));
      expect(packets[0].data[1].physicalY, equals(200.0 * dpi));
      packets.clear();

      semanticsPlaceholder.remove();
    },
    skip: isFirefox, // https://bugzilla.mozilla.org/show_bug.cgi?id=1804190
  );

  // BUTTONED ADAPTERS

  _testEach<_ButtonedEventMixin>(
    <_ButtonedEventMixin>[
      _PointerEventContext(),
      _MouseEventContext(),
    ],
    'creates an add event if the first pointer activity is a hover',
    (_ButtonedEventMixin context) {
      PointerBinding.instance!.debugOverrideDetector(context);
      final List<ui.PointerDataPacket> packets = <ui.PointerDataPacket>[];
      ui.window.onPointerDataPacket = (ui.PointerDataPacket packet) {
        packets.add(packet);
      };

      glassPane.dispatchEvent(context.hover());

      expect(packets, hasLength(1));
      expect(packets.single.data, hasLength(2));

      expect(packets.single.data[0].change, equals(ui.PointerChange.add));
      expect(packets.single.data[0].synthesized, isTrue);
      expect(packets.single.data[1].change, equals(ui.PointerChange.hover));
    },
  );

  _testEach<_ButtonedEventMixin>(
    <_ButtonedEventMixin>[
      _PointerEventContext(),
      _MouseEventContext(),
    ],
    'sends a pointermove event instead of the second pointerdown in a row',
    (_ButtonedEventMixin context) {
      PointerBinding.instance!.debugOverrideDetector(context);
      final List<ui.PointerDataPacket> packets = <ui.PointerDataPacket>[];
      ui.window.onPointerDataPacket = (ui.PointerDataPacket packet) {
        packets.add(packet);
      };

      glassPane.dispatchEvent(context.primaryDown(
        clientX: 10.0,
        clientY: 10.0,
      ));
      expect(packets, hasLength(1));
      // An add will be synthesized.
      expect(packets[0].data, hasLength(2));
      expect(packets[0].data[0].change, equals(ui.PointerChange.add));
      expect(packets[0].data[0].synthesized, isTrue);
      expect(packets[0].data[1].change, equals(ui.PointerChange.down));
      packets.clear();

      glassPane.dispatchEvent(context.primaryDown(
        clientX: 20.0,
        clientY: 20.0,
      ));
      expect(packets, hasLength(1));
      expect(packets[0].data, hasLength(1));
      expect(packets[0].data[0].change, equals(ui.PointerChange.move));
      expect(packets[0].data[0].buttons, equals(1));
      packets.clear();
    },
  );

  _testEach<_ButtonedEventMixin>(
    <_ButtonedEventMixin>[
      if (!isIosSafari) _PointerEventContext(),
      if (!isIosSafari) _MouseEventContext(),
    ],
    'does synthesize add or hover or move for scroll',
    (_ButtonedEventMixin context) {
      PointerBinding.instance!.debugOverrideDetector(context);
      final List<ui.PointerDataPacket> packets = <ui.PointerDataPacket>[];
      ui.window.onPointerDataPacket = (ui.PointerDataPacket packet) {
        packets.add(packet);
      };

      glassPane.dispatchEvent(context.wheel(
        buttons: 0,
        clientX: 10,
        clientY: 10,
        deltaX: 10,
        deltaY: 10,
      ));

      glassPane.dispatchEvent(context.wheel(
        buttons: 0,
        clientX: 20,
        clientY: 50,
        deltaX: 10,
        deltaY: 10,
      ));

      glassPane.dispatchEvent(context.mouseDown(
        button: 0,
        buttons: 1,
        clientX: 20.0,
        clientY: 50.0,
      ));

      glassPane.dispatchEvent(context.wheel(
        buttons: 1,
        clientX: 30,
        clientY: 60,
        deltaX: 10,
        deltaY: 10,
      ));

      expect(packets, hasLength(4));

      // An add will be synthesized.
      expect(packets[0].data, hasLength(2));
      expect(packets[0].data[0].change, equals(ui.PointerChange.add));
      expect(packets[0].data[0].pointerIdentifier, equals(0));
      expect(packets[0].data[0].synthesized, isTrue);
      expect(packets[0].data[0].physicalX, equals(10.0 * dpi));
      expect(packets[0].data[0].physicalY, equals(10.0 * dpi));
      expect(packets[0].data[0].physicalDeltaX, equals(0.0));
      expect(packets[0].data[0].physicalDeltaY, equals(0.0));

      expect(packets[0].data[1].change, equals(ui.PointerChange.hover));
      expect(
          packets[0].data[1].signalKind, equals(ui.PointerSignalKind.scroll));
      expect(packets[0].data[1].pointerIdentifier, equals(0));
      expect(packets[0].data[1].synthesized, isFalse);
      expect(packets[0].data[1].physicalX, equals(10.0 * dpi));
      expect(packets[0].data[1].physicalY, equals(10.0 * dpi));
      expect(packets[0].data[1].physicalDeltaX, equals(0.0));
      expect(packets[0].data[1].physicalDeltaY, equals(0.0));

      // A hover will be synthesized.
      expect(packets[1].data, hasLength(2));
      expect(packets[1].data[0].change, equals(ui.PointerChange.hover));
      expect(packets[1].data[0].pointerIdentifier, equals(0));
      expect(packets[1].data[0].synthesized, isTrue);
      expect(packets[1].data[0].physicalX, equals(20.0 * dpi));
      expect(packets[1].data[0].physicalY, equals(50.0 * dpi));
      expect(packets[1].data[0].physicalDeltaX, equals(10.0 * dpi));
      expect(packets[1].data[0].physicalDeltaY, equals(40.0 * dpi));

      expect(packets[1].data[1].change, equals(ui.PointerChange.hover));
      expect(
          packets[1].data[1].signalKind, equals(ui.PointerSignalKind.scroll));
      expect(packets[1].data[1].pointerIdentifier, equals(0));
      expect(packets[1].data[1].synthesized, isFalse);
      expect(packets[1].data[1].physicalX, equals(20.0 * dpi));
      expect(packets[1].data[1].physicalY, equals(50.0 * dpi));
      expect(packets[1].data[1].physicalDeltaX, equals(0.0));
      expect(packets[1].data[1].physicalDeltaY, equals(0.0));

      // No synthetic pointer data for down event.
      expect(packets[2].data, hasLength(1));
      expect(packets[2].data[0].change, equals(ui.PointerChange.down));
      expect(packets[2].data[0].signalKind, equals(ui.PointerSignalKind.none));
      expect(packets[2].data[0].pointerIdentifier, equals(1));
      expect(packets[2].data[0].synthesized, isFalse);
      expect(packets[2].data[0].physicalX, equals(20.0 * dpi));
      expect(packets[2].data[0].physicalY, equals(50.0 * dpi));
      expect(packets[2].data[0].physicalDeltaX, equals(0.0));
      expect(packets[2].data[0].physicalDeltaY, equals(0.0));

      // A move will be synthesized instead of hover because the button is currently down.
      expect(packets[3].data, hasLength(2));
      expect(packets[3].data[0].change, equals(ui.PointerChange.move));
      expect(packets[3].data[0].pointerIdentifier, equals(1));
      expect(packets[3].data[0].synthesized, isTrue);
      expect(packets[3].data[0].physicalX, equals(30.0 * dpi));
      expect(packets[3].data[0].physicalY, equals(60.0 * dpi));
      expect(packets[3].data[0].physicalDeltaX, equals(10.0 * dpi));
      expect(packets[3].data[0].physicalDeltaY, equals(10.0 * dpi));

      expect(packets[3].data[1].change, equals(ui.PointerChange.hover));
      expect(
          packets[3].data[1].signalKind, equals(ui.PointerSignalKind.scroll));
      expect(packets[3].data[1].pointerIdentifier, equals(1));
      expect(packets[3].data[1].synthesized, isFalse);
      expect(packets[3].data[1].physicalX, equals(30.0 * dpi));
      expect(packets[3].data[1].physicalY, equals(60.0 * dpi));
      expect(packets[3].data[1].physicalDeltaX, equals(0.0));
      expect(packets[3].data[1].physicalDeltaY, equals(0.0));
    },
  );

  _testEach<_ButtonedEventMixin>(
    <_ButtonedEventMixin>[
      if (!isIosSafari) _PointerEventContext(),
      if (!isIosSafari) _MouseEventContext(),
    ],
    'converts scroll delta to physical pixels (Firefox)',
    (_ButtonedEventMixin context) {
      PointerBinding.instance!.debugOverrideDetector(context);

      const double dpi = 2.5;
      debugOperatingSystemOverride = OperatingSystem.macOs;
      debugBrowserEngineOverride = BrowserEngine.firefox;
      window.debugOverrideDevicePixelRatio(dpi);

      final List<ui.PointerDataPacket> packets = <ui.PointerDataPacket>[];
      ui.window.onPointerDataPacket = (ui.PointerDataPacket packet) {
        packets.add(packet);
      };

      glassPane.dispatchEvent(context.wheel(
        buttons: 0,
        clientX: 10,
        clientY: 10,
        deltaX: 10,
        deltaY: 10,
      ));

      expect(packets, hasLength(1));


      // An add will be synthesized.
      expect(packets[0].data, hasLength(2));
      expect(packets[0].data[0].change, equals(ui.PointerChange.add));
      // Scroll deltas should be multiplied by `dpi`.
      expect(packets[0].data[0].scrollDeltaX, equals(10.0 * dpi));
      expect(packets[0].data[0].scrollDeltaY, equals(10.0 * dpi));

      expect(packets[0].data[1].change, equals(ui.PointerChange.hover));
      expect(packets[0].data[1].signalKind, equals(ui.PointerSignalKind.scroll));
      // Scroll deltas should be multiplied by `dpi`.
      expect(packets[0].data[0].scrollDeltaX, equals(10.0 * dpi));
      expect(packets[0].data[0].scrollDeltaY, equals(10.0 * dpi));

      window.debugOverrideDevicePixelRatio(1.0);
      debugOperatingSystemOverride = null;
      debugBrowserEngineOverride = null;
    },
  );

  _testEach<_ButtonedEventMixin>(
    <_ButtonedEventMixin>[
      if (!isIosSafari) _PointerEventContext(),
      if (!isIosSafari) _MouseEventContext(),
    ],
    'scroll delta are already in physical pixels (Chrome)',
    (_ButtonedEventMixin context) {
      PointerBinding.instance!.debugOverrideDetector(context);

      const double dpi = 2.5;
      debugOperatingSystemOverride = OperatingSystem.macOs;
      debugBrowserEngineOverride = BrowserEngine.blink;
      window.debugOverrideDevicePixelRatio(dpi);

      final List<ui.PointerDataPacket> packets = <ui.PointerDataPacket>[];
      ui.window.onPointerDataPacket = (ui.PointerDataPacket packet) {
        packets.add(packet);
      };

      glassPane.dispatchEvent(context.wheel(
        buttons: 0,
        clientX: 10,
        clientY: 10,
        deltaX: 10,
        deltaY: 10,
      ));

      expect(packets, hasLength(1));


      // An add will be synthesized.
      expect(packets[0].data, hasLength(2));
      expect(packets[0].data[0].change, equals(ui.PointerChange.add));
      // Scroll deltas should NOT be multiplied by `dpi`.
      expect(packets[0].data[0].scrollDeltaX, equals(10.0));
      expect(packets[0].data[0].scrollDeltaY, equals(10.0));

      expect(packets[0].data[1].change, equals(ui.PointerChange.hover));
      expect(packets[0].data[1].signalKind, equals(ui.PointerSignalKind.scroll));
      // Scroll deltas should NOT be multiplied by `dpi`.
      expect(packets[0].data[0].scrollDeltaX, equals(10.0));
      expect(packets[0].data[0].scrollDeltaY, equals(10.0));

      window.debugOverrideDevicePixelRatio(1.0);
      debugOperatingSystemOverride = null;
      debugBrowserEngineOverride = null;
    },
  );

  _testEach<_ButtonedEventMixin>(
    <_ButtonedEventMixin>[
      if (!isIosSafari) _PointerEventContext(),
      if (!isIosSafari) _MouseEventContext(),
    ],
    'does set pointer device kind based on delta precision and wheelDelta',
    (_ButtonedEventMixin context) {
      if (isFirefox) {
        // Firefox does not support trackpad events, as they cannot be
        // disambiguated from smoothed mouse wheel events.
        return;
      }
      PointerBinding.instance!.debugOverrideDetector(context);
      final List<ui.PointerDataPacket> packets = <ui.PointerDataPacket>[];
      ui.window.onPointerDataPacket = (ui.PointerDataPacket packet) {
        packets.add(packet);
      };

      glassPane.dispatchEvent(context.wheel(
        buttons: 0,
        clientX: 10,
        clientY: 10,
        deltaX: 119,
        deltaY: 119,
        wheelDeltaX: -357,
        wheelDeltaY: -357,
        timeStamp: 0,
      ));

      glassPane.dispatchEvent(context.wheel(
        buttons: 0,
        clientX: 10,
        clientY: 10,
        deltaX: 120,
        deltaY: 120,
        wheelDeltaX: -360,
        wheelDeltaY: -360,
        timeStamp: 10,
      ));

      glassPane.dispatchEvent(context.wheel(
        buttons: 0,
        clientX: 10,
        clientY: 10,
        deltaX: 120,
        deltaY: 120,
        wheelDeltaX: -360,
        wheelDeltaY: -360,
        timeStamp: 20,
      ));

      glassPane.dispatchEvent(context.wheel(
        buttons: 0,
        clientX: 10,
        clientY: 10,
        deltaX: 119,
        deltaY: 119,
        wheelDeltaX: -357,
        wheelDeltaY: -357,
        timeStamp: 1000,
      ));

      glassPane.dispatchEvent(context.wheel(
        buttons: 0,
        clientX: 10,
        clientY: 10,
        deltaX: -120,
        deltaY: -120,
        wheelDeltaX: 360,
        wheelDeltaY: 360,
        timeStamp: 1010,
      ));

      glassPane.dispatchEvent(context.wheel(
        buttons: 0,
        clientX: 10,
        clientY: 10,
        deltaX: 0,
        deltaY: -120,
        wheelDeltaX: 0,
        wheelDeltaY: 360,
        timeStamp: 2000,
      ));

      glassPane.dispatchEvent(context.wheel(
        buttons: 0,
        clientX: 10,
        clientY: 10,
        deltaX: 0,
        deltaY: 40,
        wheelDeltaX: 0,
        wheelDeltaY: -360,
        timeStamp: 3000,
      ));

      expect(packets, hasLength(7));

      // An add will be synthesized.
      expect(packets[0].data, hasLength(2));
      expect(packets[0].data[0].change, equals(ui.PointerChange.add));
      expect(packets[0].data[0].pointerIdentifier, equals(0));
      expect(packets[0].data[0].synthesized, isTrue);
      expect(packets[0].data[0].physicalX, equals(10.0 * dpi));
      expect(packets[0].data[0].physicalY, equals(10.0 * dpi));
      expect(packets[0].data[0].physicalDeltaX, equals(0.0));
      expect(packets[0].data[0].physicalDeltaY, equals(0.0));
      // Because the delta is not in increments of 120 and has matching wheelDelta,
      // it will be a trackpad event.
      expect(packets[0].data[1].change, equals(ui.PointerChange.hover));
      expect(
          packets[0].data[1].signalKind, equals(ui.PointerSignalKind.scroll));
      expect(
          packets[0].data[1].kind, equals(ui.PointerDeviceKind.trackpad));
      expect(packets[0].data[1].device, equals(-2));
      expect(packets[0].data[1].pointerIdentifier, equals(0));
      expect(packets[0].data[1].synthesized, isFalse);
      expect(packets[0].data[1].physicalX, equals(10.0 * dpi));
      expect(packets[0].data[1].physicalY, equals(10.0 * dpi));
      expect(packets[0].data[1].physicalDeltaX, equals(0.0));
      expect(packets[0].data[1].physicalDeltaY, equals(0.0));
      expect(packets[0].data[1].scrollDeltaX, equals(119.0));
      expect(packets[0].data[1].scrollDeltaY, equals(119.0));

      // Because the delta is in increments of 120, but is similar to the
      // previous event, it will be a trackpad event.
      expect(packets[1].data[0].change, equals(ui.PointerChange.hover));
      expect(
          packets[1].data[0].signalKind, equals(ui.PointerSignalKind.scroll));
      expect(
          packets[1].data[0].kind, equals(ui.PointerDeviceKind.trackpad));
      expect(packets[1].data[0].device, equals(-2));
      expect(packets[1].data[0].pointerIdentifier, equals(0));
      expect(packets[1].data[0].synthesized, isFalse);
      expect(packets[1].data[0].physicalX, equals(10.0 * dpi));
      expect(packets[1].data[0].physicalY, equals(10.0 * dpi));
      expect(packets[1].data[0].physicalDeltaX, equals(0.0));
      expect(packets[1].data[0].physicalDeltaY, equals(0.0));
      expect(packets[1].data[0].scrollDeltaX, equals(120.0));
      expect(packets[1].data[0].scrollDeltaY, equals(120.0));

      // Because the delta is in increments of 120, but is again similar to the
      // previous event, it will be a trackpad event.
      expect(packets[2].data[0].change, equals(ui.PointerChange.hover));
      expect(
          packets[2].data[0].signalKind, equals(ui.PointerSignalKind.scroll));
      expect(
          packets[2].data[0].kind, equals(ui.PointerDeviceKind.trackpad));
      expect(packets[2].data[0].device, equals(-2));
      expect(packets[2].data[0].pointerIdentifier, equals(0));
      expect(packets[2].data[0].synthesized, isFalse);
      expect(packets[2].data[0].physicalX, equals(10.0 * dpi));
      expect(packets[2].data[0].physicalY, equals(10.0 * dpi));
      expect(packets[2].data[0].physicalDeltaX, equals(0.0));
      expect(packets[2].data[0].physicalDeltaY, equals(0.0));
      expect(packets[2].data[0].scrollDeltaX, equals(120.0));
      expect(packets[2].data[0].scrollDeltaY, equals(120.0));

      // Because the delta is not in increments of 120 and has matching wheelDelta,
      // it will be a trackpad event.
      expect(packets[3].data[0].change, equals(ui.PointerChange.hover));
      expect(
          packets[3].data[0].signalKind, equals(ui.PointerSignalKind.scroll));
      expect(
          packets[3].data[0].kind, equals(ui.PointerDeviceKind.trackpad));
      expect(packets[3].data[0].device, equals(-2));
      expect(packets[3].data[0].pointerIdentifier, equals(0));
      expect(packets[3].data[0].synthesized, isFalse);
      expect(packets[3].data[0].physicalX, equals(10.0 * dpi));
      expect(packets[3].data[0].physicalY, equals(10.0 * dpi));
      expect(packets[3].data[0].physicalDeltaX, equals(0.0));
      expect(packets[3].data[0].physicalDeltaY, equals(0.0));
      expect(packets[3].data[0].scrollDeltaX, equals(119.0));
      expect(packets[3].data[0].scrollDeltaY, equals(119.0));

      // Because the delta is in increments of 120, and is not similar to the
      // previous event, but occurred soon after the previous event, it will be
      // a trackpad event.
      expect(packets[4].data[0].change, equals(ui.PointerChange.hover));
      expect(
          packets[4].data[0].signalKind, equals(ui.PointerSignalKind.scroll));
      expect(
          packets[4].data[0].kind, equals(ui.PointerDeviceKind.trackpad));
      expect(packets[4].data[0].device, equals(-2));
      expect(packets[4].data[0].pointerIdentifier, equals(0));
      expect(packets[4].data[0].synthesized, isFalse);
      expect(packets[4].data[0].physicalX, equals(10.0 * dpi));
      expect(packets[4].data[0].physicalY, equals(10.0 * dpi));
      expect(packets[4].data[0].physicalDeltaX, equals(0.0));
      expect(packets[4].data[0].physicalDeltaY, equals(0.0));
      expect(packets[4].data[0].scrollDeltaX, equals(-120.0));
      expect(packets[4].data[0].scrollDeltaY, equals(-120.0));

      // An add will be synthesized.
      expect(packets[5].data, hasLength(2));
      expect(packets[5].data[0].change, equals(ui.PointerChange.add));
      expect(
          packets[5].data[0].signalKind, equals(ui.PointerSignalKind.none));
      expect(
          packets[5].data[0].kind, equals(ui.PointerDeviceKind.mouse));
      expect(packets[5].data[0].device, equals(-1));
      expect(packets[5].data[0].pointerIdentifier, equals(0));
      expect(packets[5].data[0].synthesized, isTrue);
      expect(packets[5].data[0].physicalX, equals(10.0 * dpi));
      expect(packets[5].data[0].physicalY, equals(10.0 * dpi));
      expect(packets[5].data[0].physicalDeltaX, equals(0.0));
      expect(packets[5].data[0].physicalDeltaY, equals(0.0));
      expect(packets[5].data[0].scrollDeltaX, equals(0.0));
      expect(packets[5].data[0].scrollDeltaY, equals(-120.0));
      // Because the delta is in increments of 120, and is not similar to
      // the previous event, and occurred long after the previous event, it will
      // be a mouse event.
      expect(packets[5].data[1].change, equals(ui.PointerChange.hover));
      expect(
          packets[5].data[1].signalKind, equals(ui.PointerSignalKind.scroll));
      expect(
          packets[5].data[1].kind, equals(ui.PointerDeviceKind.mouse));
      expect(packets[5].data[1].device, equals(-1));
      expect(packets[5].data[1].pointerIdentifier, equals(0));
      expect(packets[5].data[1].synthesized, isFalse);
      expect(packets[5].data[1].physicalX, equals(10.0 * dpi));
      expect(packets[5].data[1].physicalY, equals(10.0 * dpi));
      expect(packets[5].data[1].physicalDeltaX, equals(0.0));
      expect(packets[5].data[1].physicalDeltaY, equals(0.0));
      expect(packets[5].data[1].scrollDeltaX, equals(0.0));
      expect(packets[5].data[1].scrollDeltaY, equals(-120.0));

      // Because the delta is not in increments of 120 and has non-matching
      // wheelDelta, it will be a mouse event.
      expect(packets[6].data, hasLength(1));
      expect(packets[6].data[0].change, equals(ui.PointerChange.hover));
      expect(
          packets[6].data[0].signalKind, equals(ui.PointerSignalKind.scroll));
      expect(
          packets[6].data[0].kind, equals(ui.PointerDeviceKind.mouse));
      expect(packets[6].data[0].device, equals(-1));
      expect(packets[6].data[0].pointerIdentifier, equals(0));
      expect(packets[6].data[0].synthesized, isFalse);
      expect(packets[6].data[0].physicalX, equals(10.0 * dpi));
      expect(packets[6].data[0].physicalY, equals(10.0 * dpi));
      expect(packets[6].data[0].physicalDeltaX, equals(0.0));
      expect(packets[6].data[0].physicalDeltaY, equals(0.0));
      expect(packets[6].data[0].scrollDeltaX, equals(0.0));
      expect(packets[6].data[0].scrollDeltaY, equals(40.0));
    },
  );

  _testEach<_ButtonedEventMixin>(
    <_ButtonedEventMixin>[
      if (!isIosSafari) _PointerEventContext(),
      if (!isIosSafari) _MouseEventContext(),
    ],
    'does choose scroll vs scale based on ctrlKey',
    (_ButtonedEventMixin context) {
      PointerBinding.instance!.debugOverrideDetector(context);
      final List<ui.PointerDataPacket> packets = <ui.PointerDataPacket>[];
      ui.window.onPointerDataPacket = (ui.PointerDataPacket packet) {
        packets.add(packet);
      };

      glassPane.dispatchEvent(context.wheel(
        buttons: 0,
        clientX: 10,
        clientY: 10,
        deltaX: 0,
        deltaY: 120,
      ));

      glassPane.dispatchEvent(context.wheel(
        buttons: 0,
        clientX: 10,
        clientY: 10,
        deltaX: 0,
        deltaY: 100,
        ctrlKey: true,
      ));

      debugOperatingSystemOverride = OperatingSystem.macOs;
      KeyboardBinding.instance?.converter.handleEvent(keyDownEvent('ControlLeft', 'Control', kCtrl));

      glassPane.dispatchEvent(context.wheel(
        buttons: 0,
        clientX: 10,
        clientY: 10,
        deltaX: 0,
        deltaY: 240,
        ctrlKey: true,
      ));

      KeyboardBinding.instance?.converter.handleEvent(keyUpEvent('ControlLeft', 'Control', kCtrl));

      expect(packets, hasLength(3));

      // An add will be synthesized.
      expect(packets[0].data, hasLength(2));
      expect(packets[0].data[0].change, equals(ui.PointerChange.add));
      expect(packets[0].data[0].pointerIdentifier, equals(0));
      expect(packets[0].data[0].synthesized, isTrue);
      expect(packets[0].data[0].physicalX, equals(10.0 * dpi));
      expect(packets[0].data[0].physicalY, equals(10.0 * dpi));
      expect(packets[0].data[0].physicalDeltaX, equals(0.0));
      expect(packets[0].data[0].physicalDeltaY, equals(0.0));
      // Because ctrlKey is not pressed, it will be a scroll.
      expect(packets[0].data[1].change, equals(ui.PointerChange.hover));
      expect(
          packets[0].data[1].signalKind, equals(ui.PointerSignalKind.scroll));
      expect(
          packets[0].data[1].kind, equals(ui.PointerDeviceKind.mouse));
      expect(packets[0].data[1].pointerIdentifier, equals(0));
      expect(packets[0].data[1].synthesized, isFalse);
      expect(packets[0].data[1].physicalX, equals(10.0 * dpi));
      expect(packets[0].data[1].physicalY, equals(10.0 * dpi));
      expect(packets[0].data[1].physicalDeltaX, equals(0.0));
      expect(packets[0].data[1].physicalDeltaY, equals(0.0));
      expect(packets[0].data[1].scrollDeltaX, equals(0.0));
      expect(packets[0].data[1].scrollDeltaY, equals(120.0));

      // Because ctrlKey is pressed, it will be a scale.
      expect(packets[1].data, hasLength(1));
      expect(packets[1].data[0].change, equals(ui.PointerChange.hover));
      expect(
          packets[1].data[0].signalKind, equals(ui.PointerSignalKind.scale));
      expect(
          packets[1].data[0].kind, equals(ui.PointerDeviceKind.mouse));
      expect(packets[1].data[0].pointerIdentifier, equals(0));
      expect(packets[1].data[0].synthesized, isFalse);
      expect(packets[1].data[0].physicalX, equals(10.0 * dpi));
      expect(packets[1].data[0].physicalY, equals(10.0 * dpi));
      expect(packets[1].data[0].physicalDeltaX, equals(0.0));
      expect(packets[1].data[0].physicalDeltaY, equals(0.0));
      expect(packets[1].data[0].scale, closeTo(0.60653065971, 1e-10)); // math.exp(-100/200)

      // [macOS only]: Because ctrlKey is true, but the key is pressed physically, it will be a scroll.
      expect(packets[2].data, hasLength(1));
      expect(packets[2].data[0].change, equals(ui.PointerChange.hover));
      expect(
          packets[2].data[0].signalKind, equals(ui.PointerSignalKind.scroll));
      expect(
          packets[2].data[0].kind, equals(ui.PointerDeviceKind.mouse));
      expect(packets[2].data[0].pointerIdentifier, equals(0));
      expect(packets[2].data[0].synthesized, isFalse);
      expect(packets[2].data[0].physicalX, equals(10.0 * dpi));
      expect(packets[2].data[0].physicalY, equals(10.0 * dpi));
      expect(packets[2].data[0].physicalDeltaX, equals(0.0));
      expect(packets[2].data[0].physicalDeltaY, equals(0.0));
      expect(packets[2].data[0].scrollDeltaX, equals(0.0));
      expect(packets[2].data[0].scrollDeltaY, equals(240.0));

      debugOperatingSystemOverride = null;
    },
  );

  _testEach<_ButtonedEventMixin>(
    <_ButtonedEventMixin>[
      if (!isIosSafari) _PointerEventContext(),
      if (!isIosSafari) _MouseEventContext()
    ],
    'does calculate delta and pointer identifier correctly',
    (_ButtonedEventMixin context) {
      PointerBinding.instance!.debugOverrideDetector(context);
      final List<ui.PointerDataPacket> packets = <ui.PointerDataPacket>[];
      ui.window.onPointerDataPacket = (ui.PointerDataPacket packet) {
        packets.add(packet);
      };

      glassPane.dispatchEvent(context.hover(
        clientX: 10.0,
        clientY: 10.0,
      ));
      expect(packets, hasLength(1));
      expect(packets[0].data, hasLength(2));
      expect(packets[0].data[0].change, equals(ui.PointerChange.add));
      expect(packets[0].data[0].pointerIdentifier, equals(0));
      expect(packets[0].data[0].synthesized, isTrue);
      expect(packets[0].data[0].physicalX, equals(10.0 * dpi));
      expect(packets[0].data[0].physicalY, equals(10.0 * dpi));
      expect(packets[0].data[0].physicalDeltaX, equals(0.0));
      expect(packets[0].data[0].physicalDeltaY, equals(0.0));

      expect(packets[0].data[1].change, equals(ui.PointerChange.hover));
      expect(packets[0].data[1].pointerIdentifier, equals(0));
      expect(packets[0].data[1].synthesized, isFalse);
      expect(packets[0].data[1].physicalX, equals(10.0 * dpi));
      expect(packets[0].data[1].physicalY, equals(10.0 * dpi));
      expect(packets[0].data[1].physicalDeltaX, equals(0.0));
      expect(packets[0].data[1].physicalDeltaY, equals(0.0));
      packets.clear();

      glassPane.dispatchEvent(context.hover(
        clientX: 20.0,
        clientY: 20.0,
      ));
      expect(packets, hasLength(1));
      expect(packets[0].data, hasLength(1));
      expect(packets[0].data[0].change, equals(ui.PointerChange.hover));
      expect(packets[0].data[0].pointerIdentifier, equals(0));
      expect(packets[0].data[0].synthesized, isFalse);
      expect(packets[0].data[0].physicalX, equals(20.0 * dpi));
      expect(packets[0].data[0].physicalY, equals(20.0 * dpi));
      expect(packets[0].data[0].physicalDeltaX, equals(10.0 * dpi));
      expect(packets[0].data[0].physicalDeltaY, equals(10.0 * dpi));
      packets.clear();

      glassPane.dispatchEvent(context.primaryDown(
        clientX: 20.0,
        clientY: 20.0,
      ));
      expect(packets, hasLength(1));
      expect(packets[0].data, hasLength(1));
      expect(packets[0].data[0].change, equals(ui.PointerChange.down));
      expect(packets[0].data[0].pointerIdentifier, equals(1));
      expect(packets[0].data[0].synthesized, isFalse);
      expect(packets[0].data[0].physicalX, equals(20.0 * dpi));
      expect(packets[0].data[0].physicalY, equals(20.0 * dpi));
      expect(packets[0].data[0].physicalDeltaX, equals(0.0));
      expect(packets[0].data[0].physicalDeltaY, equals(0.0));
      packets.clear();

      glassPane.dispatchEvent(context.primaryMove(
        clientX: 40.0,
        clientY: 30.0,
      ));
      expect(packets, hasLength(1));
      expect(packets[0].data, hasLength(1));
      expect(packets[0].data[0].change, equals(ui.PointerChange.move));
      expect(packets[0].data[0].pointerIdentifier, equals(1));
      expect(packets[0].data[0].synthesized, isFalse);
      expect(packets[0].data[0].physicalX, equals(40.0 * dpi));
      expect(packets[0].data[0].physicalY, equals(30.0 * dpi));
      expect(packets[0].data[0].physicalDeltaX, equals(20.0 * dpi));
      expect(packets[0].data[0].physicalDeltaY, equals(10.0 * dpi));
      packets.clear();

      glassPane.dispatchEvent(context.primaryUp(
        clientX: 40.0,
        clientY: 30.0,
      ));
      expect(packets, hasLength(1));
      expect(packets[0].data, hasLength(1));
      expect(packets[0].data[0].change, equals(ui.PointerChange.up));
      expect(packets[0].data[0].pointerIdentifier, equals(1));
      expect(packets[0].data[0].synthesized, isFalse);
      expect(packets[0].data[0].physicalX, equals(40.0 * dpi));
      expect(packets[0].data[0].physicalY, equals(30.0 * dpi));
      expect(packets[0].data[0].physicalDeltaX, equals(0.0));
      expect(packets[0].data[0].physicalDeltaY, equals(0.0));
      packets.clear();

      glassPane.dispatchEvent(context.hover(
        clientX: 20.0,
        clientY: 10.0,
      ));
      expect(packets, hasLength(1));
      expect(packets[0].data, hasLength(1));
      expect(packets[0].data[0].change, equals(ui.PointerChange.hover));
      expect(packets[0].data[0].pointerIdentifier, equals(1));
      expect(packets[0].data[0].synthesized, isFalse);
      expect(packets[0].data[0].physicalX, equals(20.0 * dpi));
      expect(packets[0].data[0].physicalY, equals(10.0 * dpi));
      expect(packets[0].data[0].physicalDeltaX, equals(-20.0 * dpi));
      expect(packets[0].data[0].physicalDeltaY, equals(-20.0 * dpi));
      packets.clear();

      glassPane.dispatchEvent(context.primaryDown(
        clientX: 20.0,
        clientY: 10.0,
      ));
      expect(packets, hasLength(1));
      expect(packets[0].data, hasLength(1));
      expect(packets[0].data[0].change, equals(ui.PointerChange.down));
      expect(packets[0].data[0].pointerIdentifier, equals(2));
      expect(packets[0].data[0].synthesized, isFalse);
      expect(packets[0].data[0].physicalX, equals(20.0 * dpi));
      expect(packets[0].data[0].physicalY, equals(10.0 * dpi));
      expect(packets[0].data[0].physicalDeltaX, equals(0.0));
      expect(packets[0].data[0].physicalDeltaY, equals(0.0));
      packets.clear();
    },
  );

  _testEach<_ButtonedEventMixin>(
    <_ButtonedEventMixin>[
      if (!isIosSafari) _PointerEventContext(),
      if (!isIosSafari) _MouseEventContext(),
    ],
    'correctly converts buttons of down, move, leave, and up events',
    (_ButtonedEventMixin context) {
      PointerBinding.instance!.debugOverrideDetector(context);
      final List<ui.PointerDataPacket> packets = <ui.PointerDataPacket>[];
      ui.window.onPointerDataPacket = (ui.PointerDataPacket packet) {
        packets.add(packet);
      };

      // Add and hover

      glassPane.dispatchEvent(context.hover(
        clientX: 10,
        clientY: 11,
      ));

      expect(packets, hasLength(1));
      expect(packets[0].data, hasLength(2));
      expect(packets[0].data[0].change, equals(ui.PointerChange.add));
      expect(packets[0].data[0].synthesized, isTrue);
      expect(packets[0].data[0].physicalX, equals(10 * dpi));
      expect(packets[0].data[0].physicalY, equals(11 * dpi));

      expect(packets[0].data[1].change, equals(ui.PointerChange.hover));
      expect(packets[0].data[1].synthesized, isFalse);
      expect(packets[0].data[1].physicalX, equals(10 * dpi));
      expect(packets[0].data[1].physicalY, equals(11 * dpi));
      expect(packets[0].data[1].buttons, equals(0));
      packets.clear();

      glassPane.dispatchEvent(context.mouseDown(
        button: 0,
        buttons: 1,
        clientX: 10.0,
        clientY: 11.0,
      ));
      expect(packets, hasLength(1));
      expect(packets[0].data, hasLength(1));
      expect(packets[0].data[0].change, equals(ui.PointerChange.down));
      expect(packets[0].data[0].synthesized, isFalse);
      expect(packets[0].data[0].physicalX, equals(10 * dpi));
      expect(packets[0].data[0].physicalY, equals(11 * dpi));
      expect(packets[0].data[0].buttons, equals(1));
      packets.clear();

      glassPane.dispatchEvent(context.mouseMove(
        button: _kNoButtonChange,
        buttons: 1,
        clientX: 20.0,
        clientY: 21.0,
      ));
      expect(packets, hasLength(1));
      expect(packets[0].data, hasLength(1));
      expect(packets[0].data[0].change, equals(ui.PointerChange.move));
      expect(packets[0].data[0].synthesized, isFalse);
      expect(packets[0].data[0].physicalX, equals(20 * dpi));
      expect(packets[0].data[0].physicalY, equals(21 * dpi));
      expect(packets[0].data[0].buttons, equals(1));
      packets.clear();

      glassPane.dispatchEvent(context.mouseUp(
        button: 0,
        clientX: 20.0,
        clientY: 21.0,
      ));
      expect(packets, hasLength(1));
      expect(packets[0].data, hasLength(1));
      expect(packets[0].data[0].change, equals(ui.PointerChange.up));
      expect(packets[0].data[0].synthesized, isFalse);
      expect(packets[0].data[0].physicalX, equals(20 * dpi));
      expect(packets[0].data[0].physicalY, equals(21 * dpi));
      expect(packets[0].data[0].buttons, equals(0));
      packets.clear();

      // Drag with secondary button
      glassPane.dispatchEvent(context.mouseDown(
        button: 2,
        buttons: 2,
        clientX: 20.0,
        clientY: 21.0,
      ));
      expect(packets, hasLength(1));
      expect(packets[0].data, hasLength(1));
      expect(packets[0].data[0].change, equals(ui.PointerChange.down));
      expect(packets[0].data[0].synthesized, isFalse);
      expect(packets[0].data[0].physicalX, equals(20 * dpi));
      expect(packets[0].data[0].physicalY, equals(21 * dpi));
      expect(packets[0].data[0].buttons, equals(2));
      packets.clear();

      glassPane.dispatchEvent(context.mouseMove(
        button: _kNoButtonChange,
        buttons: 2,
        clientX: 30.0,
        clientY: 31.0,
      ));
      expect(packets, hasLength(1));
      expect(packets[0].data, hasLength(1));
      expect(packets[0].data[0].change, equals(ui.PointerChange.move));
      expect(packets[0].data[0].synthesized, isFalse);
      expect(packets[0].data[0].physicalX, equals(30 * dpi));
      expect(packets[0].data[0].physicalY, equals(31 * dpi));
      expect(packets[0].data[0].buttons, equals(2));
      packets.clear();

      glassPane.dispatchEvent(context.mouseUp(
        button: 2,
        clientX: 30.0,
        clientY: 31.0,
      ));
      expect(packets, hasLength(1));
      expect(packets[0].data, hasLength(1));
      expect(packets[0].data[0].change, equals(ui.PointerChange.up));
      expect(packets[0].data[0].synthesized, isFalse);
      expect(packets[0].data[0].physicalX, equals(30 * dpi));
      expect(packets[0].data[0].physicalY, equals(31 * dpi));
      expect(packets[0].data[0].buttons, equals(0));
      packets.clear();

      // Drag with middle button
      glassPane.dispatchEvent(context.mouseDown(
        button: 1,
        buttons: 4,
        clientX: 30.0,
        clientY: 31.0,
      ));
      expect(packets, hasLength(1));
      expect(packets[0].data, hasLength(1));
      expect(packets[0].data[0].change, equals(ui.PointerChange.down));
      expect(packets[0].data[0].synthesized, isFalse);
      expect(packets[0].data[0].physicalX, equals(30 * dpi));
      expect(packets[0].data[0].physicalY, equals(31 * dpi));
      expect(packets[0].data[0].buttons, equals(4));
      packets.clear();

      glassPane.dispatchEvent(context.mouseMove(
        button: _kNoButtonChange,
        buttons: 4,
        clientX: 40.0,
        clientY: 41.0,
      ));
      expect(packets, hasLength(1));
      expect(packets[0].data, hasLength(1));
      expect(packets[0].data[0].change, equals(ui.PointerChange.move));
      expect(packets[0].data[0].synthesized, isFalse);
      expect(packets[0].data[0].physicalX, equals(40 * dpi));
      expect(packets[0].data[0].physicalY, equals(41 * dpi));
      expect(packets[0].data[0].buttons, equals(4));
      packets.clear();

      glassPane.dispatchEvent(context.mouseUp(
        button: 1,
        clientX: 40.0,
        clientY: 41.0,
      ));
      expect(packets, hasLength(1));
      expect(packets[0].data, hasLength(1));
      expect(packets[0].data[0].change, equals(ui.PointerChange.up));
      expect(packets[0].data[0].synthesized, isFalse);
      expect(packets[0].data[0].physicalX, equals(40 * dpi));
      expect(packets[0].data[0].physicalY, equals(41 * dpi));
      expect(packets[0].data[0].buttons, equals(0));
      packets.clear();

      // Leave

      glassPane.dispatchEvent(context.mouseLeave(
        buttons: 1,
        clientX: 1000.0,
        clientY: 2000.0,
      ));
      expect(packets, isEmpty);
      packets.clear();

      glassPane.dispatchEvent(context.mouseLeave(
        buttons: 0,
        clientX: 1000.0,
        clientY: 2000.0,
      ));
      expect(packets, hasLength(1));
      expect(packets[0].data, hasLength(1));
      expect(packets[0].data[0].change, equals(ui.PointerChange.hover));
      expect(packets[0].data[0].synthesized, isFalse);
      expect(packets[0].data[0].physicalX, equals(1000 * dpi));
      expect(packets[0].data[0].physicalY, equals(2000 * dpi));
      expect(packets[0].data[0].buttons, equals(0));
      packets.clear();
    },
  );

  _testEach<_ButtonedEventMixin>(
    <_ButtonedEventMixin>[
      _PointerEventContext(),
      _MouseEventContext(),
    ],
    'correctly handles button changes during a down sequence',
    (_ButtonedEventMixin context) {
      PointerBinding.instance!.debugOverrideDetector(context);
      final List<ui.PointerDataPacket> packets = <ui.PointerDataPacket>[];
      ui.window.onPointerDataPacket = (ui.PointerDataPacket packet) {
        packets.add(packet);
      };

      // Press LMB.
      glassPane.dispatchEvent(context.mouseDown(
        button: 0,
        buttons: 1,
      ));
      expect(packets, hasLength(1));
      expect(packets[0].data, hasLength(2));
      expect(packets[0].data[0].change, equals(ui.PointerChange.add));
      expect(packets[0].data[0].synthesized, isTrue);

      expect(packets[0].data[1].change, equals(ui.PointerChange.down));
      expect(packets[0].data[1].synthesized, isFalse);
      expect(packets[0].data[1].buttons, equals(1));
      packets.clear();

      // Press MMB.
      glassPane.dispatchEvent(context.mouseMove(
        button: 1,
        buttons: 5,
      ));
      expect(packets, hasLength(1));
      expect(packets[0].data, hasLength(1));
      expect(packets[0].data[0].change, equals(ui.PointerChange.move));
      expect(packets[0].data[0].synthesized, isFalse);
      expect(packets[0].data[0].buttons, equals(5));
      packets.clear();

      // Release LMB.
      glassPane.dispatchEvent(context.mouseMove(
        button: 0,
        buttons: 4,
      ));
      expect(packets, hasLength(1));
      expect(packets[0].data, hasLength(1));
      expect(packets[0].data[0].change, equals(ui.PointerChange.move));
      expect(packets[0].data[0].synthesized, isFalse);
      expect(packets[0].data[0].buttons, equals(4));
      packets.clear();

      // Release MMB.
      glassPane.dispatchEvent(context.mouseUp(
        button: 1,
      ));
      expect(packets, hasLength(1));
      expect(packets[0].data, hasLength(1));
      expect(packets[0].data[0].change, equals(ui.PointerChange.up));
      expect(packets[0].data[0].synthesized, isFalse);
      expect(packets[0].data[0].buttons, equals(0));
      packets.clear();
    },
  );

  _testEach<_ButtonedEventMixin>(
    <_ButtonedEventMixin>[
      if (!isIosSafari) _PointerEventContext(),
      if (!isIosSafari) _MouseEventContext(),
    ],
    'synthesizes a pointerup event when pointermove comes before the up',
    (_ButtonedEventMixin context) {
      PointerBinding.instance!.debugOverrideDetector(context);
      // This can happen when the user pops up the context menu by right
      // clicking, then dismisses it with a left click.

      final List<ui.PointerDataPacket> packets = <ui.PointerDataPacket>[];
      ui.window.onPointerDataPacket = (ui.PointerDataPacket packet) {
        packets.add(packet);
      };

      glassPane.dispatchEvent(context.mouseDown(
        button: 2,
        buttons: 2,
        clientX: 10,
        clientY: 11,
      ));

      expect(packets, hasLength(1));
      expect(packets[0].data, hasLength(2));
      expect(packets[0].data[0].change, equals(ui.PointerChange.add));
      expect(packets[0].data[0].synthesized, isTrue);
      expect(packets[0].data[0].physicalX, equals(10 * dpi));
      expect(packets[0].data[0].physicalY, equals(11 * dpi));

      expect(packets[0].data[1].change, equals(ui.PointerChange.down));
      expect(packets[0].data[1].synthesized, isFalse);
      expect(packets[0].data[1].physicalX, equals(10 * dpi));
      expect(packets[0].data[1].physicalY, equals(11 * dpi));
      expect(packets[0].data[1].buttons, equals(2));
      packets.clear();

      glassPane.dispatchEvent(context.mouseMove(
        button: _kNoButtonChange,
        buttons: 2,
        clientX: 20.0,
        clientY: 21.0,
      ));
      expect(packets, hasLength(1));
      expect(packets[0].data, hasLength(1));
      expect(packets[0].data[0].change, equals(ui.PointerChange.move));
      expect(packets[0].data[0].synthesized, isFalse);
      expect(packets[0].data[0].physicalX, equals(20 * dpi));
      expect(packets[0].data[0].physicalY, equals(21 * dpi));
      expect(packets[0].data[0].buttons, equals(2));
      packets.clear();

      glassPane.dispatchEvent(context.mouseMove(
        button: _kNoButtonChange,
        buttons: 2,
        clientX: 20.0,
        clientY: 21.0,
      ));
      expect(packets, hasLength(1));
      expect(packets[0].data, hasLength(1));
      expect(packets[0].data[0].change, equals(ui.PointerChange.move));
      expect(packets[0].data[0].synthesized, isFalse);
      expect(packets[0].data[0].physicalX, equals(20 * dpi));
      expect(packets[0].data[0].physicalY, equals(21 * dpi));
      expect(packets[0].data[0].buttons, equals(2));
      packets.clear();

      glassPane.dispatchEvent(context.mouseUp(
        button: 2,
        clientX: 20.0,
        clientY: 21.0,
      ));
      expect(packets, hasLength(1));
      expect(packets[0].data, hasLength(1));
      expect(packets[0].data[0].change, equals(ui.PointerChange.up));
      expect(packets[0].data[0].synthesized, isFalse);
      expect(packets[0].data[0].physicalX, equals(20 * dpi));
      expect(packets[0].data[0].physicalY, equals(21 * dpi));
      expect(packets[0].data[0].buttons, equals(0));
      packets.clear();
    },
  );

  _testEach<_ButtonedEventMixin>(
    <_ButtonedEventMixin>[
      _PointerEventContext(),
      _MouseEventContext(),
    ],
    'correctly handles uncontinuous button changes during a down sequence',
    (_ButtonedEventMixin context) {
      PointerBinding.instance!.debugOverrideDetector(context);
      // This can happen with the following gesture sequence:
      //
      //  - Pops up the context menu by right clicking, but holds RMB;
      //  - Clicks LMB;
      //  - Releases RMB.

      final List<ui.PointerDataPacket> packets = <ui.PointerDataPacket>[];
      ui.window.onPointerDataPacket = (ui.PointerDataPacket packet) {
        packets.add(packet);
      };

      // Press RMB and hold, popping up the context menu.
      glassPane.dispatchEvent(context.mouseDown(
        button: 2,
        buttons: 2,
      ));
      expect(packets, hasLength(1));
      expect(packets[0].data, hasLength(2));
      expect(packets[0].data[0].change, equals(ui.PointerChange.add));
      expect(packets[0].data[0].synthesized, isTrue);

      expect(packets[0].data[1].change, equals(ui.PointerChange.down));
      expect(packets[0].data[1].synthesized, isFalse);
      expect(packets[0].data[1].buttons, equals(2));
      packets.clear();

      // Press LMB. The event will have "button: -1" here, despite the change
      // in "buttons", probably because the "press" gesture was absorbed by
      // dismissing the context menu.
      glassPane.dispatchEvent(context.mouseMove(
        button: _kNoButtonChange,
        buttons: 3,
      ));
      expect(packets, hasLength(1));
      expect(packets[0].data, hasLength(1));
      expect(packets[0].data[0].change, equals(ui.PointerChange.move));
      expect(packets[0].data[0].synthesized, isFalse);
      expect(packets[0].data[0].buttons, equals(3));
      packets.clear();

      // Release LMB.
      glassPane.dispatchEvent(context.mouseMove(
        button: 0,
        buttons: 2,
      ));
      expect(packets, hasLength(1));
      expect(packets[0].data, hasLength(1));
      expect(packets[0].data[0].change, equals(ui.PointerChange.move));
      expect(packets[0].data[0].synthesized, isFalse);
      expect(packets[0].data[0].buttons, equals(2));
      packets.clear();

      // Release RMB.
      glassPane.dispatchEvent(context.mouseUp(
        button: 2,
      ));
      expect(packets, hasLength(1));
      expect(packets[0].data, hasLength(1));
      expect(packets[0].data[0].change, equals(ui.PointerChange.up));
      expect(packets[0].data[0].synthesized, isFalse);
      expect(packets[0].data[0].buttons, equals(0));
      packets.clear();
    },
  );

  _testEach<_ButtonedEventMixin>(
    <_ButtonedEventMixin>[
      _PointerEventContext(),
    ],
    'correctly handles missing right mouse button up when followed by move',
    (_ButtonedEventMixin context) {
      PointerBinding.instance!.debugOverrideDetector(context);
      // This can happen with the following gesture sequence:
      //
      //  - Pops up the context menu by right clicking;
      //  - Clicks LMB to close context menu.
      //  - Moves mouse.

      final List<ui.PointerDataPacket> packets = <ui.PointerDataPacket>[];
      ui.window.onPointerDataPacket = (ui.PointerDataPacket packet) {
        packets.add(packet);
      };

      // Press RMB popping up the context menu, then release by LMB down and up.
      // Browser won't send up event in that case.
      glassPane.dispatchEvent(context.mouseDown(
        button: 2,
        buttons: 2,
      ));
      expect(packets, hasLength(1));
      expect(packets[0].data, hasLength(2));
      expect(packets[0].data[0].change, equals(ui.PointerChange.add));
      expect(packets[0].data[0].synthesized, isTrue);

      expect(packets[0].data[1].change, equals(ui.PointerChange.down));
      expect(packets[0].data[1].synthesized, isFalse);
      expect(packets[0].data[1].buttons, equals(2));
      packets.clear();

      // User now hovers.
      glassPane.dispatchEvent(context.mouseMove(
        button: _kNoButtonChange,
        buttons: 0,
      ));
      expect(packets, hasLength(1));
      expect(packets[0].data, hasLength(2));
      expect(packets[0].data[0].change, equals(ui.PointerChange.up));
      expect(packets[0].data[0].synthesized, isFalse);
      expect(packets[0].data[0].buttons, equals(0));
      expect(packets[0].data[1].change, equals(ui.PointerChange.hover));
      expect(packets[0].data[1].synthesized, isFalse);
      expect(packets[0].data[1].buttons, equals(0));
      packets.clear();
    },
  );

  _testEach<_ButtonedEventMixin>(
    <_ButtonedEventMixin>[
      _PointerEventContext(),
      _MouseEventContext(),
    ],
    'handles RMB click when the browser sends it as a move',
    (_ButtonedEventMixin context) {
      PointerBinding.instance!.debugOverrideDetector(context);
      // When the user clicks the RMB and moves the mouse quickly (before the
      // context menu shows up), the browser sends a move event before down.
      // The move event will have "button:-1, buttons:2".

      final List<ui.PointerDataPacket> packets = <ui.PointerDataPacket>[];
      ui.window.onPointerDataPacket = (ui.PointerDataPacket packet) {
        packets.add(packet);
      };

      // Press RMB and hold, popping up the context menu.
      glassPane.dispatchEvent(context.mouseMove(
        button: -1,
        buttons: 2,
        clientX: 10.0,
        clientY: 10.0,
      ));
      expect(packets, hasLength(1));
      expect(packets[0].data, hasLength(2));
      expect(packets[0].data[0].change, equals(ui.PointerChange.add));
      expect(packets[0].data[0].synthesized, isTrue);

      expect(packets[0].data[1].change, equals(ui.PointerChange.hover));
      expect(packets[0].data[1].synthesized, isFalse);
      expect(packets[0].data[1].buttons, equals(0));
      packets.clear();
    },
  );

  _testEach<_ButtonedEventMixin>(
    <_ButtonedEventMixin>[
      _PointerEventContext(),
      _MouseEventContext(),
    ],
    'correctly handles hover after RMB click',
    (_ButtonedEventMixin context) {
      PointerBinding.instance!.debugOverrideDetector(context);
      // This can happen with the following gesture sequence:
      //
      //  - Pops up the context menu by right clicking, but holds RMB;
      //  - Move the pointer to hover.

      final List<ui.PointerDataPacket> packets = <ui.PointerDataPacket>[];
      ui.window.onPointerDataPacket = (ui.PointerDataPacket packet) {
        packets.add(packet);
      };

      // Press RMB and hold, popping up the context menu.
      glassPane.dispatchEvent(context.mouseDown(
        button: 2,
        buttons: 2,
        clientX: 10.0,
        clientY: 10.0,
      ));
      expect(packets, hasLength(1));
      expect(packets[0].data, hasLength(2));
      expect(packets[0].data[0].change, equals(ui.PointerChange.add));
      expect(packets[0].data[0].synthesized, isTrue);

      expect(packets[0].data[1].change, equals(ui.PointerChange.down));
      expect(packets[0].data[1].synthesized, isFalse);
      expect(packets[0].data[1].buttons, equals(2));
      packets.clear();

      // Move the mouse. The event will have "buttons: 0" because RMB was
      // released but the browser didn't send a pointerup/mouseup event.
      // The hover is also triggered at a different position.
      glassPane.dispatchEvent(context.hover(
        clientX: 20.0,
        clientY: 20.0,
      ));
      expect(packets, hasLength(1));
      expect(packets[0].data, hasLength(3));
      expect(packets[0].data[0].change, equals(ui.PointerChange.move));
      expect(packets[0].data[0].synthesized, isTrue);
      expect(packets[0].data[0].buttons, equals(2));
      expect(packets[0].data[1].change, equals(ui.PointerChange.up));
      expect(packets[0].data[1].synthesized, isFalse);
      expect(packets[0].data[1].buttons, equals(0));
      expect(packets[0].data[2].change, equals(ui.PointerChange.hover));
      expect(packets[0].data[2].synthesized, isFalse);
      expect(packets[0].data[2].buttons, equals(0));
      packets.clear();
    },
  );

  _testEach<_ButtonedEventMixin>(
    <_ButtonedEventMixin>[
      _PointerEventContext(),
      _MouseEventContext(),
    ],
    'correctly handles LMB click after RMB click',
    (_ButtonedEventMixin context) {
      PointerBinding.instance!.debugOverrideDetector(context);
      // This can happen with the following gesture sequence:
      //
      //  - Pops up the context menu by right clicking, but holds RMB;
      //  - Clicks LMB in a different location;
      //  - Release LMB.
      //
      // The LMB click occurs in a different location because when RMB is
      // clicked, and the contextmenu is shown, the browser stops sending
      // `pointermove`/`mousemove` events. Then when the LMB click comes in, it
      // could be in a different location without any `*move` events in between.

      final List<ui.PointerDataPacket> packets = <ui.PointerDataPacket>[];
      ui.window.onPointerDataPacket = (ui.PointerDataPacket packet) {
        packets.add(packet);
      };

      // Press RMB and hold, popping up the context menu.
      glassPane.dispatchEvent(context.mouseDown(
        button: 2,
        buttons: 2,
        clientX: 10.0,
        clientY: 10.0,
      ));
      expect(packets, hasLength(1));
      expect(packets[0].data, hasLength(2));
      expect(packets[0].data[0].change, equals(ui.PointerChange.add));
      expect(packets[0].data[0].synthesized, isTrue);

      expect(packets[0].data[1].change, equals(ui.PointerChange.down));
      expect(packets[0].data[1].synthesized, isFalse);
      expect(packets[0].data[1].buttons, equals(2));
      packets.clear();

      // Press LMB.
      glassPane.dispatchEvent(context.mouseDown(
        button: 0,
        buttons: 3,
        clientX: 20.0,
        clientY: 20.0,
      ));
      expect(packets, hasLength(1));
      expect(packets[0].data, hasLength(1));
      expect(packets[0].data[0].change, equals(ui.PointerChange.move));
      expect(packets[0].data[0].synthesized, isFalse);
      expect(packets[0].data[0].buttons, equals(3));
      packets.clear();

      // Release LMB.
      glassPane.dispatchEvent(context.primaryUp(
        clientX: 20.0,
        clientY: 20.0,
      ));
      expect(packets, hasLength(1));
      expect(packets[0].data, hasLength(1));
      expect(packets[0].data[0].change, equals(ui.PointerChange.up));
      expect(packets[0].data[0].synthesized, isFalse);
      expect(packets[0].data[0].buttons, equals(0));
      packets.clear();
    },
  );

  _testEach<_ButtonedEventMixin>(
    <_ButtonedEventMixin>[
      _PointerEventContext(),
      _MouseEventContext(),
    ],
    'correctly handles two consecutive RMB clicks with no up in between',
    (_ButtonedEventMixin context) {
      PointerBinding.instance!.debugOverrideDetector(context);
      // This can happen with the following gesture sequence:
      //
      //  - Pops up the context menu by right clicking, but holds RMB;
      //  - Clicks RMB again in a different location;

      final List<ui.PointerDataPacket> packets = <ui.PointerDataPacket>[];
      ui.window.onPointerDataPacket = (ui.PointerDataPacket packet) {
        packets.add(packet);
      };

      // Press RMB and hold, popping up the context menu.
      glassPane.dispatchEvent(context.mouseDown(
        button: 2,
        buttons: 2,
        clientX: 10.0,
        clientY: 10.0,
      ));
      expect(packets, hasLength(1));
      expect(packets[0].data, hasLength(2));
      expect(packets[0].data[0].change, equals(ui.PointerChange.add));
      expect(packets[0].data[0].synthesized, isTrue);
      expect(packets[0].data[1].change, equals(ui.PointerChange.down));
      expect(packets[0].data[1].synthesized, isFalse);
      expect(packets[0].data[1].buttons, equals(2));
      packets.clear();

      // Press RMB again. In Chrome, when RMB is clicked again while the
      // context menu is still active, it sends a pointerdown/mousedown event
      // with "buttons:0". We convert this to pointer up, pointer down.
      glassPane.dispatchEvent(context.mouseDown(
        button: 2,
        buttons: 0,
        clientX: 20.0,
        clientY: 20.0,
      ));
      expect(packets, hasLength(1));
      expect(packets[0].data, hasLength(3));
      expect(packets[0].data[0].change, equals(ui.PointerChange.move));
      expect(packets[0].data[0].synthesized, isTrue);
      expect(packets[0].data[0].buttons, equals(2));
      expect(packets[0].data[0].physicalX, equals(20.0 * dpi));
      expect(packets[0].data[0].physicalY, equals(20.0 * dpi));
      expect(packets[0].data[1].change, equals(ui.PointerChange.up));
      expect(packets[0].data[1].synthesized, isFalse);
      expect(packets[0].data[1].buttons, equals(0));
      expect(packets[0].data[2].change, equals(ui.PointerChange.down));
      expect(packets[0].data[2].synthesized, isFalse);
      expect(packets[0].data[2].buttons, equals(2));
      packets.clear();

      // Release RMB.
      glassPane.dispatchEvent(context.mouseUp(
        button: 2,
        clientX: 20.0,
        clientY: 20.0,
      ));
      expect(packets, hasLength(1));
      expect(packets[0].data, hasLength(1));
      expect(packets[0].data[0].change, equals(ui.PointerChange.up));
      expect(packets[0].data[0].synthesized, isFalse);
      expect(packets[0].data[0].buttons, equals(0));
      packets.clear();
    },
  );

  _testEach<_ButtonedEventMixin>(
    <_ButtonedEventMixin>[
      _PointerEventContext(),
      _MouseEventContext(),
    ],
    'correctly handles two consecutive RMB clicks with up in between',
    (_ButtonedEventMixin context) {
      PointerBinding.instance!.debugOverrideDetector(context);
      // This can happen with the following gesture sequence:
      //
      //  - Pops up the context menu by right clicking, but doesn't hold RMB;
      //  - Clicks RMB again in a different location;
      //
      // This seems to be happening sometimes when using RMB on the Mac trackpad.

      final List<ui.PointerDataPacket> packets = <ui.PointerDataPacket>[];
      ui.window.onPointerDataPacket = (ui.PointerDataPacket packet) {
        packets.add(packet);
      };

      // Press RMB, popping up the context menu.
      glassPane.dispatchEvent(context.mouseDown(
        button: 2,
        buttons: 2,
        clientX: 10.0,
        clientY: 10.0,
      ));
      expect(packets, hasLength(1));
      expect(packets[0].data, hasLength(2));
      expect(packets[0].data[0].change, equals(ui.PointerChange.add));
      expect(packets[0].data[0].synthesized, isTrue);
      expect(packets[0].data[1].change, equals(ui.PointerChange.down));
      expect(packets[0].data[1].synthesized, isFalse);
      expect(packets[0].data[1].buttons, equals(2));
      packets.clear();

      // RMB up.
      glassPane.dispatchEvent(context.mouseUp(
        button: 2,
        clientX: 10.0,
        clientY: 10.0,
      ));
      expect(packets, hasLength(1));
      expect(packets[0].data, hasLength(1));
      expect(packets[0].data[0].change, equals(ui.PointerChange.up));
      expect(packets[0].data[0].synthesized, isFalse);
      expect(packets[0].data[0].buttons, equals(0));
      packets.clear();

      // Press RMB again. In Chrome, when RMB is clicked again while the
      // context menu is still active, it sends a pointerdown/mousedown event
      // with "buttons:0".
      glassPane.dispatchEvent(context.mouseDown(
        button: 2,
        buttons: 0,
        clientX: 20.0,
        clientY: 20.0,
      ));
      expect(packets, hasLength(1));
      expect(packets[0].data, hasLength(2));
      expect(packets[0].data[0].change, equals(ui.PointerChange.hover));
      expect(packets[0].data[0].synthesized, isTrue);
      expect(packets[0].data[0].buttons, equals(0));
      expect(packets[0].data[1].change, equals(ui.PointerChange.down));
      expect(packets[0].data[1].synthesized, isFalse);
      expect(packets[0].data[1].buttons, equals(2));
      packets.clear();

      // Release RMB.
      glassPane.dispatchEvent(context.mouseUp(
        button: 2,
        clientX: 20.0,
        clientY: 20.0,
      ));
      expect(packets, hasLength(1));
      expect(packets[0].data, hasLength(1));
      expect(packets[0].data[0].change, equals(ui.PointerChange.up));
      expect(packets[0].data[0].synthesized, isFalse);
      expect(packets[0].data[0].buttons, equals(0));
      packets.clear();
    },
  );

  _testEach<_ButtonedEventMixin>(
    <_ButtonedEventMixin>[
      _PointerEventContext(),
      _MouseEventContext(),
    ],
    'correctly handles two consecutive RMB clicks in two different locations',
    (_ButtonedEventMixin context) {
      PointerBinding.instance!.debugOverrideDetector(context);
      // This can happen with the following gesture sequence:
      //
      //  - Pops up the context menu by right clicking;
      //  - The browser sends RMB up event;
      //  - Click RMB again in a different location;
      //
      // This scenario happens occasionally. I'm still not sure why, but in some
      // cases, the browser actually sends an `up` event for the RMB click even
      // when the context menu is shown.

      final List<ui.PointerDataPacket> packets = <ui.PointerDataPacket>[];
      ui.window.onPointerDataPacket = (ui.PointerDataPacket packet) {
        packets.add(packet);
      };

      // Press RMB and hold, popping up the context menu.
      glassPane.dispatchEvent(context.mouseDown(
        button: 2,
        buttons: 2,
        clientX: 10.0,
        clientY: 10.0,
      ));
      expect(packets, hasLength(1));
      expect(packets[0].data, hasLength(2));
      expect(packets[0].data[0].change, equals(ui.PointerChange.add));
      expect(packets[0].data[0].synthesized, isTrue);
      expect(packets[0].data[1].change, equals(ui.PointerChange.down));
      expect(packets[0].data[1].synthesized, isFalse);
      expect(packets[0].data[1].buttons, equals(2));
      packets.clear();

      // Release RMB.
      glassPane.dispatchEvent(context.mouseUp(
        button: 2,
        clientX: 10.0,
        clientY: 10.0,
      ));
      expect(packets, hasLength(1));
      expect(packets[0].data, hasLength(1));
      expect(packets[0].data[0].change, equals(ui.PointerChange.up));
      expect(packets[0].data[0].buttons, equals(0));
      packets.clear();

      // Press RMB again, in a different location.
      glassPane.dispatchEvent(context.mouseDown(
        button: 2,
        buttons: 2,
        clientX: 20.0,
        clientY: 20.0,
      ));
      expect(packets, hasLength(1));
      expect(packets[0].data, hasLength(2));
      expect(packets[0].data[0].change, equals(ui.PointerChange.hover));
      expect(packets[0].data[0].synthesized, isTrue);
      expect(packets[0].data[0].buttons, equals(0));
      expect(packets[0].data[1].change, equals(ui.PointerChange.down));
      expect(packets[0].data[1].synthesized, isFalse);
      expect(packets[0].data[1].buttons, equals(2));
      packets.clear();
    },
  );

  _testEach<_ButtonedEventMixin>(
    <_ButtonedEventMixin>[
      _PointerEventContext(),
      _MouseEventContext(),
    ],
    'handles overlapping left/right down and up events',
    (_ButtonedEventMixin context) {
      PointerBinding.instance!.debugOverrideDetector(context);
      // This can happen with the following gesture sequence:
      //
      //     LMB:   down-------------------up
      //     RMB:              down------------------up
      // Flutter:   down-------move-------move-------up

      final List<ui.PointerDataPacket> packets = <ui.PointerDataPacket>[];
      ui.window.onPointerDataPacket = (ui.PointerDataPacket packet) {
        packets.add(packet);
      };

      // Press and hold LMB.
      glassPane.dispatchEvent(context.mouseDown(
        button: 0,
        buttons: 1,
        clientX: 5.0,
        clientY: 100.0,
      ));
      expect(packets, hasLength(1));
      expect(packets[0].data, hasLength(2));
      expect(packets[0].data[0].change, equals(ui.PointerChange.add));
      expect(packets[0].data[0].synthesized, isTrue);
      expect(packets[0].data[1].change, equals(ui.PointerChange.down));
      expect(packets[0].data[1].synthesized, isFalse);
      expect(packets[0].data[1].buttons, equals(1));
      expect(packets[0].data[1].physicalX, equals(5.0 * dpi));
      expect(packets[0].data[1].physicalY, equals(100.0 * dpi));
      packets.clear();

      // Press and hold RMB. The pointer is already down, so we only send a move
      // to update the position of the pointer.
      glassPane.dispatchEvent(context.mouseDown(
        button: 2,
        buttons: 3,
        clientX: 20.0,
        clientY: 100.0,
      ));
      expect(packets, hasLength(1));
      expect(packets[0].data, hasLength(1));
      expect(packets[0].data[0].change, equals(ui.PointerChange.move));
      expect(packets[0].data[0].buttons, equals(3));
      expect(packets[0].data[0].physicalX, equals(20.0 * dpi));
      expect(packets[0].data[0].physicalY, equals(100.0 * dpi));
      packets.clear();

      // Release LMB. The pointer is still down (RMB), so we only send a move to
      // update the position of the pointer.
      glassPane.dispatchEvent(context.mouseUp(
        button: 0,
        buttons: 2,
        clientX: 30.0,
        clientY: 100.0,
      ));
      expect(packets, hasLength(1));
      expect(packets[0].data, hasLength(1));
      expect(packets[0].data[0].change, equals(ui.PointerChange.move));
      expect(packets[0].data[0].buttons, equals(2));
      expect(packets[0].data[0].physicalX, equals(30.0 * dpi));
      expect(packets[0].data[0].physicalY, equals(100.0 * dpi));
      packets.clear();

      // Release RMB. There's no more buttons down, so we send an up event.
      glassPane.dispatchEvent(context.mouseUp(
        button: 2,
        buttons: 0,
        clientX: 30.0,
        clientY: 100.0,
      ));
      expect(packets, hasLength(1));
      expect(packets[0].data, hasLength(1));
      expect(packets[0].data[0].change, equals(ui.PointerChange.up));
      expect(packets[0].data[0].buttons, equals(0));
      packets.clear();
    },
  );

  _testEach<_ButtonedEventMixin>(
    <_ButtonedEventMixin>[
      if (!isIosSafari) _PointerEventContext(),
      if (!isIosSafari) _MouseEventContext(),
    ],
    'correctly detects up event outside of glasspane',
    (_ButtonedEventMixin context) {
      PointerBinding.instance!.debugOverrideDetector(context);
      // This can happen when the up event occurs while the mouse is outside the
      // browser window.

      final List<ui.PointerDataPacket> packets = <ui.PointerDataPacket>[];
      ui.window.onPointerDataPacket = (ui.PointerDataPacket packet) {
        packets.add(packet);
      };

      // Press and drag around.
      glassPane.dispatchEvent(context.primaryDown(
        clientX: 10.0,
        clientY: 10.0,
      ));
      glassPane.dispatchEvent(context.primaryMove(
        clientX: 12.0,
        clientY: 10.0,
      ));
      glassPane.dispatchEvent(context.primaryMove(
        clientX: 15.0,
        clientY: 10.0,
      ));
      glassPane.dispatchEvent(context.primaryMove(
        clientX: 20.0,
        clientY: 10.0,
      ));
      packets.clear();

      // Move outside the glasspane.
      glassPane.dispatchEvent(context.primaryMove(
        clientX: 900.0,
        clientY: 1900.0,
      ));
      expect(packets, hasLength(1));
      expect(packets[0].data, hasLength(1));
      expect(packets[0].data[0].change, equals(ui.PointerChange.move));
      expect(packets[0].data[0].physicalX, equals(900.0 * dpi));
      expect(packets[0].data[0].physicalY, equals(1900.0 * dpi));
      packets.clear();

      // Release outside the glasspane.
      glassPane.dispatchEvent(context.primaryUp(
        clientX: 1000.0,
        clientY: 2000.0,
      ));
      expect(packets, hasLength(1));
      expect(packets[0].data, hasLength(2));
      expect(packets[0].data[0].change, equals(ui.PointerChange.move));
      expect(packets[0].data[0].physicalX, equals(1000.0 * dpi));
      expect(packets[0].data[0].physicalY, equals(2000.0 * dpi));
      expect(packets[0].data[1].change, equals(ui.PointerChange.up));
      expect(packets[0].data[1].physicalX, equals(1000.0 * dpi));
      expect(packets[0].data[1].physicalY, equals(2000.0 * dpi));
      packets.clear();
    },
  );

  // MULTIPOINTER ADAPTERS

  _testEach<_MultiPointerEventMixin>(
    <_MultiPointerEventMixin>[
      if (!isIosSafari) _PointerEventContext(),
      if (!isIosSafari) _TouchEventContext(),
    ],
    'treats each pointer separately',
    (_MultiPointerEventMixin context) {
      PointerBinding.instance!.debugOverrideDetector(context);
      final List<ui.PointerDataPacket> packets = <ui.PointerDataPacket>[];
      List<ui.PointerData> data;
      ui.window.onPointerDataPacket = (ui.PointerDataPacket packet) {
        packets.add(packet);
      };

      // Two pointers down
      context.multiTouchDown(const <_TouchDetails>[
        _TouchDetails(pointer: 2, clientX: 100, clientY: 101),
        _TouchDetails(pointer: 3, clientX: 200, clientY: 201),
      ]).forEach(glassPane.dispatchEvent);
      if (context.runtimeType == _PointerEventContext) {
        expect(packets.length, 2);
        expect(packets[0].data.length, 2);
        expect(packets[1].data.length, 2);
      } else if (context.runtimeType == _TouchEventContext) {
        expect(packets.length, 1);
        expect(packets[0].data.length, 4);
      } else {
        assert(false, 'Unexpected context type ${context.runtimeType}');
      }

      data = _allPointerData(packets);
      expect(data, hasLength(4));
      expect(data[0].change, equals(ui.PointerChange.add));
      expect(data[0].synthesized, isTrue);
      expect(data[0].device, equals(2));
      expect(data[0].physicalX, equals(100 * dpi));
      expect(data[0].physicalY, equals(101 * dpi));

      expect(data[1].change, equals(ui.PointerChange.down));
      expect(data[1].device, equals(2));
      expect(data[1].buttons, equals(1));
      expect(data[1].physicalX, equals(100 * dpi));
      expect(data[1].physicalY, equals(101 * dpi));
      expect(data[1].physicalDeltaX, equals(0));
      expect(data[1].physicalDeltaY, equals(0));

      expect(data[2].change, equals(ui.PointerChange.add));
      expect(data[2].synthesized, isTrue);
      expect(data[2].device, equals(3));
      expect(data[2].physicalX, equals(200 * dpi));
      expect(data[2].physicalY, equals(201 * dpi));

      expect(data[3].change, equals(ui.PointerChange.down));
      expect(data[3].device, equals(3));
      expect(data[3].buttons, equals(1));
      expect(data[3].physicalX, equals(200 * dpi));
      expect(data[3].physicalY, equals(201 * dpi));
      expect(data[3].physicalDeltaX, equals(0));
      expect(data[3].physicalDeltaY, equals(0));
      packets.clear();

      // Two pointers move
      context.multiTouchMove(const <_TouchDetails>[
        _TouchDetails(pointer: 3, clientX: 300, clientY: 302),
        _TouchDetails(pointer: 2, clientX: 400, clientY: 402),
      ]).forEach(glassPane.dispatchEvent);
      if (context.runtimeType == _PointerEventContext) {
        expect(packets.length, 2);
        expect(packets[0].data.length, 1);
        expect(packets[1].data.length, 1);
      } else if (context.runtimeType == _TouchEventContext) {
        expect(packets.length, 1);
        expect(packets[0].data.length, 2);
      } else {
        assert(false, 'Unexpected context type ${context.runtimeType}');
      }

      data = _allPointerData(packets);
      expect(data, hasLength(2));
      expect(data[0].change, equals(ui.PointerChange.move));
      expect(data[0].device, equals(3));
      expect(data[0].buttons, equals(1));
      expect(data[0].physicalX, equals(300 * dpi));
      expect(data[0].physicalY, equals(302 * dpi));
      expect(data[0].physicalDeltaX, equals(100 * dpi));
      expect(data[0].physicalDeltaY, equals(101 * dpi));

      expect(data[1].change, equals(ui.PointerChange.move));
      expect(data[1].device, equals(2));
      expect(data[1].buttons, equals(1));
      expect(data[1].physicalX, equals(400 * dpi));
      expect(data[1].physicalY, equals(402 * dpi));
      expect(data[1].physicalDeltaX, equals(300 * dpi));
      expect(data[1].physicalDeltaY, equals(301 * dpi));
      packets.clear();

      // One pointer up
      context.multiTouchUp(const <_TouchDetails>[
        _TouchDetails(pointer: 3, clientX: 300, clientY: 302),
      ]).forEach(glassPane.dispatchEvent);
      expect(packets, hasLength(1));
      expect(packets[0].data, hasLength(2));
      expect(packets[0].data[0].change, equals(ui.PointerChange.up));
      expect(packets[0].data[0].device, equals(3));
      expect(packets[0].data[0].buttons, equals(0));
      expect(packets[0].data[0].physicalX, equals(300 * dpi));
      expect(packets[0].data[0].physicalY, equals(302 * dpi));
      expect(packets[0].data[0].physicalDeltaX, equals(0));
      expect(packets[0].data[0].physicalDeltaY, equals(0));

      expect(packets[0].data[1].change, equals(ui.PointerChange.remove));
      expect(packets[0].data[1].device, equals(3));
      expect(packets[0].data[1].buttons, equals(0));
      expect(packets[0].data[1].physicalX, equals(300 * dpi));
      expect(packets[0].data[1].physicalY, equals(302 * dpi));
      expect(packets[0].data[1].physicalDeltaX, equals(0));
      expect(packets[0].data[1].physicalDeltaY, equals(0));
      packets.clear();

      // Another pointer up
      context.multiTouchUp(const <_TouchDetails>[
        _TouchDetails(pointer: 2, clientX: 400, clientY: 402),
      ]).forEach(glassPane.dispatchEvent);
      expect(packets, hasLength(1));
      expect(packets[0].data, hasLength(2));
      expect(packets[0].data[0].change, equals(ui.PointerChange.up));
      expect(packets[0].data[0].device, equals(2));
      expect(packets[0].data[0].buttons, equals(0));
      expect(packets[0].data[0].physicalX, equals(400 * dpi));
      expect(packets[0].data[0].physicalY, equals(402 * dpi));
      expect(packets[0].data[0].physicalDeltaX, equals(0));
      expect(packets[0].data[0].physicalDeltaY, equals(0));

      expect(packets[0].data[1].change, equals(ui.PointerChange.remove));
      expect(packets[0].data[1].device, equals(2));
      expect(packets[0].data[1].buttons, equals(0));
      expect(packets[0].data[1].physicalX, equals(400 * dpi));
      expect(packets[0].data[1].physicalY, equals(402 * dpi));
      expect(packets[0].data[1].physicalDeltaX, equals(0));
      expect(packets[0].data[1].physicalDeltaY, equals(0));
      packets.clear();

      // Again two pointers down (reuse pointer ID)
      context.multiTouchDown(const <_TouchDetails>[
        _TouchDetails(pointer: 3, clientX: 500, clientY: 501),
        _TouchDetails(pointer: 2, clientX: 600, clientY: 601),
      ]).forEach(glassPane.dispatchEvent);
      if (context.runtimeType == _PointerEventContext) {
        expect(packets.length, 2);
        expect(packets[0].data.length, 2);
        expect(packets[1].data.length, 2);
      } else if (context.runtimeType == _TouchEventContext) {
        expect(packets.length, 1);
        expect(packets[0].data.length, 4);
      } else {
        assert(false, 'Unexpected context type ${context.runtimeType}');
      }

      data = _allPointerData(packets);
      expect(data, hasLength(4));
      expect(data[0].change, equals(ui.PointerChange.add));
      expect(data[0].synthesized, isTrue);
      expect(data[0].device, equals(3));
      expect(data[0].physicalX, equals(500 * dpi));
      expect(data[0].physicalY, equals(501 * dpi));

      expect(data[1].change, equals(ui.PointerChange.down));
      expect(data[1].device, equals(3));
      expect(data[1].buttons, equals(1));
      expect(data[1].physicalX, equals(500 * dpi));
      expect(data[1].physicalY, equals(501 * dpi));
      expect(data[1].physicalDeltaX, equals(0));
      expect(data[1].physicalDeltaY, equals(0));

      expect(data[2].change, equals(ui.PointerChange.add));
      expect(data[2].synthesized, isTrue);
      expect(data[2].device, equals(2));
      expect(data[2].physicalX, equals(600 * dpi));
      expect(data[2].physicalY, equals(601 * dpi));

      expect(data[3].change, equals(ui.PointerChange.down));
      expect(data[3].device, equals(2));
      expect(data[3].buttons, equals(1));
      expect(data[3].physicalX, equals(600 * dpi));
      expect(data[3].physicalY, equals(601 * dpi));
      expect(data[3].physicalDeltaX, equals(0));
      expect(data[3].physicalDeltaY, equals(0));
      packets.clear();
    },
  );

  _testEach<_MultiPointerEventMixin>(
    <_MultiPointerEventMixin>[
      if (!isIosSafari) _PointerEventContext(),
      if (!isIosSafari) _TouchEventContext(),
    ],
    'correctly parses cancel event',
    (_MultiPointerEventMixin context) {
      PointerBinding.instance!.debugOverrideDetector(context);
      final List<ui.PointerDataPacket> packets = <ui.PointerDataPacket>[];
      ui.window.onPointerDataPacket = (ui.PointerDataPacket packet) {
        packets.add(packet);
      };

      // Two pointers down
      context.multiTouchDown(const <_TouchDetails>[
        _TouchDetails(pointer: 2, clientX: 100, clientY: 101),
        _TouchDetails(pointer: 3, clientX: 200, clientY: 201),
      ]).forEach(glassPane.dispatchEvent);
      packets.clear(); // Down event is tested in other tests.

      // One pointer cancel
      context.multiTouchCancel(const <_TouchDetails>[
        _TouchDetails(pointer: 3, clientX: 300, clientY: 302),
      ]).forEach(glassPane.dispatchEvent);
      expect(packets.length, 1);
      expect(packets[0].data.length, 2);
      expect(packets[0].data[0].change, equals(ui.PointerChange.cancel));
      expect(packets[0].data[0].device, equals(3));
      expect(packets[0].data[0].buttons, equals(0));
      expect(packets[0].data[0].physicalX, equals(200 * dpi));
      expect(packets[0].data[0].physicalY, equals(201 * dpi));
      expect(packets[0].data[0].physicalDeltaX, equals(0));
      expect(packets[0].data[0].physicalDeltaY, equals(0));

      expect(packets[0].data[1].change, equals(ui.PointerChange.remove));
      expect(packets[0].data[1].device, equals(3));
      expect(packets[0].data[1].buttons, equals(0));
      expect(packets[0].data[1].physicalX, equals(200 * dpi));
      expect(packets[0].data[1].physicalY, equals(201 * dpi));
      expect(packets[0].data[1].physicalDeltaX, equals(0));
      expect(packets[0].data[1].physicalDeltaY, equals(0));
      packets.clear();
    },
  );

  // POINTER ADAPTER

  _testEach<_PointerEventContext>(
    <_PointerEventContext>[
      if (!isIosSafari) _PointerEventContext(),
    ],
    'does not synthesize pointer up if from different device',
    (_PointerEventContext context) {
      PointerBinding.instance!.debugOverrideDetector(context);
      final List<ui.PointerDataPacket> packets = <ui.PointerDataPacket>[];
      ui.window.onPointerDataPacket = (ui.PointerDataPacket packet) {
        packets.add(packet);
      };

      context.multiTouchDown(const <_TouchDetails>[
        _TouchDetails(pointer: 1, clientX: 100, clientY: 101),
      ]).forEach(glassPane.dispatchEvent);
      expect(packets, hasLength(1));
      // An add will be synthesized.
      expect(packets[0].data, hasLength(2));
      expect(packets[0].data[0].change, equals(ui.PointerChange.add));
      expect(packets[0].data[0].synthesized, isTrue);
      expect(packets[0].data[0].device, equals(1));
      expect(packets[0].data[1].change, equals(ui.PointerChange.down));
      expect(packets[0].data[1].device, equals(1));
      packets.clear();

      context.multiTouchDown(const <_TouchDetails>[
        _TouchDetails(pointer: 2, clientX: 200, clientY: 202),
      ]).forEach(glassPane.dispatchEvent);
      // An add will be synthesized.
      expect(packets, hasLength(1));
      expect(packets[0].data, hasLength(2));
      expect(packets[0].data[0].change, equals(ui.PointerChange.add));
      expect(packets[0].data[0].synthesized, isTrue);
      expect(packets[0].data[0].device, equals(2));
      expect(packets[0].data[1].change, equals(ui.PointerChange.down));
      expect(packets[0].data[1].device, equals(2));
      packets.clear();
    },
  );

  _testEach<_PointerEventContext>(
    <_PointerEventContext>[
      if (!isIosSafari) _PointerEventContext(),
    ],
    'ignores pointer up or pointer cancel events for unknown device',
    (_PointerEventContext context) {
      PointerBinding.instance!.debugOverrideDetector(context);
      final List<ui.PointerDataPacket> packets = <ui.PointerDataPacket>[];
      ui.window.onPointerDataPacket = (ui.PointerDataPacket packet) {
        packets.add(packet);
      };

      context.multiTouchUp(const <_TouchDetails>[
        _TouchDetails(pointer: 23, clientX: 200, clientY: 202),
      ]).forEach(glassPane.dispatchEvent);
      expect(packets, hasLength(0));

      context.multiTouchCancel(const <_TouchDetails>[
        _TouchDetails(pointer: 24, clientX: 200, clientY: 202),
      ]).forEach(glassPane.dispatchEvent);
      expect(packets, hasLength(0));
    },
  );

  _testEach<_PointerEventContext>(
    <_PointerEventContext>[
      _PointerEventContext(),
    ],
    'handles random pointer id on up events',
    (_PointerEventContext context) {
      PointerBinding.instance!.debugOverrideDetector(context);
      // This happens with pens that are simulated with mouse events
      // (e.g. Wacom). It sends events with the pointer type "mouse", and
      // assigns a random pointer ID to each event.
      //
      // For more info, see: https://github.com/flutter/flutter/issues/75559

      final List<ui.PointerDataPacket> packets = <ui.PointerDataPacket>[];
      ui.window.onPointerDataPacket = (ui.PointerDataPacket packet) {
        packets.add(packet);
      };

      glassPane.dispatchEvent(context.mouseDown(
        pointerId: 12,
        button: 0,
        buttons: 1,
        clientX: 10.0,
        clientY: 10.0,
      ));

      expect(packets, hasLength(1));
      expect(packets.single.data, hasLength(2));

      expect(packets.single.data[0].change, equals(ui.PointerChange.add));
      expect(packets.single.data[0].synthesized, isTrue);
      expect(packets.single.data[1].change, equals(ui.PointerChange.down));
      packets.clear();

      expect(
        () {
          glassPane.dispatchEvent(context.mouseUp(
            pointerId: 41,
            button: 0,
            buttons: 0,
            clientX: 10.0,
            clientY: 10.0,
          ));
        },
        returnsNormally,
      );

      expect(packets, hasLength(1));
      expect(packets.single.data, hasLength(1));

      expect(packets.single.data[0].change, equals(ui.PointerChange.up));
    },
  );

  // TOUCH ADAPTER

  _testEach<_TouchEventContext>(
    <_TouchEventContext>[
      if (!isIosSafari) _TouchEventContext(),
    ],
    'does calculate delta and pointer identifier correctly',
    (_TouchEventContext context) {
      // Mouse and Pointer are in another test since these tests can involve hovering
      PointerBinding.instance!.debugOverrideDetector(context);
      final List<ui.PointerDataPacket> packets = <ui.PointerDataPacket>[];
      ui.window.onPointerDataPacket = (ui.PointerDataPacket packet) {
        packets.add(packet);
      };

      context.multiTouchDown(const <_TouchDetails>[
        _TouchDetails(pointer: 1, clientX: 20, clientY: 20),
      ]).forEach(glassPane.dispatchEvent);
      expect(packets, hasLength(1));
      expect(packets[0].data, hasLength(2));
      expect(packets[0].data[0].change, equals(ui.PointerChange.add));
      expect(packets[0].data[0].pointerIdentifier, equals(1));
      expect(packets[0].data[0].synthesized, isTrue);
      expect(packets[0].data[0].physicalX, equals(20.0 * dpi));
      expect(packets[0].data[0].physicalY, equals(20.0 * dpi));
      expect(packets[0].data[0].physicalDeltaX, equals(0.0));
      expect(packets[0].data[0].physicalDeltaY, equals(0.0));

      expect(packets[0].data[1].change, equals(ui.PointerChange.down));
      expect(packets[0].data[1].pointerIdentifier, equals(1));
      expect(packets[0].data[1].synthesized, isFalse);
      expect(packets[0].data[1].physicalX, equals(20.0 * dpi));
      expect(packets[0].data[1].physicalY, equals(20.0 * dpi));
      expect(packets[0].data[1].physicalDeltaX, equals(0.0));
      expect(packets[0].data[1].physicalDeltaY, equals(0.0));
      packets.clear();

      context.multiTouchMove(const <_TouchDetails>[
        _TouchDetails(pointer: 1, clientX: 40, clientY: 30),
      ]).forEach(glassPane.dispatchEvent);
      expect(packets, hasLength(1));
      expect(packets[0].data, hasLength(1));
      expect(packets[0].data[0].change, equals(ui.PointerChange.move));
      expect(packets[0].data[0].pointerIdentifier, equals(1));
      expect(packets[0].data[0].synthesized, isFalse);
      expect(packets[0].data[0].physicalX, equals(40.0 * dpi));
      expect(packets[0].data[0].physicalY, equals(30.0 * dpi));
      expect(packets[0].data[0].physicalDeltaX, equals(20.0 * dpi));
      expect(packets[0].data[0].physicalDeltaY, equals(10.0 * dpi));
      packets.clear();

      context.multiTouchUp(const <_TouchDetails>[
        _TouchDetails(pointer: 1, clientX: 40, clientY: 30),
      ]).forEach(glassPane.dispatchEvent);
      expect(packets, hasLength(1));
      expect(packets[0].data, hasLength(2));
      expect(packets[0].data[0].change, equals(ui.PointerChange.up));
      expect(packets[0].data[0].pointerIdentifier, equals(1));
      expect(packets[0].data[0].synthesized, isFalse);
      expect(packets[0].data[0].physicalX, equals(40.0 * dpi));
      expect(packets[0].data[0].physicalY, equals(30.0 * dpi));
      expect(packets[0].data[0].physicalDeltaX, equals(0.0));
      expect(packets[0].data[0].physicalDeltaY, equals(0.0));

      expect(packets[0].data[1].change, equals(ui.PointerChange.remove));
      expect(packets[0].data[1].pointerIdentifier, equals(1));
      expect(packets[0].data[1].synthesized, isTrue);
      expect(packets[0].data[1].physicalX, equals(40.0 * dpi));
      expect(packets[0].data[1].physicalY, equals(30.0 * dpi));
      expect(packets[0].data[1].physicalDeltaX, equals(0.0));
      expect(packets[0].data[1].physicalDeltaY, equals(0.0));
      packets.clear();

      context.multiTouchDown(const <_TouchDetails>[
        _TouchDetails(pointer: 2, clientX: 20, clientY: 10),
      ]).forEach(glassPane.dispatchEvent);
      expect(packets, hasLength(1));
      expect(packets[0].data, hasLength(2));
      expect(packets[0].data[0].change, equals(ui.PointerChange.add));
      expect(packets[0].data[0].pointerIdentifier, equals(2));
      expect(packets[0].data[0].synthesized, isTrue);
      expect(packets[0].data[0].physicalX, equals(20.0 * dpi));
      expect(packets[0].data[0].physicalY, equals(10.0 * dpi));
      expect(packets[0].data[0].physicalDeltaX, equals(0.0));
      expect(packets[0].data[0].physicalDeltaY, equals(0.0));

      expect(packets[0].data[1].change, equals(ui.PointerChange.down));
      expect(packets[0].data[1].pointerIdentifier, equals(2));
      expect(packets[0].data[1].synthesized, isFalse);
      expect(packets[0].data[1].physicalX, equals(20.0 * dpi));
      expect(packets[0].data[1].physicalY, equals(10.0 * dpi));
      expect(packets[0].data[1].physicalDeltaX, equals(0.0));
      expect(packets[0].data[1].physicalDeltaY, equals(0.0));
      packets.clear();
    },
  );
}

class MockSafariPointerEventWorkaround implements SafariPointerEventWorkaround {
  bool workAroundInvoked = false;

  @override
  void workAroundMissingPointerEvents() {
    workAroundInvoked = true;
  }
}

abstract class _BasicEventContext implements PointerSupportDetector {
  String get name;

  bool get isSupported;

  // Accepted modifier keys are 'Alt', 'Control', 'Meta' and 'Shift'.
  // https://www.w3.org/TR/uievents-key/#keys-modifier defines more modifiers,
  // but only the four main modifiers could be set from MouseEvent, PointerEvent
  // and TouchEvent constructors.
  bool altPressed = false;
  bool ctrlPressed = false;
  bool metaPressed = false;
  bool shiftPressed = false;

  // Generate an event that is:
  //
  //  * For mouse, a left click
  //  * For touch, a touch down
  DomEvent primaryDown({double clientX, double clientY});

  // Generate an event that is:
  //
  //  * For mouse, a drag with LMB down
  //  * For touch, a touch drag
  DomEvent primaryMove({double clientX, double clientY});

  // Generate an event that is:
  //
  //  * For mouse, release LMB
  //  * For touch, a touch up
  DomEvent primaryUp({double clientX, double clientY});

  void pressAllModifiers() {
    altPressed = true;
    ctrlPressed = true;
    metaPressed = true;
    shiftPressed = true;
  }

  void unpressAllModifiers() {
    altPressed = false;
    ctrlPressed = false;
    metaPressed = false;
    shiftPressed = false;
  }
}

mixin _ButtonedEventMixin on _BasicEventContext {
  // Generate an event that is a mouse down with the specific buttons.
  DomEvent mouseDown(
      {double? clientX, double? clientY, int? button, int? buttons});

  // Generate an event that is a mouse drag with the specific buttons, or button
  // changes during the drag.
  //
  // If there is no button change, assign `button` with _kNoButtonChange.
  DomEvent mouseMove(
      {double? clientX,
      double? clientY,
      required int button,
      required int buttons});

  // Generate an event that moves the mouse outside of the tracked area.
  DomEvent mouseLeave({double? clientX, double? clientY, required int buttons});

  // Generate an event that releases all mouse buttons.
  DomEvent mouseUp({double? clientX, double? clientY, int? button, int? buttons});

  DomEvent hover({double? clientX, double? clientY}) {
    return mouseMove(
      buttons: 0,
      button: _kNoButtonChange,
      clientX: clientX,
      clientY: clientY,
    );
  }

  @override
  DomEvent primaryDown({double? clientX, double? clientY}) {
    return mouseDown(
      buttons: 1,
      button: 0,
      clientX: clientX,
      clientY: clientY,
    );
  }

  @override
  DomEvent primaryMove({double? clientX, double? clientY}) {
    return mouseMove(
      buttons: 1,
      button: _kNoButtonChange,
      clientX: clientX,
      clientY: clientY,
    );
  }

  @override
  DomEvent primaryUp({double? clientX, double? clientY}) {
    return mouseUp(
      button: 0,
      clientX: clientX,
      clientY: clientY,
    );
  }

  DomEvent wheel({
    required int? buttons,
    required double? clientX,
    required double? clientY,
    required double? deltaX,
    required double? deltaY,
    double? wheelDeltaX,
    double? wheelDeltaY,
    int? timeStamp,
    bool ctrlKey = false,
  }) {
    final DomEvent event = createDomWheelEvent('wheel', <String, Object>{
        if (buttons != null) 'buttons': buttons,
        if (clientX != null) 'clientX': clientX,
        if (clientY != null) 'clientY': clientY,
        if (deltaX != null) 'deltaX': deltaX,
        if (deltaY != null) 'deltaY': deltaY,
        if (wheelDeltaX != null) 'wheelDeltaX': wheelDeltaX,
        if (wheelDeltaY != null) 'wheelDeltaY': wheelDeltaY,
        'ctrlKey': ctrlKey,
    });
    // timeStamp can't be set in the constructor, need to override the getter.
    if (timeStamp != null) {
      js_util.callMethod(
        objectConstructor,
        'defineProperty',
        <dynamic>[
          event,
          'timeStamp',
          js_util.jsify(<String, dynamic>{
            'value': timeStamp,
            'configurable': true
          })
        ]
      );
    }
    return event;
  }
}

class _TouchDetails {
  const _TouchDetails({this.pointer, this.clientX, this.clientY});

  final int? pointer;
  final double? clientX;
  final double? clientY;
}

mixin _MultiPointerEventMixin on _BasicEventContext {
  List<DomEvent> multiTouchDown(List<_TouchDetails> touches);
  List<DomEvent> multiTouchMove(List<_TouchDetails> touches);
  List<DomEvent> multiTouchUp(List<_TouchDetails> touches);
  List<DomEvent> multiTouchCancel(List<_TouchDetails> touches);

  @override
  DomEvent primaryDown({double? clientX, double? clientY}) {
    return multiTouchDown(<_TouchDetails>[
      _TouchDetails(
        pointer: 1,
        clientX: clientX,
        clientY: clientY,
      ),
    ])[0];
  }

  @override
  DomEvent primaryMove({double? clientX, double? clientY}) {
    return multiTouchMove(<_TouchDetails>[
      _TouchDetails(
        pointer: 1,
        clientX: clientX,
        clientY: clientY,
      ),
    ])[0];
  }

  @override
  DomEvent primaryUp({double? clientX, double? clientY}) {
    return multiTouchUp(<_TouchDetails>[
      _TouchDetails(
        pointer: 1,
        clientX: clientX,
        clientY: clientY,
      ),
    ])[0];
  }
}

// A test context for `_TouchAdapter`, including its name, PointerSupportDetector
// to override, and how to generate events.
class _TouchEventContext extends _BasicEventContext
    with _MultiPointerEventMixin
    implements PointerSupportDetector {
  _TouchEventContext() : _target = domDocument.createElement('div');

  @override
  String get name => 'TouchAdapter';

  @override
  bool get isSupported => _defaultSupportDetector.hasTouchEvents;

  @override
  bool get hasPointerEvents => false;

  @override
  bool get hasTouchEvents => true;

  @override
  bool get hasMouseEvents => false;

  final DomEventTarget _target;

  DomTouch _createTouch({
    int? identifier,
    double? clientX,
    double? clientY,
  }) {
    return createDomTouch(<String, dynamic>{
      'identifier': identifier,
      'clientX': clientX,
      'clientY': clientY,
      'target': _target,
    });
  }

  DomTouchEvent _createTouchEvent(
      String eventType, List<_TouchDetails> touches) {
    return createDomTouchEvent(
      eventType,
      <String, dynamic>{
        'changedTouches': touches
            .map(
              (_TouchDetails details) => _createTouch(
                identifier: details.pointer,
                clientX: details.clientX,
                clientY: details.clientY,
              ),
            )
            .toList(),
        'altKey': altPressed,
        'ctrlKey': ctrlPressed,
        'metaKey': metaPressed,
        'shiftKey': shiftPressed,
      },
    );
  }

  @override
  List<DomEvent> multiTouchDown(List<_TouchDetails> touches) {
    return <DomEvent>[_createTouchEvent('touchstart', touches)];
  }

  @override
  List<DomEvent> multiTouchMove(List<_TouchDetails> touches) {
    return <DomEvent>[_createTouchEvent('touchmove', touches)];
  }

  @override
  List<DomEvent> multiTouchUp(List<_TouchDetails> touches) {
    return <DomEvent>[_createTouchEvent('touchend', touches)];
  }

  @override
  List<DomEvent> multiTouchCancel(List<_TouchDetails> touches) {
    return <DomEvent>[_createTouchEvent('touchcancel', touches)];
  }
}

// A test context for `_MouseAdapter`, including its name, PointerSupportDetector
// to override, and how to generate events.
//
// For the difference between MouseEvent and PointerEvent, see _MouseAdapter.
class _MouseEventContext extends _BasicEventContext
    with _ButtonedEventMixin
    implements PointerSupportDetector {
  @override
  String get name => 'MouseAdapter';

  @override
  bool get isSupported => _defaultSupportDetector.hasMouseEvents;

  @override
  bool get hasPointerEvents => false;

  @override
  bool get hasTouchEvents => false;

  @override
  bool get hasMouseEvents => true;

  @override
  DomEvent mouseDown({
    double? clientX,
    double? clientY,
    int? button,
    int? buttons,
  }) {
    return _createMouseEvent(
      'mousedown',
      buttons: buttons,
      button: button,
      clientX: clientX,
      clientY: clientY,
    );
  }

  @override
  DomEvent mouseMove({
    double? clientX,
    double? clientY,
    required int button,
    required int buttons,
  }) {
    final bool hasButtonChange = button != _kNoButtonChange;
    final bool changeIsButtonDown =
        hasButtonChange && (buttons & convertButtonToButtons(button)) != 0;
    final String adjustedType = !hasButtonChange
        ? 'mousemove'
        : changeIsButtonDown
            ? 'mousedown'
            : 'mouseup';
    final int adjustedButton = hasButtonChange ? button : 0;
    return _createMouseEvent(
      adjustedType,
      buttons: buttons,
      button: adjustedButton,
      clientX: clientX,
      clientY: clientY,
    );
  }

  @override
  DomEvent mouseLeave({
    double? clientX,
    double? clientY,
    required int buttons,
  }) {
    return _createMouseEvent(
      'mouseleave',
      buttons: buttons,
      button: 0,
      clientX: clientX,
      clientY: clientY,
    );
  }

  @override
  DomEvent mouseUp({
    double? clientX,
    double? clientY,
    int? button,
    int? buttons,
  }) {
    return _createMouseEvent(
      'mouseup',
      buttons: buttons,
      button: button,
      clientX: clientX,
      clientY: clientY,
    );
  }

  DomMouseEvent _createMouseEvent(
    String type, {
    int? buttons,
    int? button,
    double? clientX,
    double? clientY,
  }) {
    return createDomMouseEvent(type, <String, Object>{
      if (buttons != null) 'buttons': buttons,
      if (button != null) 'button': button,
      if (clientX != null) 'clientX': clientX,
      if (clientY != null) 'clientY': clientY,
      'bubbles': true,
      'altKey': altPressed,
      'ctrlKey': ctrlPressed,
      'metaKey': metaPressed,
      'shiftKey': shiftPressed,
    });
  }
}

// A test context for `_PointerAdapter`, including its name, PointerSupportDetector
// to override, and how to generate events.
//
// For the difference between MouseEvent and PointerEvent, see _MouseAdapter.
class _PointerEventContext extends _BasicEventContext
    with _ButtonedEventMixin
    implements PointerSupportDetector, _MultiPointerEventMixin {
  @override
  String get name => 'PointerAdapter';

  @override
  bool get isSupported => _defaultSupportDetector.hasPointerEvents;

  @override
  bool get hasPointerEvents => true;

  @override
  bool get hasTouchEvents => false;

  @override
  bool get hasMouseEvents => false;

  @override
  List<DomEvent> multiTouchDown(List<_TouchDetails> touches) {
    return touches
        .map((_TouchDetails details) => _downWithFullDetails(
              pointer: details.pointer,
              buttons: 1,
              button: 0,
              clientX: details.clientX,
              clientY: details.clientY,
              pointerType: 'touch',
            ))
        .toList();
  }

  @override
  DomEvent mouseDown({
    double? clientX,
    double? clientY,
    int? button,
    int? buttons,
    int? pointerId = 1,
  }) {
    return _downWithFullDetails(
      pointer: pointerId,
      buttons: buttons,
      button: button,
      clientX: clientX,
      clientY: clientY,
      pointerType: 'mouse',
    );
  }

  DomEvent _downWithFullDetails({
    double? clientX,
    double? clientY,
    int? button,
    int? buttons,
    int? pointer,
    String? pointerType,
  }) {
    return createDomPointerEvent('pointerdown', <String, dynamic>{
      'pointerId': pointer,
      'button': button,
      'buttons': buttons,
      'clientX': clientX,
      'clientY': clientY,
      'pointerType': pointerType,
      'altKey': altPressed,
      'ctrlKey': ctrlPressed,
      'metaKey': metaPressed,
      'shiftKey': shiftPressed,
    });
  }

  @override
  List<DomEvent> multiTouchMove(List<_TouchDetails> touches) {
    return touches
        .map((_TouchDetails details) => _moveWithFullDetails(
              pointer: details.pointer,
              buttons: 1,
              button: _kNoButtonChange,
              clientX: details.clientX,
              clientY: details.clientY,
              pointerType: 'touch',
            ))
        .toList();
  }

  @override
  DomEvent mouseMove({
    double? clientX,
    double? clientY,
    required int button,
    required int buttons,
    int pointerId = 1,
  }) {
    return _moveWithFullDetails(
      pointer: pointerId,
      buttons: buttons,
      button: button,
      clientX: clientX,
      clientY: clientY,
      pointerType: 'mouse',
    );
  }

  DomEvent _moveWithFullDetails({
    double? clientX,
    double? clientY,
    int? button,
    int? buttons,
    int? pointer,
    String? pointerType,
  }) {
    return createDomPointerEvent('pointermove', <String, dynamic>{
      'pointerId': pointer,
      'button': button,
      'buttons': buttons,
      'clientX': clientX,
      'clientY': clientY,
      'pointerType': pointerType,
    });
  }

  @override
  DomEvent mouseLeave({
    double? clientX,
    double? clientY,
    required int buttons,
    int pointerId = 1,
  }) {
    return _leaveWithFullDetails(
      pointer: pointerId,
      buttons: buttons,
      button: 0,
      clientX: clientX,
      clientY: clientY,
      pointerType: 'mouse',
    );
  }

  DomEvent _leaveWithFullDetails({
    double? clientX,
    double? clientY,
    int? button,
    int? buttons,
    int? pointer,
    String? pointerType,
  }) {
    return createDomPointerEvent('pointerleave', <String, dynamic>{
      'pointerId': pointer,
      'button': button,
      'buttons': buttons,
      'clientX': clientX,
      'clientY': clientY,
      'pointerType': pointerType,
    });
  }

  @override
  List<DomEvent> multiTouchUp(List<_TouchDetails> touches) {
    return touches
        .map((_TouchDetails details) => _upWithFullDetails(
              pointer: details.pointer,
              button: 0,
              clientX: details.clientX,
              clientY: details.clientY,
              pointerType: 'touch',
            ))
        .toList();
  }

  @override
  DomEvent mouseUp({
    double? clientX,
    double? clientY,
    int? button,
    int? buttons,
    int? pointerId = 1,
  }) {
    return _upWithFullDetails(
      pointer: pointerId,
      button: button,
      buttons: buttons,
      clientX: clientX,
      clientY: clientY,
      pointerType: 'mouse',
    );
  }

  DomEvent _upWithFullDetails({
    double? clientX,
    double? clientY,
    int? button,
    int? buttons,
    int? pointer,
    String? pointerType,
  }) {
    return createDomPointerEvent('pointerup', <String, dynamic>{
      'bubbles': true,
      'pointerId': pointer,
      'button': button,
      'buttons': buttons,
      'clientX': clientX,
      'clientY': clientY,
      'pointerType': pointerType,
    });
  }

  @override
  List<DomEvent> multiTouchCancel(List<_TouchDetails> touches) {
    return touches
        .map((_TouchDetails details) =>
            createDomPointerEvent('pointercancel', <String, dynamic>{
              'pointerId': details.pointer,
              'button': 0,
              'buttons': 0,
              'clientX': 0,
              'clientY': 0,
              'pointerType': 'touch',
            }))
        .toList();
  }
}
