Unverified Commit 8ade81fb authored by Bruno Leroux's avatar Bruno Leroux Committed by GitHub

[flutter_test] Change KeyEventSimulator default transit mode (#143847)

## Description

This PRs changes the default value transit mode for key event simulation.

The default transit mode for key event simulation is currently `KeyDataTransitMode.rawKeyData` while on the framework side `KeyDataTransitMode.keyDataThenRawKeyData` is the preferred transit mode.

`KeyDataTransitMode.keyDataThenRawKeyData` is more accurate and can help detect issues.

For instance the following test will fail with `KeyDataTransitMode.rawKeyData` because raw keyboard logic for modifier keys is less accurate:

```dart
  testWidgets('Press control left once', (WidgetTester tester) async {
    debugKeyEventSimulatorTransitModeOverride = KeyDataTransitMode.keyDataThenRawKeyData;

    final List<KeyEvent> events = <KeyEvent>[];
    final FocusNode focusNode = FocusNode();
    addTearDown(focusNode.dispose);

    await tester.pumpWidget(
      Focus(
        focusNode: focusNode,
        autofocus: true,
        onKeyEvent: (_, KeyEvent event) {
          events.add(event);
          return KeyEventResult.handled;
        },
        child: Container(),
      ),
    );

    await simulateKeyDownEvent(LogicalKeyboardKey.controlLeft);

    // This will fail when transit mode is KeyDataTransitMode.rawKeyData
    // because a down event for controlRight is synthesized.
    expect(events.length, 1);

    debugKeyEventSimulatorTransitModeOverride = null;
  });
```

And the following this test is ok with `KeyDataTransitMode.rawKeyData` but rightly fails with `KeyDataTransitMode.keyDataThenRawKeyData`:

```dart
  testWidgets('Simulates consecutive key down events', (WidgetTester tester) async {
    debugKeyEventSimulatorTransitModeOverride = KeyDataTransitMode.rawKeyData;

    // Simulating several key down events without key up in between is tolerated
    // when transit mode is KeyDataTransitMode.rawKeyData, it will trigger an
    // assert on KeyDataTransitMode.keyDataThenRawKeyData.
    await simulateKeyDownEvent(LogicalKeyboardKey.arrowDown);
    await simulateKeyDownEvent(LogicalKeyboardKey.arrowDown);

    debugKeyEventSimulatorTransitModeOverride = null;
  });
```

## Related Issue

Related to https://github.com/flutter/flutter/issues/143845

## Tests

Adds two tests.
parent f6770276
...@@ -8507,14 +8507,12 @@ void main() { ...@@ -8507,14 +8507,12 @@ void main() {
expect(controller.selection.extentOffset, 20); expect(controller.selection.extentOffset, 20);
await tester.pump(kDoubleTapTimeout); await tester.pump(kDoubleTapTimeout);
await tester.sendKeyDownEvent(LogicalKeyboardKey.shift);
await tester.tapAt(textOffsetToPosition(tester, 23)); await tester.tapAt(textOffsetToPosition(tester, 23));
await tester.pumpAndSettle(); await tester.pumpAndSettle();
expect(controller.selection.baseOffset, 13); expect(controller.selection.baseOffset, 13);
expect(controller.selection.extentOffset, 23); expect(controller.selection.extentOffset, 23);
await tester.pump(kDoubleTapTimeout); await tester.pump(kDoubleTapTimeout);
await tester.sendKeyDownEvent(LogicalKeyboardKey.shift);
await tester.tapAt(textOffsetToPosition(tester, 4)); await tester.tapAt(textOffsetToPosition(tester, 4));
await tester.pumpAndSettle(); await tester.pumpAndSettle();
expect(controller.selection.baseOffset, 13); expect(controller.selection.baseOffset, 13);
......
...@@ -694,7 +694,7 @@ void main() { ...@@ -694,7 +694,7 @@ void main() {
await tester.tap(find.byType(DropdownMenu<TestMenu>)); await tester.tap(find.byType(DropdownMenu<TestMenu>));
await tester.pump(); await tester.pump();
await simulateKeyDownEvent(LogicalKeyboardKey.arrowDown); await tester.sendKeyEvent(LogicalKeyboardKey.arrowDown);
await tester.pumpAndSettle(); await tester.pumpAndSettle();
Finder button0Material = find.descendant( Finder button0Material = find.descendant(
of: find.widgetWithText(MenuItemButton, 'Item 0').last, of: find.widgetWithText(MenuItemButton, 'Item 0').last,
...@@ -705,7 +705,7 @@ void main() { ...@@ -705,7 +705,7 @@ void main() {
expect(item0material.color, themeData.colorScheme.onSurface.withOpacity(0.12)); expect(item0material.color, themeData.colorScheme.onSurface.withOpacity(0.12));
// Press down key one more time, the highlight should move to the next item. // Press down key one more time, the highlight should move to the next item.
await simulateKeyDownEvent(LogicalKeyboardKey.arrowDown); await tester.sendKeyEvent(LogicalKeyboardKey.arrowDown);
await tester.pumpAndSettle(); await tester.pumpAndSettle();
final Finder button1Material = find.descendant( final Finder button1Material = find.descendant(
of: find.widgetWithText(MenuItemButton, 'Menu 1').last, of: find.widgetWithText(MenuItemButton, 'Menu 1').last,
...@@ -735,7 +735,7 @@ void main() { ...@@ -735,7 +735,7 @@ void main() {
await tester.tap(find.byType(DropdownMenu<TestMenu>)); await tester.tap(find.byType(DropdownMenu<TestMenu>));
await tester.pump(); await tester.pump();
await simulateKeyDownEvent(LogicalKeyboardKey.arrowUp); await tester.sendKeyEvent(LogicalKeyboardKey.arrowUp);
await tester.pumpAndSettle(); await tester.pumpAndSettle();
Finder button5Material = find.descendant( Finder button5Material = find.descendant(
of: find.widgetWithText(MenuItemButton, 'Item 5').last, of: find.widgetWithText(MenuItemButton, 'Item 5').last,
...@@ -746,7 +746,7 @@ void main() { ...@@ -746,7 +746,7 @@ void main() {
expect(item5material.color, themeData.colorScheme.onSurface.withOpacity(0.12)); expect(item5material.color, themeData.colorScheme.onSurface.withOpacity(0.12));
// Press up key one more time, the highlight should move up to the item 4. // Press up key one more time, the highlight should move up to the item 4.
await simulateKeyDownEvent(LogicalKeyboardKey.arrowUp); await tester.sendKeyEvent(LogicalKeyboardKey.arrowUp);
await tester.pumpAndSettle(); await tester.pumpAndSettle();
final Finder button4Material = find.descendant( final Finder button4Material = find.descendant(
of: find.widgetWithText(MenuItemButton, 'Item 4').last, of: find.widgetWithText(MenuItemButton, 'Item 4').last,
...@@ -779,17 +779,17 @@ void main() { ...@@ -779,17 +779,17 @@ void main() {
await tester.tap(find.byType(DropdownMenu<TestMenu>)); await tester.tap(find.byType(DropdownMenu<TestMenu>));
await tester.pump(); await tester.pump();
await simulateKeyDownEvent(LogicalKeyboardKey.arrowDown); await tester.sendKeyEvent(LogicalKeyboardKey.arrowDown);
await tester.pump(); await tester.pump();
expect(find.widgetWithText(TextField, 'Item 0'), findsOneWidget); expect(find.widgetWithText(TextField, 'Item 0'), findsOneWidget);
// Press down key one more time to the next item. // Press down key one more time to the next item.
await simulateKeyDownEvent(LogicalKeyboardKey.arrowDown); await tester.sendKeyEvent(LogicalKeyboardKey.arrowDown);
await tester.pump(); await tester.pump();
expect(find.widgetWithText(TextField, 'Menu 1'), findsOneWidget); expect(find.widgetWithText(TextField, 'Menu 1'), findsOneWidget);
// Press down to the next item. // Press down to the next item.
await simulateKeyDownEvent(LogicalKeyboardKey.arrowDown); await tester.sendKeyEvent(LogicalKeyboardKey.arrowDown);
await tester.pump(); await tester.pump();
expect(find.widgetWithText(TextField, 'Item 2'), findsOneWidget); expect(find.widgetWithText(TextField, 'Item 2'), findsOneWidget);
}, variant: TargetPlatformVariant.desktop()); }, variant: TargetPlatformVariant.desktop());
...@@ -810,17 +810,17 @@ void main() { ...@@ -810,17 +810,17 @@ void main() {
await tester.tap(find.byType(DropdownMenu<TestMenu>)); await tester.tap(find.byType(DropdownMenu<TestMenu>));
await tester.pump(); await tester.pump();
await simulateKeyDownEvent(LogicalKeyboardKey.arrowUp); await tester.sendKeyEvent(LogicalKeyboardKey.arrowUp);
await tester.pump(); await tester.pump();
expect(find.widgetWithText(TextField, 'Item 5'), findsOneWidget); expect(find.widgetWithText(TextField, 'Item 5'), findsOneWidget);
// Press up key one more time to the upper item. // Press up key one more time to the upper item.
await simulateKeyDownEvent(LogicalKeyboardKey.arrowUp); await tester.sendKeyEvent(LogicalKeyboardKey.arrowUp);
await tester.pump(); await tester.pump();
expect(find.widgetWithText(TextField, 'Item 4'), findsOneWidget); expect(find.widgetWithText(TextField, 'Item 4'), findsOneWidget);
// Press up to the upper item. // Press up to the upper item.
await simulateKeyDownEvent(LogicalKeyboardKey.arrowUp); await tester.sendKeyEvent(LogicalKeyboardKey.arrowUp);
await tester.pump(); await tester.pump();
expect(find.widgetWithText(TextField, 'Item 3'), findsOneWidget); expect(find.widgetWithText(TextField, 'Item 3'), findsOneWidget);
}, variant: TargetPlatformVariant.desktop()); }, variant: TargetPlatformVariant.desktop());
...@@ -849,7 +849,7 @@ void main() { ...@@ -849,7 +849,7 @@ void main() {
await tester.tap(find.byType(DropdownMenu<TestMenu>)); await tester.tap(find.byType(DropdownMenu<TestMenu>));
await tester.pumpAndSettle(); await tester.pumpAndSettle();
await simulateKeyDownEvent(LogicalKeyboardKey.arrowDown); await tester.sendKeyEvent(LogicalKeyboardKey.arrowDown);
await tester.pumpAndSettle(); await tester.pumpAndSettle();
final Finder button0Material = find.descendant( final Finder button0Material = find.descendant(
of: find.widgetWithText(MenuItemButton, 'Item 0').last, of: find.widgetWithText(MenuItemButton, 'Item 0').last,
...@@ -859,7 +859,7 @@ void main() { ...@@ -859,7 +859,7 @@ void main() {
expect(item0Material.color, themeData.colorScheme.onSurface.withOpacity(0.12)); // first item can be highlighted as it's enabled. expect(item0Material.color, themeData.colorScheme.onSurface.withOpacity(0.12)); // first item can be highlighted as it's enabled.
// Continue to press down key. Item 3 should be highlighted as Menu 1 and Item 2 are both disabled. // Continue to press down key. Item 3 should be highlighted as Menu 1 and Item 2 are both disabled.
await simulateKeyDownEvent(LogicalKeyboardKey.arrowDown); await tester.sendKeyEvent(LogicalKeyboardKey.arrowDown);
await tester.pumpAndSettle(); await tester.pumpAndSettle();
final Finder button3Material = find.descendant( final Finder button3Material = find.descendant(
of: find.widgetWithText(MenuItemButton, 'Item 3').last, of: find.widgetWithText(MenuItemButton, 'Item 3').last,
...@@ -941,6 +941,7 @@ void main() { ...@@ -941,6 +941,7 @@ void main() {
// Press up to the upper item (Item 0). // Press up to the upper item (Item 0).
await simulateKeyDownEvent(LogicalKeyboardKey.arrowUp); await simulateKeyDownEvent(LogicalKeyboardKey.arrowUp);
await simulateKeyUpEvent(LogicalKeyboardKey.arrowUp);
await tester.pumpAndSettle(); await tester.pumpAndSettle();
expect(find.widgetWithText(TextField, 'Item 0'), findsOneWidget); expect(find.widgetWithText(TextField, 'Item 0'), findsOneWidget);
final Finder button0Material = find.descendant( final Finder button0Material = find.descendant(
...@@ -952,6 +953,7 @@ void main() { ...@@ -952,6 +953,7 @@ void main() {
// Continue to move up to the last item (Item 5). // Continue to move up to the last item (Item 5).
await simulateKeyDownEvent(LogicalKeyboardKey.arrowUp); await simulateKeyDownEvent(LogicalKeyboardKey.arrowUp);
await simulateKeyUpEvent(LogicalKeyboardKey.arrowUp);
await tester.pumpAndSettle(); await tester.pumpAndSettle();
expect(find.widgetWithText(TextField, 'Item 5'), findsOneWidget); expect(find.widgetWithText(TextField, 'Item 5'), findsOneWidget);
final Finder button5Material = find.descendant( final Finder button5Material = find.descendant(
......
...@@ -15933,14 +15933,12 @@ void main() { ...@@ -15933,14 +15933,12 @@ void main() {
expect(controller.selection.extentOffset, 20); expect(controller.selection.extentOffset, 20);
await tester.pump(kDoubleTapTimeout); await tester.pump(kDoubleTapTimeout);
await tester.sendKeyDownEvent(LogicalKeyboardKey.shift);
await tester.tapAt(textOffsetToPosition(tester, 23)); await tester.tapAt(textOffsetToPosition(tester, 23));
await tester.pumpAndSettle(); await tester.pumpAndSettle();
expect(controller.selection.baseOffset, 13); expect(controller.selection.baseOffset, 13);
expect(controller.selection.extentOffset, 23); expect(controller.selection.extentOffset, 23);
await tester.pump(kDoubleTapTimeout); await tester.pump(kDoubleTapTimeout);
await tester.sendKeyDownEvent(LogicalKeyboardKey.shift);
await tester.tapAt(textOffsetToPosition(tester, 4)); await tester.tapAt(textOffsetToPosition(tester, 4));
await tester.pumpAndSettle(); await tester.pumpAndSettle();
expect(controller.selection.baseOffset, 13); expect(controller.selection.baseOffset, 13);
......
...@@ -30,7 +30,7 @@ void main() { ...@@ -30,7 +30,7 @@ void main() {
await simulateKeyDownEvent(LogicalKeyboardKey.backquote, platform: platform); await simulateKeyDownEvent(LogicalKeyboardKey.backquote, platform: platform);
RawKeyboard.instance.removeListener(handleKey); RawKeyboard.instance.removeListener(handleKey);
} }
}); }, variant: KeySimulatorTransitModeVariant.rawKeyData());
testWidgets('No character is produced for non-printables', (WidgetTester tester) async { testWidgets('No character is produced for non-printables', (WidgetTester tester) async {
for (final String platform in <String>['linux', 'android', 'macos', 'fuchsia', 'windows', 'web', 'ios']) { for (final String platform in <String>['linux', 'android', 'macos', 'fuchsia', 'windows', 'web', 'ios']) {
...@@ -41,7 +41,7 @@ void main() { ...@@ -41,7 +41,7 @@ void main() {
await simulateKeyDownEvent(LogicalKeyboardKey.shiftLeft, platform: platform); await simulateKeyDownEvent(LogicalKeyboardKey.shiftLeft, platform: platform);
RawKeyboard.instance.removeListener(handleKey); RawKeyboard.instance.removeListener(handleKey);
} }
}); }, variant: KeySimulatorTransitModeVariant.rawKeyData());
testWidgets('keysPressed is maintained', (WidgetTester tester) async { testWidgets('keysPressed is maintained', (WidgetTester tester) async {
for (final String platform in <String>['linux', 'android', 'macos', 'fuchsia', 'windows', 'ios']) { for (final String platform in <String>['linux', 'android', 'macos', 'fuchsia', 'windows', 'ios']) {
...@@ -147,7 +147,10 @@ void main() { ...@@ -147,7 +147,10 @@ void main() {
expect(RawKeyboard.instance.keysPressed, isEmpty, reason: 'on $platform'); expect(RawKeyboard.instance.keysPressed, isEmpty, reason: 'on $platform');
} }
} }
}, skip: isBrowser); // https://github.com/flutter/flutter/issues/61021 },
variant: KeySimulatorTransitModeVariant.rawKeyData(),
skip: isBrowser, // https://github.com/flutter/flutter/issues/61021
);
testWidgets('keysPressed is correct when modifier is released before key', (WidgetTester tester) async { testWidgets('keysPressed is correct when modifier is released before key', (WidgetTester tester) async {
for (final String platform in <String>['linux', 'android', 'macos', 'fuchsia', 'windows', 'ios']) { for (final String platform in <String>['linux', 'android', 'macos', 'fuchsia', 'windows', 'ios']) {
...@@ -198,7 +201,10 @@ void main() { ...@@ -198,7 +201,10 @@ void main() {
await simulateKeyUpEvent(LogicalKeyboardKey.keyA, platform: platform, physicalKey: PhysicalKeyboardKey.keyA); await simulateKeyUpEvent(LogicalKeyboardKey.keyA, platform: platform, physicalKey: PhysicalKeyboardKey.keyA);
expect(RawKeyboard.instance.keysPressed, isEmpty, reason: 'on $platform'); expect(RawKeyboard.instance.keysPressed, isEmpty, reason: 'on $platform');
} }
}, skip: isBrowser); // https://github.com/flutter/flutter/issues/76741 },
variant: KeySimulatorTransitModeVariant.rawKeyData(),
skip: isBrowser, // https://github.com/flutter/flutter/issues/76741
);
testWidgets('keysPressed modifiers are synchronized with key events on macOS', (WidgetTester tester) async { testWidgets('keysPressed modifiers are synchronized with key events on macOS', (WidgetTester tester) async {
expect(RawKeyboard.instance.keysPressed, isEmpty); expect(RawKeyboard.instance.keysPressed, isEmpty);
...@@ -222,7 +228,10 @@ void main() { ...@@ -222,7 +228,10 @@ void main() {
<LogicalKeyboardKey>{LogicalKeyboardKey.shiftLeft, LogicalKeyboardKey.keyA}, <LogicalKeyboardKey>{LogicalKeyboardKey.shiftLeft, LogicalKeyboardKey.keyA},
), ),
); );
}, skip: isBrowser); // [intended] This is a macOS-specific test. },
variant: KeySimulatorTransitModeVariant.rawKeyData(),
skip: isBrowser, // [intended] This is a macOS-specific test.
);
testWidgets('keysPressed modifiers are synchronized with key events on iOS', (WidgetTester tester) async { testWidgets('keysPressed modifiers are synchronized with key events on iOS', (WidgetTester tester) async {
expect(RawKeyboard.instance.keysPressed, isEmpty); expect(RawKeyboard.instance.keysPressed, isEmpty);
...@@ -246,7 +255,10 @@ void main() { ...@@ -246,7 +255,10 @@ void main() {
<LogicalKeyboardKey>{LogicalKeyboardKey.shiftLeft, LogicalKeyboardKey.keyA}, <LogicalKeyboardKey>{LogicalKeyboardKey.shiftLeft, LogicalKeyboardKey.keyA},
), ),
); );
}, skip: isBrowser); // [intended] This is an iOS-specific test. },
variant: KeySimulatorTransitModeVariant.rawKeyData(),
skip: isBrowser, // [intended] This is a iOS-specific test.
);
testWidgets('keysPressed modifiers are synchronized with key events on Windows', (WidgetTester tester) async { testWidgets('keysPressed modifiers are synchronized with key events on Windows', (WidgetTester tester) async {
expect(RawKeyboard.instance.keysPressed, isEmpty); expect(RawKeyboard.instance.keysPressed, isEmpty);
...@@ -270,7 +282,10 @@ void main() { ...@@ -270,7 +282,10 @@ void main() {
<LogicalKeyboardKey>{LogicalKeyboardKey.shiftLeft, LogicalKeyboardKey.keyA}, <LogicalKeyboardKey>{LogicalKeyboardKey.shiftLeft, LogicalKeyboardKey.keyA},
), ),
); );
}, skip: isBrowser); // [intended] This is a Windows-specific test. },
variant: KeySimulatorTransitModeVariant.rawKeyData(),
skip: isBrowser, // [intended] This is a Windows-specific test.
);
testWidgets('keysPressed modifiers are synchronized with key events on android', (WidgetTester tester) async { testWidgets('keysPressed modifiers are synchronized with key events on android', (WidgetTester tester) async {
expect(RawKeyboard.instance.keysPressed, isEmpty); expect(RawKeyboard.instance.keysPressed, isEmpty);
...@@ -294,7 +309,10 @@ void main() { ...@@ -294,7 +309,10 @@ void main() {
<LogicalKeyboardKey>{LogicalKeyboardKey.shiftLeft, LogicalKeyboardKey.keyA}, <LogicalKeyboardKey>{LogicalKeyboardKey.shiftLeft, LogicalKeyboardKey.keyA},
), ),
); );
}, skip: isBrowser); // [intended] This is an Android-specific test. },
variant: KeySimulatorTransitModeVariant.rawKeyData(),
skip: isBrowser, // [intended] This is an Android-specific test.
);
testWidgets('keysPressed modifiers are synchronized with key events on fuchsia', (WidgetTester tester) async { testWidgets('keysPressed modifiers are synchronized with key events on fuchsia', (WidgetTester tester) async {
expect(RawKeyboard.instance.keysPressed, isEmpty); expect(RawKeyboard.instance.keysPressed, isEmpty);
...@@ -318,7 +336,10 @@ void main() { ...@@ -318,7 +336,10 @@ void main() {
<LogicalKeyboardKey>{LogicalKeyboardKey.shiftLeft, LogicalKeyboardKey.keyA}, <LogicalKeyboardKey>{LogicalKeyboardKey.shiftLeft, LogicalKeyboardKey.keyA},
), ),
); );
}, skip: isBrowser); // [intended] This is a Fuchsia-specific test. },
variant: KeySimulatorTransitModeVariant.rawKeyData(),
skip: isBrowser, // [intended] This is a Fuchsia-specific test.
);
testWidgets('keysPressed modifiers are synchronized with key events on Linux GLFW', (WidgetTester tester) async { testWidgets('keysPressed modifiers are synchronized with key events on Linux GLFW', (WidgetTester tester) async {
expect(RawKeyboard.instance.keysPressed, isEmpty); expect(RawKeyboard.instance.keysPressed, isEmpty);
...@@ -348,7 +369,10 @@ void main() { ...@@ -348,7 +369,10 @@ void main() {
}, },
), ),
); );
}, skip: isBrowser); // [intended] This is a GLFW-specific test. },
variant: KeySimulatorTransitModeVariant.rawKeyData(),
skip: isBrowser, // [intended] This is a GLFW-specific test.
);
Future<void> simulateGTKKeyEvent(bool keyDown, int scancode, int keycode, int modifiers) async { Future<void> simulateGTKKeyEvent(bool keyDown, int scancode, int keycode, int modifiers) async {
final Map<String, dynamic> data = <String, dynamic>{ final Map<String, dynamic> data = <String, dynamic>{
...@@ -397,7 +421,10 @@ void main() { ...@@ -397,7 +421,10 @@ void main() {
}, },
), ),
); );
}, skip: isBrowser); // [intended] This is a GTK-specific test. },
variant: KeySimulatorTransitModeVariant.rawKeyData(),
skip: isBrowser, // [intended] This is a GTK-specific test.
);
// Regression test for https://github.com/flutter/flutter/issues/114591 . // Regression test for https://github.com/flutter/flutter/issues/114591 .
// //
...@@ -414,7 +441,10 @@ void main() { ...@@ -414,7 +441,10 @@ void main() {
}, },
), ),
); );
}, skip: isBrowser); // [intended] This is a GTK-specific test. },
variant: KeySimulatorTransitModeVariant.rawKeyData(),
skip: isBrowser, // [intended] This is a GTK-specific test.
);
// Regression test for https://github.com/flutter/flutter/issues/114591 . // Regression test for https://github.com/flutter/flutter/issues/114591 .
// //
...@@ -447,7 +477,10 @@ void main() { ...@@ -447,7 +477,10 @@ void main() {
}, },
), ),
); );
}, skip: !isBrowser); // [intended] This is a Browser-specific test. },
variant: KeySimulatorTransitModeVariant.rawKeyData(),
skip: !isBrowser, // [intended] This is a Browser-specific test.
);
testWidgets('keysPressed modifiers are synchronized with key events on web', (WidgetTester tester) async { testWidgets('keysPressed modifiers are synchronized with key events on web', (WidgetTester tester) async {
expect(RawKeyboard.instance.keysPressed, isEmpty); expect(RawKeyboard.instance.keysPressed, isEmpty);
...@@ -572,7 +605,10 @@ void main() { ...@@ -572,7 +605,10 @@ void main() {
}, },
), ),
); );
}, skip: isBrowser); // [intended] This is an Android-specific test. },
variant: KeySimulatorTransitModeVariant.rawKeyData(),
skip: isBrowser, // [intended] This is a Android-specific test.
);
testWidgets('sided modifiers without a side set return all sides on macOS', (WidgetTester tester) async { testWidgets('sided modifiers without a side set return all sides on macOS', (WidgetTester tester) async {
expect(RawKeyboard.instance.keysPressed, isEmpty); expect(RawKeyboard.instance.keysPressed, isEmpty);
......
...@@ -684,7 +684,7 @@ abstract final class KeyEventSimulator { ...@@ -684,7 +684,7 @@ abstract final class KeyEventSimulator {
return result!; return result!;
} }
static const KeyDataTransitMode _defaultTransitMode = KeyDataTransitMode.rawKeyData; static const KeyDataTransitMode _defaultTransitMode = KeyDataTransitMode.keyDataThenRawKeyData;
// The simulation transit mode for [simulateKeyDownEvent], [simulateKeyUpEvent], // The simulation transit mode for [simulateKeyDownEvent], [simulateKeyUpEvent],
// and [simulateKeyRepeatEvent]. // and [simulateKeyRepeatEvent].
...@@ -693,8 +693,8 @@ abstract final class KeyEventSimulator { ...@@ -693,8 +693,8 @@ abstract final class KeyEventSimulator {
// and delivered. For detailed introduction, see [KeyDataTransitMode] and // and delivered. For detailed introduction, see [KeyDataTransitMode] and
// its values. // its values.
// //
// The `_transitMode` defaults to [KeyDataTransitMode.rawKeyEvent], and can be // The `_transitMode` defaults to [KeyDataTransitMode.keyDataThenRawKeyData], and can
// overridden with [debugKeyEventSimulatorTransitModeOverride]. In widget tests, it // be overridden with [debugKeyEventSimulatorTransitModeOverride]. In widget tests, it
// is often set with [KeySimulationModeVariant]. // is often set with [KeySimulationModeVariant].
static KeyDataTransitMode get _transitMode { static KeyDataTransitMode get _transitMode {
KeyDataTransitMode? result; KeyDataTransitMode? result;
...@@ -705,6 +705,12 @@ abstract final class KeyEventSimulator { ...@@ -705,6 +705,12 @@ abstract final class KeyEventSimulator {
return result ?? _defaultTransitMode; return result ?? _defaultTransitMode;
} }
/// Returns the transit mode that simulated key events are constructed
/// and delivered. For detailed introduction, see [KeyDataTransitMode]
/// and its values.
@visibleForTesting
static KeyDataTransitMode get transitMode => _transitMode;
static String get _defaultPlatform => kIsWeb ? 'web' : Platform.operatingSystem; static String get _defaultPlatform => kIsWeb ? 'web' : Platform.operatingSystem;
/// Simulates sending a hardware key down event. /// Simulates sending a hardware key down event.
...@@ -965,6 +971,15 @@ class KeySimulatorTransitModeVariant extends TestVariant<KeyDataTransitMode> { ...@@ -965,6 +971,15 @@ class KeySimulatorTransitModeVariant extends TestVariant<KeyDataTransitMode> {
KeySimulatorTransitModeVariant.keyDataThenRawKeyData() KeySimulatorTransitModeVariant.keyDataThenRawKeyData()
: this(<KeyDataTransitMode>{KeyDataTransitMode.keyDataThenRawKeyData}); : this(<KeyDataTransitMode>{KeyDataTransitMode.keyDataThenRawKeyData});
/// Creates a [KeySimulatorTransitModeVariant] that only contains
/// [KeyDataTransitMode.rawKeyData].
@Deprecated(
'No longer supported. Transit mode is always key data only. '
'This feature was deprecated after v3.18.0-2.0.pre.',
)
KeySimulatorTransitModeVariant.rawKeyData()
: this(<KeyDataTransitMode>{KeyDataTransitMode.rawKeyData});
@override @override
final Set<KeyDataTransitMode> values; final Set<KeyDataTransitMode> values;
......
...@@ -37,12 +37,25 @@ Future<void> _shouldThrow<T extends Error>(AsyncValueGetter<void> func) async { ...@@ -37,12 +37,25 @@ Future<void> _shouldThrow<T extends Error>(AsyncValueGetter<void> func) async {
} }
void main() { void main() {
testWidgets('default transit mode is keyDataThenRawKeyData', (WidgetTester tester) async {
expect(KeyEventSimulator.transitMode, KeyDataTransitMode.keyDataThenRawKeyData);
});
testWidgets('debugKeyEventSimulatorTransitModeOverride overrides default transit mode', (WidgetTester tester) async {
debugKeyEventSimulatorTransitModeOverride = KeyDataTransitMode.rawKeyData;
expect(KeyEventSimulator.transitMode, KeyDataTransitMode.rawKeyData);
// Unsetting debugKeyEventSimulatorTransitModeOverride can't be called in a
// tear down callback because TestWidgetsFlutterBinding._verifyInvariants
// is called before tear down callbacks.
debugKeyEventSimulatorTransitModeOverride = null;
});
testWidgets('simulates keyboard events (RawEvent)', (WidgetTester tester) async { testWidgets('simulates keyboard events (RawEvent)', (WidgetTester tester) async {
debugKeyEventSimulatorTransitModeOverride = KeyDataTransitMode.rawKeyData; debugKeyEventSimulatorTransitModeOverride = KeyDataTransitMode.rawKeyData;
final List<RawKeyEvent> events = <RawKeyEvent>[]; final List<RawKeyEvent> events = <RawKeyEvent>[];
final FocusNode focusNode = FocusNode(); final FocusNode focusNode = FocusNode();
addTearDown(focusNode.dispose);
await tester.pumpWidget( await tester.pumpWidget(
RawKeyboardListener( RawKeyboardListener(
...@@ -80,7 +93,6 @@ void main() { ...@@ -80,7 +93,6 @@ void main() {
} }
await tester.pumpWidget(Container()); await tester.pumpWidget(Container());
focusNode.dispose();
debugKeyEventSimulatorTransitModeOverride = null; debugKeyEventSimulatorTransitModeOverride = null;
}); });
...@@ -89,8 +101,8 @@ void main() { ...@@ -89,8 +101,8 @@ void main() {
debugKeyEventSimulatorTransitModeOverride = KeyDataTransitMode.keyDataThenRawKeyData; debugKeyEventSimulatorTransitModeOverride = KeyDataTransitMode.keyDataThenRawKeyData;
final List<KeyEvent> events = <KeyEvent>[]; final List<KeyEvent> events = <KeyEvent>[];
final FocusNode focusNode = FocusNode(); final FocusNode focusNode = FocusNode();
addTearDown(focusNode.dispose);
await tester.pumpWidget( await tester.pumpWidget(
KeyboardListener( KeyboardListener(
...@@ -243,7 +255,6 @@ void main() { ...@@ -243,7 +255,6 @@ void main() {
await tester.idle(); await tester.idle();
await tester.pumpWidget(Container()); await tester.pumpWidget(Container());
focusNode.dispose();
debugKeyEventSimulatorTransitModeOverride = null; debugKeyEventSimulatorTransitModeOverride = null;
}); });
...@@ -252,8 +263,9 @@ void main() { ...@@ -252,8 +263,9 @@ void main() {
debugKeyEventSimulatorTransitModeOverride = KeyDataTransitMode.rawKeyData; debugKeyEventSimulatorTransitModeOverride = KeyDataTransitMode.rawKeyData;
final List<Object> events = <Object>[]; final List<Object> events = <Object>[];
final FocusNode focusNode = FocusNode(); final FocusNode focusNode = FocusNode();
addTearDown(focusNode.dispose);
await tester.pumpWidget( await tester.pumpWidget(
Focus( Focus(
focusNode: focusNode, focusNode: focusNode,
...@@ -308,8 +320,9 @@ void main() { ...@@ -308,8 +320,9 @@ void main() {
debugKeyEventSimulatorTransitModeOverride = KeyDataTransitMode.keyDataThenRawKeyData; debugKeyEventSimulatorTransitModeOverride = KeyDataTransitMode.keyDataThenRawKeyData;
final List<Object> events = <Object>[]; final List<Object> events = <Object>[];
final FocusNode focusNode = FocusNode(); final FocusNode focusNode = FocusNode();
addTearDown(focusNode.dispose);
await tester.pumpWidget( await tester.pumpWidget(
Focus( Focus(
focusNode: focusNode, focusNode: focusNode,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment