// Copyright 2014 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_test/flutter_test.dart';

import 'clipboard_utils.dart';
import 'keyboard_utils.dart';

Iterable<SingleActivator> allModifierVariants(LogicalKeyboardKey trigger) {
  const Iterable<bool> trueFalse = <bool>[false, true];
  return trueFalse.expand((bool shift) {
    return trueFalse.expand((bool control) {
      return trueFalse.expand((bool alt) {
        return trueFalse.map((bool meta) => SingleActivator(trigger, shift: shift, control: control, alt: alt, meta: meta));
      });
    });
  });
}

void main() {
  TestWidgetsFlutterBinding.ensureInitialized();
  final MockClipboard mockClipboard = MockClipboard();

  setUp(() async {
    TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger.setMockMethodCallHandler(SystemChannels.platform, mockClipboard.handleMethodCall);
    await Clipboard.setData(const ClipboardData(text: 'empty'));
  });

  tearDown(() {
    TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger.setMockMethodCallHandler(SystemChannels.platform, null);
  });

  const String testText =
      'Now is the time for\n' // 20
      'all good people\n'     // 20 + 16 => 36
      'to come to the aid\n'  // 36 + 19 => 55
      'of their country.';    // 55 + 17 => 72
  const String testCluster = '👨‍👩‍👦👨‍👩‍👦👨‍👩‍👦'; // 8 * 3

  // Exactly 20 characters each line.
  const String testSoftwrapText =
      '0123456789ABCDEFGHIJ'
      '0123456789ABCDEFGHIJ'
      '0123456789ABCDEFGHIJ'
      '0123456789ABCDEFGHIJ';

  const String testVerticalText = '1\n2\n3\n4\n5\n6\n7\n8\n9';
  const String longText =
      'Lorem ipsum dolor sit amet, consectetur adipiscing elit, '
      'sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. '
      'Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris '
      'nisi ut aliquip ex ea commodo consequat. '
      'Lorem ipsum dolor sit amet, consectetur adipiscing elit, '
      'sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. '
      'Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris '
      'nisi ut aliquip ex ea commodo consequat. ';
  final TextEditingController controller = TextEditingController(text: testText);
  final ScrollController scrollController = ScrollController();

  final FocusNode focusNode = FocusNode();
  Widget buildEditableText({
    TextAlign textAlign = TextAlign.left,
    bool readOnly = false,
    bool obscured = false,
    TextStyle style = const TextStyle(fontSize: 10.0),
    bool enableInteractiveSelection = true
  }) {
    return MaterialApp(
      home: Align(
        alignment: Alignment.topLeft,
        child: SizedBox(
          // Softwrap at exactly 20 characters.
          width: 201,
          height: 200,
          child: EditableText(
            controller: controller,
            showSelectionHandles: true,
            autofocus: true,
            focusNode: focusNode,
            style: style,
            textScaleFactor: 1,
            // Avoid the cursor from taking up width.
            cursorWidth: 0,
            cursorColor: Colors.blue,
            backgroundCursorColor: Colors.grey,
            selectionControls: materialTextSelectionControls,
            keyboardType: TextInputType.text,
            maxLines: obscured ? 1 : null,
            readOnly: readOnly,
            textAlign: textAlign,
            obscureText: obscured,
            enableInteractiveSelection: enableInteractiveSelection,
            scrollController: scrollController
          ),
        ),
      ),
    );
  }

  group('Common text editing shortcuts: ',
    () {
      final TargetPlatformVariant allExceptApple = TargetPlatformVariant.all(excluding: <TargetPlatform>{TargetPlatform.macOS, TargetPlatform.iOS});

      group('backspace', () {
        const LogicalKeyboardKey trigger = LogicalKeyboardKey.backspace;

        testWidgets('backspace', (WidgetTester tester) async {
          controller.text = testText;
          // Move the selection to the beginning of the 2nd line (after the newline
          // character).
          controller.selection = const TextSelection.collapsed(
            offset: 20,
            affinity: TextAffinity.upstream,
          );

          await tester.pumpWidget(buildEditableText());
          await sendKeyCombination(tester, const SingleActivator(trigger));

          expect(
            controller.text,
            'Now is the time forall good people\n'
            'to come to the aid\n'
            'of their country.',
          );

          expect(
            controller.selection,
            const TextSelection.collapsed(offset: 19),
          );
        }, variant: TargetPlatformVariant.all(excluding: <TargetPlatform>{ TargetPlatform.iOS }));

        testWidgets('backspace readonly', (WidgetTester tester) async {
          controller.text = testText;
          controller.selection = const TextSelection.collapsed(
            offset: 20,
            affinity: TextAffinity.upstream,
          );

          await tester.pumpWidget(buildEditableText(readOnly: true));
          await sendKeyCombination(tester, const SingleActivator(trigger));

          expect(controller.text, testText);

          expect(
            controller.selection,
            const TextSelection.collapsed(offset: 20, affinity: TextAffinity.upstream),
          );
        }, variant: TargetPlatformVariant.all());

        testWidgets('backspace at start', (WidgetTester tester) async {
          controller.text = testText;
          controller.selection = const TextSelection.collapsed(
            offset: 0,
          );

          await tester.pumpWidget(buildEditableText());
          await sendKeyCombination(tester, const SingleActivator(trigger));

          expect(
            controller.text,
            'Now is the time for\n'
            'all good people\n'
            'to come to the aid\n'
            'of their country.',
          );

          expect(
            controller.selection,
            const TextSelection.collapsed(offset: 0),
          );
        }, variant: TargetPlatformVariant.all());

        testWidgets('backspace at end', (WidgetTester tester) async {
          controller.text = testText;
          controller.selection = const TextSelection.collapsed(
            offset: 72,
            affinity: TextAffinity.upstream,
          );

          await tester.pumpWidget(buildEditableText());
          await sendKeyCombination(tester, const SingleActivator(trigger));

          expect(
            controller.text,
            'Now is the time for\n'
            'all good people\n'
            'to come to the aid\n'
            'of their country',
          );

          expect(
            controller.selection,
            const TextSelection.collapsed(offset: 71),
          );
        }, variant: TargetPlatformVariant.all(excluding: <TargetPlatform>{ TargetPlatform.iOS }));

        testWidgets('backspace inside of a cluster', (WidgetTester tester) async {
          controller.text = testCluster;
          controller.selection = const TextSelection.collapsed(
            offset: 1,
            affinity: TextAffinity.upstream,
          );

          await tester.pumpWidget(buildEditableText());
          await sendKeyCombination(tester, const SingleActivator(trigger));

          expect(
            controller.text,
            '👨‍👩‍👦👨‍👩‍👦',
          );

          expect(
            controller.selection,
            const TextSelection.collapsed(offset: 0),
          );
        }, variant: TargetPlatformVariant.all(excluding: <TargetPlatform>{ TargetPlatform.iOS }));

        testWidgets('backspace at cluster boundary', (WidgetTester tester) async {
          controller.text = testCluster;
          controller.selection = const TextSelection.collapsed(
            offset: 8,
            affinity: TextAffinity.upstream,
          );

          await tester.pumpWidget(buildEditableText());
          await sendKeyCombination(tester, const SingleActivator(trigger));

          expect(
            controller.text,
            '👨‍👩‍👦👨‍👩‍👦',
          );

          expect(
            controller.selection,
            const TextSelection.collapsed(offset: 0),
          );
        }, variant: TargetPlatformVariant.all(excluding: <TargetPlatform>{ TargetPlatform.iOS }));
      });

      group('delete: ', () {
        const LogicalKeyboardKey trigger = LogicalKeyboardKey.delete;

        testWidgets('delete', (WidgetTester tester) async {
          controller.text = testText;
          // Move the selection to the beginning of the 2nd line (after the newline
          // character).
          controller.selection = const TextSelection.collapsed(
            offset: 20,
            affinity: TextAffinity.upstream,
          );

          await tester.pumpWidget(buildEditableText());
          await sendKeyCombination(tester, const SingleActivator(trigger));

          expect(
            controller.text,
            'Now is the time for\n'
            'll good people\n'
            'to come to the aid\n'
            'of their country.',
          );

          expect(
            controller.selection,
            const TextSelection.collapsed(offset: 20),
          );
        }, variant: TargetPlatformVariant.all(excluding: <TargetPlatform>{ TargetPlatform.iOS }));

        testWidgets('delete readonly', (WidgetTester tester) async {
          controller.text = testText;
          controller.selection = const TextSelection.collapsed(
            offset: 20,
            affinity: TextAffinity.upstream,
          );

          await tester.pumpWidget(buildEditableText(readOnly: true));
          await sendKeyCombination(tester, const SingleActivator(trigger));

          expect(controller.text, testText);

          expect(
            controller.selection,
            const TextSelection.collapsed(offset: 20, affinity: TextAffinity.upstream),
          );
        }, variant: TargetPlatformVariant.all(excluding: <TargetPlatform>{ TargetPlatform.iOS }));

        testWidgets('delete at start', (WidgetTester tester) async {
          controller.text = testText;
          controller.selection = const TextSelection.collapsed(
            offset: 0,
          );

          await tester.pumpWidget(buildEditableText());
          await sendKeyCombination(tester, const SingleActivator(trigger));

          expect(
            controller.text,
            'ow is the time for\n'
            'all good people\n'
            'to come to the aid\n'
            'of their country.',
          );

          expect(
            controller.selection,
            const TextSelection.collapsed(offset: 0),
          );
        }, variant: TargetPlatformVariant.all(excluding: <TargetPlatform>{ TargetPlatform.iOS }));

        testWidgets('delete at end', (WidgetTester tester) async {
          controller.text = testText;
          controller.selection = const TextSelection.collapsed(
            offset: 72,
            affinity: TextAffinity.upstream,
          );

          await tester.pumpWidget(buildEditableText());
          await sendKeyCombination(tester, const SingleActivator(trigger));

          expect(
            controller.text,
            'Now is the time for\n'
            'all good people\n'
            'to come to the aid\n'
            'of their country.',
          );

          expect(
            controller.selection,
            const TextSelection.collapsed(offset: 72, affinity: TextAffinity.upstream),
          );
        }, variant: TargetPlatformVariant.all());

        testWidgets('delete inside of a cluster', (WidgetTester tester) async {
          controller.text = testCluster;
          controller.selection = const TextSelection.collapsed(
            offset: 1,
            affinity: TextAffinity.upstream,
          );

          await tester.pumpWidget(buildEditableText());
          await sendKeyCombination(tester, const SingleActivator(trigger));

          expect(
            controller.text,
            '👨‍👩‍👦👨‍👩‍👦',
          );

          expect(
            controller.selection,
            const TextSelection.collapsed(offset: 0),
          );
        }, variant: TargetPlatformVariant.all(excluding: <TargetPlatform>{ TargetPlatform.iOS }));

        testWidgets('delete at cluster boundary', (WidgetTester tester) async {
          controller.text = testCluster;
          controller.selection = const TextSelection.collapsed(
            offset: 8,
            affinity: TextAffinity.upstream,
          );

          await tester.pumpWidget(buildEditableText());
          await sendKeyCombination(tester, const SingleActivator(trigger));

          expect(
            controller.text,
            '👨‍👩‍👦👨‍👩‍👦',
          );

          expect(
            controller.selection,
            const TextSelection.collapsed(offset: 8),
          );
        }, variant: TargetPlatformVariant.all(excluding: <TargetPlatform>{ TargetPlatform.iOS }));
      });

      group('Non-collapsed delete', () {
        // This shares the same logic as backspace.
        const LogicalKeyboardKey trigger = LogicalKeyboardKey.delete;

        testWidgets('inside of a cluster', (WidgetTester tester) async {
          controller.text = testCluster;
          controller.selection = const TextSelection(
            baseOffset: 9,
            extentOffset: 12,
          );

          await tester.pumpWidget(buildEditableText());
          await sendKeyCombination(tester, const SingleActivator(trigger));

          expect(
            controller.text,
            '👨‍👩‍👦👨‍👩‍👦',
          );

          expect(
            controller.selection,
            const TextSelection.collapsed(offset: 8),
          );
        }, variant: TargetPlatformVariant.all(excluding: <TargetPlatform>{ TargetPlatform.iOS }));

        testWidgets('at the boundaries of a cluster', (WidgetTester tester) async {
          controller.text = testCluster;
          controller.selection = const TextSelection(
            baseOffset: 8,
            extentOffset: 16,
          );

          await tester.pumpWidget(buildEditableText());
          await sendKeyCombination(tester, const SingleActivator(trigger));

          expect(
            controller.text,
            '👨‍👩‍👦👨‍👩‍👦',
          );

          expect(
            controller.selection,
            const TextSelection.collapsed(offset: 8),
          );
        }, variant: TargetPlatformVariant.all(excluding: <TargetPlatform>{ TargetPlatform.iOS }));

        testWidgets('cross-cluster', (WidgetTester tester) async {
          controller.text = testCluster;
          controller.selection = const TextSelection(
            baseOffset: 1,
            extentOffset: 9,
          );

          await tester.pumpWidget(buildEditableText());
          await sendKeyCombination(tester, const SingleActivator(trigger));

          expect(
            controller.text,
            '👨‍👩‍👦',
          );

          expect(
            controller.selection,
            const TextSelection.collapsed(offset: 0),
          );
        }, variant: TargetPlatformVariant.all(excluding: <TargetPlatform>{ TargetPlatform.iOS }));

        testWidgets('cross-cluster obscured text', (WidgetTester tester) async {
          controller.text = testCluster;
          controller.selection = const TextSelection(
            baseOffset: 1,
            extentOffset: 9,
          );

          await tester.pumpWidget(buildEditableText(obscured: true));
          await sendKeyCombination(tester, const SingleActivator(trigger));

          // Both emojis that were partially selected are deleted entirely.
          expect(
            controller.text,
            '‍👩‍👦👨‍👩‍👦',
          );

          expect(
            controller.selection,
            const TextSelection.collapsed(offset: 0),
          );
        }, variant: TargetPlatformVariant.all(excluding: <TargetPlatform>{ TargetPlatform.iOS }));
      });

      group('word modifier + backspace', () {
        const LogicalKeyboardKey trigger = LogicalKeyboardKey.backspace;
        SingleActivator wordModifierBackspace() {
          final bool isApple = defaultTargetPlatform == TargetPlatform.macOS || defaultTargetPlatform == TargetPlatform.iOS;
          return SingleActivator(trigger, control: !isApple, alt: isApple);
        }

        testWidgets('WordModifier-backspace', (WidgetTester tester) async {
          controller.text = testText;
          // Place the caret before "people".
          controller.selection = const TextSelection.collapsed(
            offset: 29,
            affinity: TextAffinity.upstream,
          );

          await tester.pumpWidget(buildEditableText());
          await sendKeyCombination(tester, wordModifierBackspace());

          expect(
            controller.text,
            'Now is the time for\n'
            'all people\n'
            'to come to the aid\n'
            'of their country.',
          );

          expect(
            controller.selection,
            const TextSelection.collapsed(offset: 24),
          );
        }, variant: TargetPlatformVariant.all(excluding: <TargetPlatform>{ TargetPlatform.iOS }));

        testWidgets('readonly', (WidgetTester tester) async {
          controller.text = testText;
          controller.selection = const TextSelection.collapsed(
            offset: 29,
            affinity: TextAffinity.upstream,
          );

          await tester.pumpWidget(buildEditableText(readOnly: true));
          await sendKeyCombination(tester, wordModifierBackspace());

          expect(controller.text, testText);

          expect(
            controller.selection,
            const TextSelection.collapsed(offset: 29, affinity: TextAffinity.upstream),
          );
        }, variant: TargetPlatformVariant.all());

        testWidgets('at start', (WidgetTester tester) async {
          controller.text = testText;
          controller.selection = const TextSelection.collapsed(
            offset: 0,
          );

          await tester.pumpWidget(buildEditableText());
          await sendKeyCombination(tester, wordModifierBackspace());

          expect(
            controller.text,
            'Now is the time for\n'
            'all good people\n'
            'to come to the aid\n'
            'of their country.',
          );

          expect(
            controller.selection,
            const TextSelection.collapsed(offset: 0),
          );
        }, variant: TargetPlatformVariant.all());

        testWidgets('at end', (WidgetTester tester) async {
          controller.text = testText;
          controller.selection = const TextSelection.collapsed(
            offset: 72,
            affinity: TextAffinity.upstream,
          );

          await tester.pumpWidget(buildEditableText());
          await sendKeyCombination(tester, wordModifierBackspace());

          expect(
            controller.text,
            'Now is the time for\n'
            'all good people\n'
            'to come to the aid\n'
            'of their ',
          );

          expect(
            controller.selection,
            const TextSelection.collapsed(offset: 64),
          );
        }, variant: TargetPlatformVariant.all(excluding: <TargetPlatform>{ TargetPlatform.iOS }));

        testWidgets('inside of a cluster', (WidgetTester tester) async {
          controller.text = testCluster;
          controller.selection = const TextSelection.collapsed(
            offset: 1,
            affinity: TextAffinity.upstream,
          );

          await tester.pumpWidget(buildEditableText());
          await sendKeyCombination(tester, wordModifierBackspace());

          expect(
            controller.text,
            '👨‍👩‍👦👨‍👩‍👦',
          );

          expect(
            controller.selection,
            const TextSelection.collapsed(offset: 0),
          );
        }, variant: TargetPlatformVariant.all(excluding: <TargetPlatform>{ TargetPlatform.iOS }));

        testWidgets('at cluster boundary', (WidgetTester tester) async {
          controller.text = testCluster;
          controller.selection = const TextSelection.collapsed(
            offset: 8,
            affinity: TextAffinity.upstream,
          );

          await tester.pumpWidget(buildEditableText());
          await sendKeyCombination(tester, wordModifierBackspace());

          expect(
            controller.text,
            '👨‍👩‍👦👨‍👩‍👦',
          );

          expect(
            controller.selection,
            const TextSelection.collapsed(offset: 0),
          );
        }, variant: TargetPlatformVariant.all(excluding: <TargetPlatform>{ TargetPlatform.iOS }));
      });

      group('word modifier + delete', () {
        const LogicalKeyboardKey trigger = LogicalKeyboardKey.delete;
        SingleActivator wordModifierDelete() {
          final bool isApple = defaultTargetPlatform == TargetPlatform.macOS || defaultTargetPlatform == TargetPlatform.iOS;
          return SingleActivator(trigger, control: !isApple, alt: isApple);
        }

        testWidgets('WordModifier-delete', (WidgetTester tester) async {
          controller.text = testText;
          // Place the caret after "all".
          controller.selection = const TextSelection.collapsed(
            offset: 23,
            affinity: TextAffinity.upstream,
          );

          await tester.pumpWidget(buildEditableText());
          await sendKeyCombination(tester, wordModifierDelete());

          expect(
            controller.text,
            'Now is the time for\n'
            'all people\n'
            'to come to the aid\n'
            'of their country.',
          );

          expect(
            controller.selection,
            const TextSelection.collapsed(offset: 23),
          );
        }, variant: TargetPlatformVariant.all(excluding: <TargetPlatform>{ TargetPlatform.iOS }));

        testWidgets('readonly', (WidgetTester tester) async {
          controller.text = testText;
          controller.selection = const TextSelection.collapsed(
            offset: 23,
            affinity: TextAffinity.upstream,
          );

          await tester.pumpWidget(buildEditableText(readOnly: true));
          await sendKeyCombination(tester, wordModifierDelete());

          expect(controller.text, testText);

          expect(
            controller.selection,
            const TextSelection.collapsed(offset: 23, affinity: TextAffinity.upstream),
          );
        }, variant: TargetPlatformVariant.all());

        testWidgets('at start', (WidgetTester tester) async {
          controller.text = testText;
          controller.selection = const TextSelection.collapsed(
            offset: 0,
          );

          await tester.pumpWidget(buildEditableText());
          await sendKeyCombination(tester, wordModifierDelete());

          expect(
            controller.text,
            ' is the time for\n'
            'all good people\n'
            'to come to the aid\n'
            'of their country.',
          );

          expect(
            controller.selection,
            const TextSelection.collapsed(offset: 0),
          );
        }, variant: TargetPlatformVariant.all(excluding: <TargetPlatform>{ TargetPlatform.iOS }));

        testWidgets('at end', (WidgetTester tester) async {
          controller.text = testText;
          controller.selection = const TextSelection.collapsed(
            offset: 72,
            affinity: TextAffinity.upstream,
          );

          await tester.pumpWidget(buildEditableText());
          await sendKeyCombination(tester, wordModifierDelete());

          expect(controller.text, testText);
          expect(
            controller.selection,
            const TextSelection.collapsed(offset: 72, affinity: TextAffinity.upstream),
          );
        }, variant: TargetPlatformVariant.all());

        testWidgets('inside of a cluster', (WidgetTester tester) async {
          controller.text = testCluster;
          controller.selection = const TextSelection.collapsed(
            offset: 1,
            affinity: TextAffinity.upstream,
          );

          await tester.pumpWidget(buildEditableText());
          await sendKeyCombination(tester, wordModifierDelete());

          expect(
            controller.text,
            '👨‍👩‍👦👨‍👩‍👦',
          );

          expect(
            controller.selection,
            const TextSelection.collapsed(offset: 0),
          );
        }, variant: TargetPlatformVariant.all(excluding: <TargetPlatform>{ TargetPlatform.iOS }));

        testWidgets('at cluster boundary', (WidgetTester tester) async {
          controller.text = testCluster;
          controller.selection = const TextSelection.collapsed(
            offset: 8,
            affinity: TextAffinity.upstream,
          );

          await tester.pumpWidget(buildEditableText());
          await sendKeyCombination(tester, wordModifierDelete());

          expect(
            controller.text,
            '👨‍👩‍👦👨‍👩‍👦',
          );

          expect(
            controller.selection,
            const TextSelection.collapsed(offset: 8),
          );
        }, variant: TargetPlatformVariant.all(excluding: <TargetPlatform>{ TargetPlatform.iOS }));
      });

      group('line modifier + backspace', () {
        const LogicalKeyboardKey trigger = LogicalKeyboardKey.backspace;
        SingleActivator lineModifierBackspace() {
          final bool isApple = defaultTargetPlatform == TargetPlatform.macOS || defaultTargetPlatform == TargetPlatform.iOS;
          return SingleActivator(trigger, meta: isApple, alt: !isApple);
        }

        testWidgets('alt-backspace', (WidgetTester tester) async {
          controller.text = testText;
          // Place the caret before "people".
          controller.selection = const TextSelection.collapsed(
            offset: 29,
            affinity: TextAffinity.upstream,
          );

          await tester.pumpWidget(buildEditableText());
          await sendKeyCombination(tester, lineModifierBackspace());

          expect(
            controller.text,
            'Now is the time for\n'
            'people\n'
            'to come to the aid\n'
            'of their country.',
          );

          expect(
            controller.selection,
            const TextSelection.collapsed(offset: 20),
          );
        }, variant: TargetPlatformVariant.all());

        testWidgets('softwrap line boundary, upstream', (WidgetTester tester) async {
          controller.text = testSoftwrapText;
          // Place the caret at the end of the 2nd line.
          controller.selection = const TextSelection.collapsed(
            offset: 40,
            affinity: TextAffinity.upstream,
          );

          await tester.pumpWidget(buildEditableText());
          await sendKeyCombination(tester, lineModifierBackspace());

          expect(
            controller.text,
            '0123456789ABCDEFGHIJ'
            '0123456789ABCDEFGHIJ'
            '0123456789ABCDEFGHIJ'
          );

          expect(
            controller.selection,
            const TextSelection.collapsed(offset: 20),
          );
        }, variant: TargetPlatformVariant.all());

        testWidgets('softwrap line boundary, downstream', (WidgetTester tester) async {
          controller.text = testSoftwrapText;
          // Place the caret at the beginning of the 3rd line.
          controller.selection = const TextSelection.collapsed(
            offset: 40,
          );

          await tester.pumpWidget(buildEditableText());
          await sendKeyCombination(tester, lineModifierBackspace());

          expect(
            controller.selection,
            const TextSelection.collapsed(offset: 40),
          );
          expect(controller.text, testSoftwrapText);
        }, variant: TargetPlatformVariant.all());

        testWidgets('readonly', (WidgetTester tester) async {
          controller.text = testText;
          controller.selection = const TextSelection.collapsed(
            offset: 29,
            affinity: TextAffinity.upstream,
          );

          await tester.pumpWidget(buildEditableText(readOnly: true));
          await sendKeyCombination(tester, lineModifierBackspace());

          expect(controller.text, testText);

          expect(
            controller.selection,
            const TextSelection.collapsed(offset: 29, affinity: TextAffinity.upstream),
          );
        }, variant: TargetPlatformVariant.all());

        testWidgets('at start', (WidgetTester tester) async {
          controller.text = testText;
          controller.selection = const TextSelection.collapsed(
            offset: 0,
          );

          await tester.pumpWidget(buildEditableText());
          await sendKeyCombination(tester, lineModifierBackspace());

          expect(
            controller.text,
            'Now is the time for\n'
            'all good people\n'
            'to come to the aid\n'
            'of their country.',
          );

          expect(
            controller.selection,
            const TextSelection.collapsed(offset: 0),
          );
        }, variant: TargetPlatformVariant.all());

        testWidgets('at end', (WidgetTester tester) async {
          controller.text = testText;
          controller.selection = const TextSelection.collapsed(
            offset: 72,
            affinity: TextAffinity.upstream,
          );

          await tester.pumpWidget(buildEditableText());
          await sendKeyCombination(tester, lineModifierBackspace());

          expect(
            controller.text,
            'Now is the time for\n'
            'all good people\n'
            'to come to the aid\n'
          );

          expect(
            controller.selection,
            const TextSelection.collapsed(offset: 55),
          );
        }, variant: TargetPlatformVariant.all());

        testWidgets('inside of a cluster', (WidgetTester tester) async {
          controller.text = testCluster;
          controller.selection = const TextSelection.collapsed(
            offset: 1,
            affinity: TextAffinity.upstream,
          );

          await tester.pumpWidget(buildEditableText());
          await sendKeyCombination(tester, lineModifierBackspace());

          expect(
            controller.text,
            '👨‍👩‍👦👨‍👩‍👦',
          );

          expect(
            controller.selection,
            const TextSelection.collapsed(offset: 0),
          );
        }, variant: TargetPlatformVariant.all());

        testWidgets('at cluster boundary', (WidgetTester tester) async {
          controller.text = testCluster;
          controller.selection = const TextSelection.collapsed(
            offset: 8,
            affinity: TextAffinity.upstream,
          );

          await tester.pumpWidget(buildEditableText());
          await sendKeyCombination(tester, lineModifierBackspace());

          expect(
            controller.text,
            '👨‍👩‍👦👨‍👩‍👦',
          );

          expect(
            controller.selection,
            const TextSelection.collapsed(offset: 0),
          );
        }, variant: TargetPlatformVariant.all());
      });

      group('line modifier + delete', () {
        const LogicalKeyboardKey trigger = LogicalKeyboardKey.delete;
        SingleActivator lineModifierDelete() {
          final bool isApple = defaultTargetPlatform == TargetPlatform.macOS || defaultTargetPlatform == TargetPlatform.iOS;
          return SingleActivator(trigger, meta: isApple, alt: !isApple);
        }

        testWidgets('alt-delete', (WidgetTester tester) async {
          controller.text = testText;
          // Place the caret after "all".
          controller.selection = const TextSelection.collapsed(
            offset: 23,
            affinity: TextAffinity.upstream,
          );

          await tester.pumpWidget(buildEditableText());
          await sendKeyCombination(tester, lineModifierDelete());

          expect(
            controller.text,
            'Now is the time for\n'
            'all\n'
            'to come to the aid\n'
            'of their country.',
          );

          expect(
            controller.selection,
            const TextSelection.collapsed(offset: 23),
          );
        }, variant: TargetPlatformVariant.all());

        testWidgets('softwrap line boundary, upstream', (WidgetTester tester) async {
          controller.text = testSoftwrapText;
          // Place the caret at the end of the 2nd line.
          controller.selection = const TextSelection.collapsed(
            offset: 40,
            affinity: TextAffinity.upstream,
          );

          await tester.pumpWidget(buildEditableText());
          await sendKeyCombination(tester, lineModifierDelete());

          expect(controller.text, testSoftwrapText);

          expect(
            controller.selection,
            const TextSelection.collapsed(offset: 40, affinity: TextAffinity.upstream),
          );
        }, variant: TargetPlatformVariant.all());

        testWidgets('softwrap line boundary, downstream', (WidgetTester tester) async {
          controller.text = testSoftwrapText;
          // Place the caret at the beginning of the 3rd line.
          controller.selection = const TextSelection.collapsed(
            offset: 40,
          );

          await tester.pumpWidget(buildEditableText());
          await sendKeyCombination(tester, lineModifierDelete());

          expect(
            controller.text,
            '0123456789ABCDEFGHIJ'
            '0123456789ABCDEFGHIJ'
            '0123456789ABCDEFGHIJ'
          );

          expect(
            controller.selection,
            const TextSelection.collapsed(offset: 40),
          );
        }, variant: TargetPlatformVariant.all());

        testWidgets('readonly', (WidgetTester tester) async {
          controller.text = testText;
          controller.selection = const TextSelection.collapsed(
            offset: 23,
            affinity: TextAffinity.upstream,
          );

          await tester.pumpWidget(buildEditableText(readOnly: true));
          await sendKeyCombination(tester, lineModifierDelete());

          expect(controller.text, testText);

          expect(
            controller.selection,
            const TextSelection.collapsed(offset: 23, affinity: TextAffinity.upstream),
          );
        }, variant: TargetPlatformVariant.all());

        testWidgets('at start', (WidgetTester tester) async {
          controller.text = testText;
          controller.selection = const TextSelection.collapsed(
            offset: 0,
          );

          await tester.pumpWidget(buildEditableText());
          await sendKeyCombination(tester, lineModifierDelete());

          expect(
            controller.text,
            '\n'
            'all good people\n'
            'to come to the aid\n'
            'of their country.',
          );

          expect(
            controller.selection,
            const TextSelection.collapsed(offset: 0),
          );
        }, variant: TargetPlatformVariant.all());

        testWidgets('at end', (WidgetTester tester) async {
          controller.text = testText;
          controller.selection = const TextSelection.collapsed(
            offset: 72,
            affinity: TextAffinity.upstream,
          );

          await tester.pumpWidget(buildEditableText());
          await sendKeyCombination(tester, lineModifierDelete());

          expect(controller.text, testText);
          expect(
            controller.selection,
            const TextSelection.collapsed(offset: 72, affinity: TextAffinity.upstream),
          );
        }, variant: TargetPlatformVariant.all());

        testWidgets('inside of a cluster', (WidgetTester tester) async {
          controller.text = testCluster;
          controller.selection = const TextSelection.collapsed(
            offset: 1,
            affinity: TextAffinity.upstream,
          );

          await tester.pumpWidget(buildEditableText());
          await sendKeyCombination(tester, lineModifierDelete());

          expect(
            controller.text,
            isEmpty,
          );

          expect(
            controller.selection,
            const TextSelection.collapsed(offset: 0),
          );
        }, variant: TargetPlatformVariant.all());

        testWidgets('at cluster boundary', (WidgetTester tester) async {
          controller.text = testCluster;
          controller.selection = const TextSelection.collapsed(
            offset: 8,
            affinity: TextAffinity.upstream,
          );

          await tester.pumpWidget(buildEditableText());
          await sendKeyCombination(tester, lineModifierDelete());

          expect(
            controller.text,
            '👨‍👩‍👦',
          );

          expect(
            controller.selection,
            const TextSelection.collapsed(offset: 8),
          );
        }, variant: TargetPlatformVariant.all());
      });

      group('Arrow Movement', () {
        group('left', () {
          const LogicalKeyboardKey trigger = LogicalKeyboardKey.arrowLeft;

          testWidgets('at start', (WidgetTester tester) async {
            controller.text = testText;
            controller.selection = const TextSelection.collapsed(
              offset: 0,
            );

            await tester.pumpWidget(buildEditableText());

            for (final SingleActivator activator in allModifierVariants(trigger)) {
              await sendKeyCombination(tester, activator);
              await tester.pump();

              expect(
                controller.selection,
                const TextSelection.collapsed(offset: 0),
                reason: activator.toString(),
              );
            }
          }, variant: TargetPlatformVariant.all());

          testWidgets('base arrow key movement', (WidgetTester tester) async {
            controller.text = testText;
            controller.selection = const TextSelection.collapsed(
              offset: 20,
            );
            await tester.pumpWidget(buildEditableText());
            await sendKeyCombination(tester, const SingleActivator(trigger));
            await tester.pump();

            expect(controller.selection, const TextSelection.collapsed(
              offset: 19,
            ));
          }, variant: TargetPlatformVariant.all());

          testWidgets('word modifier + arrow key movement', (WidgetTester tester) async {
            controller.text = testText;
            controller.selection = const TextSelection.collapsed(
              offset: 7,   // Before the first "the"
            );
            await tester.pumpWidget(buildEditableText());
            await sendKeyCombination(tester, const SingleActivator(trigger, control: true));
            await tester.pump();

            expect(controller.selection, const TextSelection.collapsed(
              offset: 4,
            ));
          }, variant: allExceptApple);

          testWidgets('line modifier + arrow key movement', (WidgetTester tester) async {
            controller.text = testText;
            controller.selection = const TextSelection.collapsed(
              offset: 24,   // Before the "good".
            );
            await tester.pumpWidget(buildEditableText());
            await sendKeyCombination(tester, const SingleActivator(trigger, alt: true));
            await tester.pump();

            expect(controller.selection, const TextSelection.collapsed(
              offset: 20,
            ));
          }, variant: allExceptApple);
        });

        group('right', () {
          const LogicalKeyboardKey trigger = LogicalKeyboardKey.arrowRight;

          testWidgets('at end', (WidgetTester tester) async {
            controller.text = testText;
            controller.selection = const TextSelection.collapsed(
              offset: 72,
            );

            await tester.pumpWidget(buildEditableText());

            for (final SingleActivator activator in allModifierVariants(trigger)) {
              await sendKeyCombination(tester, activator);
              await tester.pump();

              expect(controller.selection.isCollapsed, isTrue, reason: activator.toString());
              expect(controller.selection.baseOffset, 72, reason: activator.toString());
            }
          }, variant: TargetPlatformVariant.all());

          testWidgets('base arrow key movement', (WidgetTester tester) async {
            controller.text = testText;
            controller.selection = const TextSelection.collapsed(
              offset: 20,
            );
            await tester.pumpWidget(buildEditableText());
            await sendKeyCombination(tester, const SingleActivator(trigger));
            await tester.pump();

            expect(controller.selection, const TextSelection.collapsed(
              offset: 21,
            ));
          }, variant: TargetPlatformVariant.all());

          testWidgets('word modifier + arrow key movement', (WidgetTester tester) async {
            controller.text = testText;
            controller.selection = const TextSelection.collapsed(
              offset: 7,   // Before the first "the"
            );
            await tester.pumpWidget(buildEditableText());
            await sendKeyCombination(tester, const SingleActivator(trigger, control: true));
            await tester.pump();

            expect(controller.selection, const TextSelection.collapsed(
              offset: 10,
            ));
          }, variant: allExceptApple);

         testWidgets('line modifier + arrow key movement', (WidgetTester tester) async {
            controller.text = testText;
            controller.selection = const TextSelection.collapsed(
              offset: 24,   // Before the "good".
            );
            await tester.pumpWidget(buildEditableText());
            await sendKeyCombination(tester, const SingleActivator(trigger, alt: true));
            await tester.pump();

            expect(controller.selection, const TextSelection.collapsed(
              offset: 35, // Before the newline character.
              affinity: TextAffinity.upstream,
            ));
          }, variant: allExceptApple);
        });

        group('With initial non-collapsed selection', () {
          testWidgets('base arrow key movement', (WidgetTester tester) async {
            controller.text = testText;
            // The word "all" is selected.
            controller.selection = const TextSelection(
              baseOffset: 20,
              extentOffset: 23,
            );
            await tester.pumpWidget(buildEditableText());
            await sendKeyCombination(tester, const SingleActivator(LogicalKeyboardKey.arrowLeft));
            await tester.pump();

            expect(controller.selection, const TextSelection.collapsed(
              offset: 20,
            ));

            // The word "all" is selected.
            controller.selection = const TextSelection(
              baseOffset: 23,
              extentOffset: 20,
            );
            await tester.pump();
            await sendKeyCombination(tester, const SingleActivator(LogicalKeyboardKey.arrowLeft));
            await tester.pump();
            expect(controller.selection, const TextSelection.collapsed(
              offset: 20,
            ));

            // The word "all" is selected.
            controller.selection = const TextSelection(
              baseOffset: 20,
              extentOffset: 23,
            );
            await tester.pump();
            await sendKeyCombination(tester, const SingleActivator(LogicalKeyboardKey.arrowRight));
            await tester.pump();
            expect(controller.selection, const TextSelection.collapsed(
              offset: 23,
            ));

            // The word "all" is selected.
            controller.selection = const TextSelection(
              baseOffset: 23,
              extentOffset: 20,
            );
            await tester.pump();
            await sendKeyCombination(tester, const SingleActivator(LogicalKeyboardKey.arrowRight));
            await tester.pump();
            expect(controller.selection, const TextSelection.collapsed(
              offset: 23,
            ));
          }, variant: TargetPlatformVariant.all());

          testWidgets('word modifier + arrow key movement', (WidgetTester tester) async {
            controller.text = testText;
            // "good" to "come" is selected.
            controller.selection = const TextSelection(
              baseOffset: 24,
              extentOffset: 43,
            );
            await tester.pumpWidget(buildEditableText());
            await sendKeyCombination(tester, const SingleActivator(LogicalKeyboardKey.arrowLeft, control: true));
            await tester.pump();

            expect(controller.selection, const TextSelection.collapsed(
              offset: 39, // Before "come".
            ));

            // "good" to "come" is selected.
            controller.selection = const TextSelection(
              baseOffset: 43,
              extentOffset: 24,
            );
            await tester.pump();
            await sendKeyCombination(tester, const SingleActivator(LogicalKeyboardKey.arrowLeft, control: true));
            await tester.pump();
            expect(controller.selection, const TextSelection.collapsed(
              offset: 20, // Before "all".
              //offset: 39, // Before "come".
            ));

            // "good" to "come" is selected.
            controller.selection = const TextSelection(
              baseOffset: 24,
              extentOffset: 43,
            );
            await tester.pump();
            await sendKeyCombination(tester, const SingleActivator(LogicalKeyboardKey.arrowRight, control: true));
            await tester.pump();
            expect(controller.selection, const TextSelection.collapsed(
              offset: 46, // After "to".
            ));

            // "good" to "come" is selected.
            controller.selection = const TextSelection(
              baseOffset: 43,
              extentOffset: 24,
            );
            await tester.pump();
            await sendKeyCombination(tester, const SingleActivator(LogicalKeyboardKey.arrowRight, control: true));
            await tester.pump();
            expect(controller.selection, const TextSelection.collapsed(
              offset: 28, // After "good".
            ));
          }, variant: allExceptApple);

         testWidgets('line modifier + arrow key movement', (WidgetTester tester) async {
            controller.text = testText;
            // "good" to "come" is selected.
            controller.selection = const TextSelection(
              baseOffset: 24,
              extentOffset: 43,
            );
            await tester.pumpWidget(buildEditableText());
            await sendKeyCombination(tester, const SingleActivator(LogicalKeyboardKey.arrowLeft, alt: true));
            await tester.pump();

            expect(controller.selection, const TextSelection.collapsed(
              offset: 36, // Before "to".
            ));

            // "good" to "come" is selected.
            controller.selection = const TextSelection(
              baseOffset: 43,
              extentOffset: 24,
            );
            await tester.pump();
            await sendKeyCombination(tester, const SingleActivator(LogicalKeyboardKey.arrowLeft, alt: true));
            await tester.pump();
            expect(controller.selection, const TextSelection.collapsed(
              offset: 20, // Before "all".
            ));

            // "good" to "come" is selected.
            controller.selection = const TextSelection(
              baseOffset: 24,
              extentOffset: 43,
            );
            await tester.pump();
            await sendKeyCombination(tester, const SingleActivator(LogicalKeyboardKey.arrowRight, alt: true));
            await tester.pump();
            expect(controller.selection, const TextSelection.collapsed(
              offset: 54, // After "aid".
              affinity: TextAffinity.upstream,
            ));

            // "good" to "come" is selected.
            controller.selection = const TextSelection(
              baseOffset: 43,
              extentOffset: 24,
            );
            await tester.pump();
            await sendKeyCombination(tester, const SingleActivator(LogicalKeyboardKey.arrowRight, alt: true));
            await tester.pump();
            expect(controller.selection, const TextSelection.collapsed(
              offset: 35, // After "people".
              affinity: TextAffinity.upstream,
            ));
          }, variant: allExceptApple);
        });

        group('vertical movement', () {
          testWidgets('at start', (WidgetTester tester) async {
            controller.text = testText;
            controller.selection = const TextSelection.collapsed(
              offset: 0,
            );

            await tester.pumpWidget(buildEditableText());

            for (final SingleActivator activator in allModifierVariants(LogicalKeyboardKey.arrowUp)) {
              await sendKeyCombination(tester, activator);
              await tester.pump();

              expect(controller.text, testText);
              expect(
                controller.selection,
                const TextSelection.collapsed(offset: 0),
                reason: activator.toString(),
              );
            }

            for (final SingleActivator activator in allModifierVariants(LogicalKeyboardKey.pageUp)) {
              await sendKeyCombination(tester, activator);
              await tester.pump();

              expect(controller.text, testText);
              expect(
                controller.selection,
                const TextSelection.collapsed(offset: 0),
                reason: activator.toString(),
              );
            }
          }, variant: TargetPlatformVariant.all());

          testWidgets('at end', (WidgetTester tester) async {
            controller.text = testText;
            controller.selection = const TextSelection.collapsed(
              offset: 72,
            );

            await tester.pumpWidget(buildEditableText());

            for (final SingleActivator activator in allModifierVariants(LogicalKeyboardKey.arrowDown)) {
              await sendKeyCombination(tester, activator);
              await tester.pump();

              expect(controller.text, testText);
              expect(controller.selection.baseOffset, 72, reason: activator.toString());
              expect(controller.selection.extentOffset, 72, reason: activator.toString());
            }

            for (final SingleActivator activator in allModifierVariants(LogicalKeyboardKey.pageDown)) {
              await sendKeyCombination(tester, activator);
              await tester.pump();

              expect(controller.text, testText);
              expect(controller.selection.baseOffset, 72, reason: activator.toString());
              expect(controller.selection.extentOffset, 72, reason: activator.toString());
            }
          }, variant: TargetPlatformVariant.all());

          testWidgets('run', (WidgetTester tester) async {
            controller.text =
              'aa\n'     // 3
              'a\n'      // 3 + 2 = 5
              'aa\n'     // 5 + 3 = 8
              'aaa\n'    // 8 + 4 = 12
              'aaaa';    // 12 + 4 = 16

            controller.selection = const TextSelection.collapsed(
              offset: 2,
            );
            await tester.pumpWidget(buildEditableText());
            await tester.pump(); // Wait for autofocus to take effect.

            await sendKeyCombination(tester, const SingleActivator(LogicalKeyboardKey.arrowDown));
            await tester.pump();
            expect(controller.selection, const TextSelection.collapsed(
              offset: 4,
              affinity: TextAffinity.upstream,
            ));

            await sendKeyCombination(tester, const SingleActivator(LogicalKeyboardKey.arrowDown));
            await tester.pump();
            expect(controller.selection, const TextSelection.collapsed(
              offset: 7,
              affinity: TextAffinity.upstream,
            ));

            await sendKeyCombination(tester, const SingleActivator(LogicalKeyboardKey.arrowDown));
            await tester.pump();
            expect(controller.selection, const TextSelection.collapsed(
              offset: 10,
            ));

            await sendKeyCombination(tester, const SingleActivator(LogicalKeyboardKey.arrowDown));
            await tester.pump();
            expect(controller.selection, const TextSelection.collapsed(
              offset: 14,
            ));

            await sendKeyCombination(tester, const SingleActivator(LogicalKeyboardKey.arrowDown));
            await tester.pump();
            expect(controller.selection, const TextSelection.collapsed(
              offset: 16,
            ));

            await sendKeyCombination(tester, const SingleActivator(LogicalKeyboardKey.arrowUp));
            await tester.pump();
            expect(controller.selection, const TextSelection.collapsed(
              offset: 10,
            ));

            await sendKeyCombination(tester, const SingleActivator(LogicalKeyboardKey.arrowUp));
            await tester.pump();
            expect(controller.selection, const TextSelection.collapsed(
              offset: 7,
              affinity: TextAffinity.upstream,
            ));

            await sendKeyCombination(tester, const SingleActivator(LogicalKeyboardKey.arrowUp));
            await tester.pump();
            expect(controller.selection, const TextSelection.collapsed(
              offset: 4,
              affinity: TextAffinity.upstream,
            ));

            await sendKeyCombination(tester, const SingleActivator(LogicalKeyboardKey.arrowUp));
            await tester.pump();
            expect(controller.selection, const TextSelection.collapsed(
              offset: 2,
              affinity: TextAffinity.upstream,
            ));

            await sendKeyCombination(tester, const SingleActivator(LogicalKeyboardKey.arrowUp));
            await tester.pump();
            expect(controller.selection, const TextSelection.collapsed(
              offset: 0,
            ));

            await sendKeyCombination(tester, const SingleActivator(LogicalKeyboardKey.arrowDown));
            await tester.pump();
            expect(controller.selection, const TextSelection.collapsed(
              offset: 4,
              affinity: TextAffinity.upstream,
            ));
          }, variant: TargetPlatformVariant.all());

          testWidgets('run with page down/up', (WidgetTester tester) async {
            controller.text =
              'aa\n'     // 3
              'a\n'      // 3 + 2 = 5
              'aa\n'     // 5 + 3 = 8
              'aaa\n'    // 8 + 4 = 12
              '${"aaa\n" * 50}'
              'aaaa';

            controller.selection = const TextSelection.collapsed(offset: 2);
            await tester.pumpWidget(buildEditableText());

            await sendKeyCombination(tester, const SingleActivator(LogicalKeyboardKey.arrowDown));
            await tester.pump();
            expect(controller.selection, const TextSelection.collapsed(
              offset: 4,
              affinity: TextAffinity.upstream,
            ));

            await sendKeyCombination(tester, const SingleActivator(LogicalKeyboardKey.pageDown));
            await tester.pump();
            expect(controller.selection, const TextSelection.collapsed(offset: 82));

            await sendKeyCombination(tester, const SingleActivator(LogicalKeyboardKey.arrowUp));
            await tester.pump();
            expect(controller.selection, const TextSelection.collapsed(offset: 78));

            await sendKeyCombination(tester, const SingleActivator(LogicalKeyboardKey.pageUp));
            await tester.pump();
            expect(controller.selection, const TextSelection.collapsed(
              offset: 2,
              affinity: TextAffinity.upstream,
            ));
          }, variant: TargetPlatformVariant.all(excluding: <TargetPlatform>{TargetPlatform.iOS, TargetPlatform.macOS})); // intended: on macOS Page Up/Down only scrolls

          testWidgets('run can be interrupted by layout changes', (WidgetTester tester) async {
            controller.text =
              'aa\n'     // 3
              'a\n'      // 3 + 2 = 5
              'aa\n'     // 5 + 3 = 8
              'aaa\n'    // 8 + 4 = 12
              'aaaa';    // 12 + 4 = 16

            controller.selection = const TextSelection.collapsed(
              offset: 2,
            );
            await tester.pumpWidget(buildEditableText());

            await sendKeyCombination(tester, const SingleActivator(LogicalKeyboardKey.arrowUp));
            await tester.pump();
            expect(controller.selection, const TextSelection.collapsed(
              offset: 0,
            ));

            // Layout changes.
            await tester.pumpWidget(buildEditableText(textAlign: TextAlign.right));
            await sendKeyCombination(tester, const SingleActivator(LogicalKeyboardKey.arrowDown));
            await tester.pump();

            expect(controller.selection, const TextSelection.collapsed(
              offset: 3,
            ));
          }, variant: TargetPlatformVariant.all());

          testWidgets('run can be interrupted by selection changes', (WidgetTester tester) async {
            controller.text =
              'aa\n'     // 3
              'a\n'      // 3 + 2 = 5
              'aa\n'     // 5 + 3 = 8
              'aaa\n'    // 8 + 4 = 12
              'aaaa';    // 12 + 4 = 16

            controller.selection = const TextSelection.collapsed(
              offset: 2,
            );
            await tester.pumpWidget(buildEditableText());

            await sendKeyCombination(tester, const SingleActivator(LogicalKeyboardKey.arrowUp));
            await tester.pump();
            expect(controller.selection, const TextSelection.collapsed(
              offset: 0,
            ));

            controller.selection = const TextSelection.collapsed(
              offset: 1,
            );
            await tester.pump();
            controller.selection = const TextSelection.collapsed(
              offset: 0,
            );
            await tester.pump();

            await sendKeyCombination(tester, const SingleActivator(LogicalKeyboardKey.arrowDown));
            await tester.pump();
            expect(controller.selection, const TextSelection.collapsed(
              offset: 3,   // Would have been 4 if the run wasn't interrupted.
            ));
          }, variant: TargetPlatformVariant.all());

          testWidgets('long run with fractional text height', (WidgetTester tester) async {
            controller.text = "${'źdźbło\n' * 49}źdźbło";
            controller.selection = const TextSelection.collapsed(offset: 2);
            await tester.pumpWidget(buildEditableText(style: const TextStyle(fontSize: 13.0, height: 1.17)));

            for (int i = 1; i <= 49; i++) {
              await sendKeyCombination(tester, const SingleActivator(LogicalKeyboardKey.arrowDown));
              await tester.pump();
              expect(
                controller.selection,
                TextSelection.collapsed(offset: 2 + i * 7),
                reason: 'line $i',
              );
            }

            for (int i = 49; i >= 1; i--) {
              await sendKeyCombination(tester, const SingleActivator(LogicalKeyboardKey.arrowUp));
              await tester.pump();
              expect(
                controller.selection,
                TextSelection.collapsed(offset: 2 + (i - 1) * 7),
                reason: 'line $i',
              );
            }
          }, variant: TargetPlatformVariant.all());

          // Regression test for https://github.com/flutter/flutter/issues/139196.
          testWidgets('does not create invalid selection', (WidgetTester tester) async {
            controller.value = const TextEditingValue(text: 'A', selection: TextSelection.collapsed(offset: 1));
            await tester.pumpWidget(buildEditableText());
            controller.value = const TextEditingValue(text: 'AA', selection: TextSelection.collapsed(offset: 2));
            await sendKeyCombination(tester, const SingleActivator(LogicalKeyboardKey.arrowDown));
          }, variant: TargetPlatformVariant.all());
        });
      });
    },
    skip: kIsWeb, // [intended] on web these keys are handled by the browser.
  );

  group('macOS shortcuts', () {
    final TargetPlatformVariant macOSOnly = TargetPlatformVariant.only(TargetPlatform.macOS);

    testWidgets('word modifier + arrowLeft', (WidgetTester tester) async {
      controller.text = testText;
      controller.selection = const TextSelection.collapsed(
        offset: 7,   // Before the first "the"
      );
      await tester.pumpWidget(buildEditableText());
      await sendKeyCombination(tester, const SingleActivator(LogicalKeyboardKey.arrowLeft, alt: true));
      await tester.pump();

      expect(controller.selection, const TextSelection.collapsed(
        offset: 4,
      ));
    }, variant: macOSOnly);

    testWidgets('word modifier + arrowRight', (WidgetTester tester) async {
      controller.text = testText;
      controller.selection = const TextSelection.collapsed(
        offset: 7,   // Before the first "the"
      );
      await tester.pumpWidget(buildEditableText());
      await sendKeyCombination(tester, const SingleActivator(LogicalKeyboardKey.arrowRight, alt: true));
      await tester.pump();

      expect(controller.selection, const TextSelection.collapsed(
        offset: 10, // after the first "the"
      ));
    }, variant: macOSOnly);

    testWidgets('line modifier + arrowLeft', (WidgetTester tester) async {
      controller.text = testText;
      controller.selection = const TextSelection.collapsed(
        offset: 24,   // Before the "good".
      );
      await tester.pumpWidget(buildEditableText());
      await sendKeyCombination(tester, const SingleActivator(LogicalKeyboardKey.arrowLeft, meta: true));
      await tester.pump();

      expect(controller.selection, const TextSelection.collapsed(
        offset: 20,
      ));
    }, variant: macOSOnly);

    testWidgets('line modifier + arrowRight', (WidgetTester tester) async {
      controller.text = testText;
      controller.selection = const TextSelection.collapsed(
        offset: 24,   // Before the "good".
      );
      await tester.pumpWidget(buildEditableText());
      await sendKeyCombination(tester, const SingleActivator(LogicalKeyboardKey.arrowRight, meta: true));
      await tester.pump();

      expect(controller.selection, const TextSelection.collapsed(
        offset: 35, // Before the newline character.
        affinity: TextAffinity.upstream,
      ));
    }, variant: macOSOnly);

    testWidgets('word modifier + arrow key movement', (WidgetTester tester) async {
      controller.text = testText;
      // "good" to "come" is selected.
      controller.selection = const TextSelection(
        baseOffset: 24,
        extentOffset: 43,
      );
      await tester.pumpWidget(buildEditableText());
      await sendKeyCombination(tester, const SingleActivator(LogicalKeyboardKey.arrowLeft, alt: true));
      await tester.pump();

      expect(controller.selection, const TextSelection.collapsed(
        offset: 39, // Before "come".
      ));

      // "good" to "come" is selected.
      controller.selection = const TextSelection(
        baseOffset: 43,
        extentOffset: 24,
      );
      await tester.pump();
      await sendKeyCombination(tester, const SingleActivator(LogicalKeyboardKey.arrowLeft, alt: true));
      await tester.pump();
      expect(controller.selection, const TextSelection.collapsed(
        offset: 20, // Before "all".
        //offset: 39, // Before "come".
      ));

      // "good" to "come" is selected.
      controller.selection = const TextSelection(
        baseOffset: 24,
        extentOffset: 43,
      );
      await tester.pump();
      await sendKeyCombination(tester, const SingleActivator(LogicalKeyboardKey.arrowRight, alt: true));
      await tester.pump();
      expect(controller.selection, const TextSelection.collapsed(
        offset: 46, // After "to".
      ));

      // "good" to "come" is selected.
      controller.selection = const TextSelection(
        baseOffset: 43,
        extentOffset: 24,
      );
      await tester.pump();
      await sendKeyCombination(tester, const SingleActivator(LogicalKeyboardKey.arrowRight, alt: true));
      await tester.pump();
      expect(controller.selection, const TextSelection.collapsed(
        offset: 28, // After "good".
      ));
    }, variant: macOSOnly);

    testWidgets('line modifier + arrow key movement', (WidgetTester tester) async {
      controller.text = testText;
      // "good" to "come" is selected.
      controller.selection = const TextSelection(
        baseOffset: 24,
        extentOffset: 43,
      );
      await tester.pumpWidget(buildEditableText());
      await sendKeyCombination(tester, const SingleActivator(LogicalKeyboardKey.arrowLeft, meta: true));
      await tester.pump();

      expect(controller.selection, const TextSelection.collapsed(
        offset: 36, // Before "to".
      ));

      // "good" to "come" is selected.
      controller.selection = const TextSelection(
        baseOffset: 43,
        extentOffset: 24,
      );
      await tester.pump();
      await sendKeyCombination(tester, const SingleActivator(LogicalKeyboardKey.arrowLeft, meta: true));
      await tester.pump();
      expect(controller.selection, const TextSelection.collapsed(
        offset: 20, // Before "all".
      ));

      // "good" to "come" is selected.
      controller.selection = const TextSelection(
        baseOffset: 24,
        extentOffset: 43,
      );
      await tester.pump();
      await sendKeyCombination(tester, const SingleActivator(LogicalKeyboardKey.arrowRight, meta: true));
      await tester.pump();
      expect(controller.selection, const TextSelection.collapsed(
        offset: 54, // After "aid".
        affinity: TextAffinity.upstream,
      ));

      // "good" to "come" is selected.
      controller.selection = const TextSelection(
        baseOffset: 43,
        extentOffset: 24,
      );
      await tester.pump();
      await sendKeyCombination(tester, const SingleActivator(LogicalKeyboardKey.arrowRight, meta: true));
      await tester.pump();
      expect(controller.selection, const TextSelection.collapsed(
        offset: 35, // After "people".
        affinity: TextAffinity.upstream,
      ));
    }, variant: macOSOnly);
  }, skip: kIsWeb); // [intended] on web these keys are handled by the browser.

  group('Web does not accept', () {
    final TargetPlatformVariant allExceptApple = TargetPlatformVariant.all(excluding: <TargetPlatform>{ TargetPlatform.iOS, TargetPlatform.macOS });
    const TargetPlatformVariant appleOnly = TargetPlatformVariant(<TargetPlatform>{ TargetPlatform.macOS, TargetPlatform.iOS });
    group('macOS shortcuts', () {

      testWidgets('word modifier + arrowLeft', (WidgetTester tester) async {
        controller.text = testText;
        controller.selection = const TextSelection.collapsed(
          offset: 7,   // Before the first "the"
        );
        await tester.pumpWidget(buildEditableText());
        await sendKeyCombination(tester, const SingleActivator(LogicalKeyboardKey.arrowLeft, alt: true));
        await tester.pump();

        expect(controller.selection, const TextSelection.collapsed(offset: 7));
      }, variant: appleOnly);

      testWidgets('word modifier + arrowRight', (WidgetTester tester) async {
        controller.text = testText;
        controller.selection = const TextSelection.collapsed(
          offset: 7,   // Before the first "the"
        );
        await tester.pumpWidget(buildEditableText());
        await sendKeyCombination(tester, const SingleActivator(LogicalKeyboardKey.arrowRight, alt: true));
        await tester.pump();

        expect(controller.selection, const TextSelection.collapsed(offset: 7));
      }, variant: appleOnly);

      testWidgets('line modifier + arrowLeft', (WidgetTester tester) async {
        controller.text = testText;
        controller.selection = const TextSelection.collapsed(
          offset: 24,   // Before the "good".
        );
        await tester.pumpWidget(buildEditableText());
        await sendKeyCombination(tester, const SingleActivator(LogicalKeyboardKey.arrowLeft, meta: true));
        await tester.pump();

        expect(controller.selection, const TextSelection.collapsed(offset: 24,));
      }, variant: appleOnly);

      testWidgets('line modifier + arrowRight', (WidgetTester tester) async {
        controller.text = testText;
        controller.selection = const TextSelection.collapsed(
          offset: 24,   // Before the "good".
        );
        await tester.pumpWidget(buildEditableText());
        await sendKeyCombination(tester, const SingleActivator(LogicalKeyboardKey.arrowRight, meta: true));
        await tester.pump();

        expect(controller.selection, const TextSelection.collapsed(
          offset: 24, // Before the newline character.
        ));
      }, variant: appleOnly);

      testWidgets('word modifier + arrow key movement', (WidgetTester tester) async {
        controller.text = testText;
        controller.selection = const TextSelection(
          baseOffset: 24,
          extentOffset: 43,
        );
        await tester.pumpWidget(buildEditableText());
        await sendKeyCombination(tester, const SingleActivator(LogicalKeyboardKey.arrowLeft, alt: true));
        await tester.pump();

        expect(controller.selection, const TextSelection(
          baseOffset: 24,
          extentOffset: 43,
        ));

        controller.selection = const TextSelection(
          baseOffset: 43,
          extentOffset: 24,
        );
        await tester.pump();
        await sendKeyCombination(tester, const SingleActivator(LogicalKeyboardKey.arrowLeft, alt: true));
        await tester.pump();
        expect(controller.selection, const TextSelection(
          baseOffset: 43,
          extentOffset: 24,
        ));

        controller.selection = const TextSelection(
          baseOffset: 24,
          extentOffset: 43,
        );
        await tester.pump();
        await sendKeyCombination(tester, const SingleActivator(LogicalKeyboardKey.arrowRight, alt: true));
        await tester.pump();
        expect(controller.selection, const TextSelection(
          baseOffset: 24,
          extentOffset: 43,
        ));

        // "good" to "come" is selected.
        controller.selection = const TextSelection(
          baseOffset: 43,
          extentOffset: 24,
        );
        await tester.pump();
        await sendKeyCombination(tester, const SingleActivator(LogicalKeyboardKey.arrowRight, alt: true));
        await tester.pump();
        expect(controller.selection, const TextSelection(
          baseOffset: 43,
          extentOffset: 24,
        ));
      }, variant: appleOnly);

      testWidgets('line modifier + arrow key movement', (WidgetTester tester) async {
        controller.text = testText;
        // "good" to "come" is selected.
        controller.selection = const TextSelection(
          baseOffset: 24,
          extentOffset: 43,
        );
        await tester.pumpWidget(buildEditableText());
        await sendKeyCombination(tester, const SingleActivator(LogicalKeyboardKey.arrowLeft, meta: true));
        await tester.pump();

        expect(controller.selection, const TextSelection(
          baseOffset: 24,
          extentOffset: 43,
        ));

        // "good" to "come" is selected.
        controller.selection = const TextSelection(
          baseOffset: 43,
          extentOffset: 24,
        );
        await tester.pump();
        await sendKeyCombination(tester, const SingleActivator(LogicalKeyboardKey.arrowLeft, meta: true));
        await tester.pump();
        expect(controller.selection, const TextSelection(
          baseOffset: 43,
          extentOffset: 24,
        ));

        // "good" to "come" is selected.
        controller.selection = const TextSelection(
          baseOffset: 24,
          extentOffset: 43,
        );
        await tester.pump();
        await sendKeyCombination(tester, const SingleActivator(LogicalKeyboardKey.arrowRight, meta: true));
        await tester.pump();
        expect(controller.selection, const TextSelection(
          baseOffset: 24,
          extentOffset: 43,
        ));

        // "good" to "come" is selected.
        controller.selection = const TextSelection(
          baseOffset: 43,
          extentOffset: 24,
        );
        await tester.pump();
        await sendKeyCombination(tester, const SingleActivator(LogicalKeyboardKey.arrowRight, meta: true));
        await tester.pump();
        expect(controller.selection, const TextSelection(
          baseOffset: 43,
          extentOffset: 24,
        ));
      }, variant: appleOnly);
    });

    testWidgets('vertical movement outside of selection',
        (WidgetTester tester) async {
      controller.text = testText;
      controller.selection = const TextSelection.collapsed(
        offset: 0,
      );

      await tester.pumpWidget(buildEditableText());

      for (final SingleActivator activator in allModifierVariants(LogicalKeyboardKey.arrowDown)) {
        // Skip for the shift shortcut since web accepts it.
        if (activator.shift) {
          continue;
        }
        await sendKeyCombination(tester, activator);
        await tester.pump();

        expect(controller.text, testText);
        expect(
          controller.selection,
          const TextSelection.collapsed(offset: 0),
          reason: activator.toString(),
        );
      }
    }, variant: TargetPlatformVariant.all());

    testWidgets('select all non apple', (WidgetTester tester) async {
      controller.text = testText;
      controller.selection = const TextSelection.collapsed(
        offset: 0,
      );

      await tester.pumpWidget(buildEditableText());
      await sendKeyCombination(tester, const SingleActivator(LogicalKeyboardKey.keyA, control: true));
      await tester.pump();

      expect(controller.selection, const TextSelection.collapsed(offset: 0));
    }, variant: allExceptApple);

    testWidgets('select all apple', (WidgetTester tester) async {
      controller.text = testText;
      controller.selection = const TextSelection.collapsed(
        offset: 0,
      );

      await tester.pumpWidget(buildEditableText());
      await sendKeyCombination(tester, const SingleActivator(LogicalKeyboardKey.keyA, meta: true));
      await tester.pump();

      expect(controller.selection, const TextSelection.collapsed(offset: 0));
    }, variant: appleOnly);

    testWidgets('copy non apple', (WidgetTester tester) async {
      controller.text = testText;
      controller.selection = const TextSelection(
        baseOffset: 0,
        extentOffset: 4,
      );

      await tester.pumpWidget(buildEditableText());
      await sendKeyCombination(tester, const SingleActivator(LogicalKeyboardKey.keyC, control: true));
      await tester.pump();

      final Map<String, dynamic> clipboardData = mockClipboard.clipboardData as Map<String, dynamic>;
      expect(clipboardData['text'], 'empty');
    }, variant: allExceptApple);

    testWidgets('copy apple', (WidgetTester tester) async {
      controller.text = testText;
      controller.selection = const TextSelection(
        baseOffset: 0,
        extentOffset: 4,
      );

      await tester.pumpWidget(buildEditableText());
      await sendKeyCombination(tester, const SingleActivator(LogicalKeyboardKey.keyC, meta: true));
      await tester.pump();

      final Map<String, dynamic> clipboardData = mockClipboard.clipboardData as Map<String, dynamic>;
      expect(clipboardData['text'], 'empty');
    }, variant: appleOnly);

    testWidgets('cut non apple', (WidgetTester tester) async {
      controller.text = testText;
      controller.selection = const TextSelection(
        baseOffset: 0,
        extentOffset: 4,
      );

      await tester.pumpWidget(buildEditableText());
      await sendKeyCombination(tester, const SingleActivator(LogicalKeyboardKey.keyX, control: true));
      await tester.pump();

      final Map<String, dynamic> clipboardData = mockClipboard.clipboardData as Map<String, dynamic>;
      expect(clipboardData['text'], 'empty');
      expect(controller.selection, const TextSelection(
        baseOffset: 0,
        extentOffset: 4,
      ));
    }, variant: allExceptApple);

    testWidgets('cut apple', (WidgetTester tester) async {
      controller.text = testText;
      controller.selection = const TextSelection(
        baseOffset: 0,
        extentOffset: 4,
      );

      await tester.pumpWidget(buildEditableText());
      await sendKeyCombination(tester, const SingleActivator(LogicalKeyboardKey.keyX, meta: true));
      await tester.pump();

      final Map<String, dynamic> clipboardData = mockClipboard.clipboardData as Map<String, dynamic>;
      expect(clipboardData['text'], 'empty');
      expect(controller.selection, const TextSelection(
        baseOffset: 0,
        extentOffset: 4,
      ));
    }, variant: appleOnly);

    testWidgets('paste non apple', (WidgetTester tester) async {
      controller.text = testText;
      controller.selection = const TextSelection.collapsed(offset: 0);
      mockClipboard.clipboardData = <String, dynamic>{
        'text': 'some text',
      };
      await tester.pumpWidget(buildEditableText());
      await sendKeyCombination(tester, const SingleActivator(LogicalKeyboardKey.keyV, control: true));
      await tester.pump();
      expect(controller.selection, const TextSelection.collapsed(offset: 0));
      expect(controller.text, testText);
    }, variant: allExceptApple);

    testWidgets('paste apple', (WidgetTester tester) async {
      controller.text = testText;
      controller.selection = const TextSelection.collapsed(offset: 0);
      mockClipboard.clipboardData = <String, dynamic>{
        'text': 'some text',
      };
      await tester.pumpWidget(buildEditableText());
      await sendKeyCombination(tester, const SingleActivator(LogicalKeyboardKey.keyV, meta: true));
      await tester.pump();
      expect(controller.selection, const TextSelection.collapsed(offset: 0));
      expect(controller.text, testText);
    }, variant: appleOnly);

  }, skip: !kIsWeb);// [intended] specific tests target web.

  group('Web does accept', () {
    final TargetPlatformVariant macOSOnly = TargetPlatformVariant.only(TargetPlatform.macOS);
    const TargetPlatformVariant desktopExceptMacOS = TargetPlatformVariant(<TargetPlatform>{
      TargetPlatform.linux,
      TargetPlatform.windows,
    });

      testWidgets('select up', (WidgetTester tester) async {
        const SingleActivator selectUp =
            SingleActivator(LogicalKeyboardKey.arrowUp, shift: true);
        controller.text = testVerticalText;
        controller.selection = const TextSelection.collapsed(
          offset: 5,
        );

        await tester.pumpWidget(buildEditableText());
        await sendKeyCombination(tester, selectUp);
        await tester.pump();

        expect(controller.text, testVerticalText);
        expect(
          controller.selection,
          const TextSelection(
              baseOffset: 5,
              extentOffset: 3), // selection extends upwards from 5
          reason: selectUp.toString(),
        );
      }, variant: TargetPlatformVariant.desktop());

      testWidgets('select down', (WidgetTester tester) async {
        const SingleActivator selectDown =
            SingleActivator(LogicalKeyboardKey.arrowDown, shift: true);
        controller.text = testVerticalText;
        controller.selection = const TextSelection.collapsed(
          offset: 5,
        );

        await tester.pumpWidget(buildEditableText());
        await sendKeyCombination(tester, selectDown);
        await tester.pump();

        expect(controller.text, testVerticalText);
        expect(
          controller.selection,
          const TextSelection(
              baseOffset: 5,
              extentOffset: 7), // selection extends downwards from 5
          reason: selectDown.toString(),
        );
      }, variant: TargetPlatformVariant.desktop());

      testWidgets('select all up', (WidgetTester tester) async {
        final bool isMacOS = defaultTargetPlatform == TargetPlatform.macOS;
        final SingleActivator selectAllUp = isMacOS
            ? const SingleActivator(LogicalKeyboardKey.arrowUp,
                shift: true, meta: true)
            : const SingleActivator(LogicalKeyboardKey.arrowUp,
                shift: true, alt: true);
        controller.text = testVerticalText;
        controller.selection = const TextSelection.collapsed(
          offset: 5,
        );

        await tester.pumpWidget(buildEditableText());
        await sendKeyCombination(tester, selectAllUp);
        await tester.pump();

        expect(controller.text, testVerticalText);
        expect(
          controller.selection,
          const TextSelection(
              baseOffset: 5,
              extentOffset: 0), // selection extends all the way up
          reason: selectAllUp.toString(),
        );
      }, variant: TargetPlatformVariant.desktop());

      testWidgets('select all down', (WidgetTester tester) async {
        final bool isMacOS = defaultTargetPlatform == TargetPlatform.macOS;
        final SingleActivator selectAllDown = isMacOS
            ? const SingleActivator(LogicalKeyboardKey.arrowDown,
                shift: true, meta: true)
            : const SingleActivator(LogicalKeyboardKey.arrowDown,
                shift: true, alt: true);
        controller.text = testVerticalText;
        controller.selection = const TextSelection.collapsed(
          offset: 5,
        );

        await tester.pumpWidget(buildEditableText());
        await sendKeyCombination(tester, selectAllDown);
        await tester.pump();

        expect(controller.text, testVerticalText);
        expect(
          controller.selection,
          const TextSelection(
              baseOffset: 5,
              extentOffset: 17), // selection extends all the way down
          reason: selectAllDown.toString(),
        );
    }, variant: TargetPlatformVariant.desktop());

    testWidgets('select left', (WidgetTester tester) async {
      const SingleActivator selectLeft =
          SingleActivator(LogicalKeyboardKey.arrowLeft, shift: true);
      controller.text = 'testing';
      controller.selection = const TextSelection.collapsed(
        offset: 5,
      );

      await tester.pumpWidget(buildEditableText());
      await sendKeyCombination(tester, selectLeft);
      await tester.pump();

      expect(controller.text, 'testing');
      expect(
        controller.selection,
        const TextSelection(baseOffset: 5, extentOffset: 4),
        reason: selectLeft.toString(),
      );
    }, variant: TargetPlatformVariant.desktop());

    testWidgets('select right', (WidgetTester tester) async {
      const SingleActivator selectRight =
          SingleActivator(LogicalKeyboardKey.arrowRight, shift: true);
      controller.text = 'testing';
      controller.selection = const TextSelection.collapsed(
        offset: 5,
      );

      await tester.pumpWidget(buildEditableText());
      await sendKeyCombination(tester, selectRight);
      await tester.pump();

      expect(controller.text, 'testing');
      expect(
        controller.selection,
        const TextSelection(baseOffset: 5, extentOffset: 6),
        reason: selectRight.toString(),
      );
    }, variant: TargetPlatformVariant.desktop());

    testWidgets(
        'select left should not expand selection if selection is disabled',
        (WidgetTester tester) async {
      const SingleActivator selectLeft =
          SingleActivator(LogicalKeyboardKey.arrowLeft, shift: true);
      controller.text = 'testing';
      controller.selection = const TextSelection.collapsed(
        offset: 5,
      );

      await tester
          .pumpWidget(buildEditableText(enableInteractiveSelection: false));
      await sendKeyCombination(tester, selectLeft);
      await tester.pump();

      expect(controller.text, 'testing');
      expect(
        controller.selection,
        const TextSelection.collapsed(offset: 4), // should not expand selection
        reason: selectLeft.toString(),
      );
    }, variant: TargetPlatformVariant.desktop());

    testWidgets(
        'select right should not expand selection if selection is disabled',
        (WidgetTester tester) async {
      const SingleActivator selectRight =
          SingleActivator(LogicalKeyboardKey.arrowRight, shift: true);
      controller.text = 'testing';
      controller.selection = const TextSelection.collapsed(offset: 5);

      await tester
          .pumpWidget(buildEditableText(enableInteractiveSelection: false));
      await sendKeyCombination(tester, selectRight);
      await tester.pump();

      expect(controller.text, 'testing');
      expect(
        controller.selection,
        const TextSelection.collapsed(offset: 6), // should not expand selection
        reason: selectRight.toString(),
      );
    }, variant: TargetPlatformVariant.desktop());

    testWidgets('select all left', (WidgetTester tester) async {
      final bool isMacOS = defaultTargetPlatform == TargetPlatform.macOS;
      final SingleActivator selectAllLeft = isMacOS
          ? const SingleActivator(LogicalKeyboardKey.arrowLeft,
              shift: true, meta: true)
          : const SingleActivator(LogicalKeyboardKey.arrowLeft,
              shift: true, alt: true);
      controller.text = 'testing';
      controller.selection = const TextSelection.collapsed(
        offset: 5,
      );

      await tester.pumpWidget(buildEditableText());
      await sendKeyCombination(tester, selectAllLeft);
      await tester.pump();

      expect(controller.text, 'testing');
      expect(
        controller.selection,
        const TextSelection(baseOffset: 5, extentOffset: 0),
        reason: selectAllLeft.toString(),
      );
    }, variant: TargetPlatformVariant.desktop());

    testWidgets('select all right', (WidgetTester tester) async {
      final bool isMacOS = defaultTargetPlatform == TargetPlatform.macOS;
      final SingleActivator selectAllRight = isMacOS
          ? const SingleActivator(LogicalKeyboardKey.arrowRight,
              shift: true, meta: true)
          : const SingleActivator(LogicalKeyboardKey.arrowRight,
              shift: true, alt: true);
      controller.text = 'testing';
      controller.selection = const TextSelection.collapsed(
        offset: 5,
      );

      await tester.pumpWidget(buildEditableText());
      await sendKeyCombination(tester, selectAllRight);
      await tester.pump();

      expect(controller.text, 'testing');
      expect(
        controller.selection,
        const TextSelection(baseOffset: 5, extentOffset: 7),
        reason: selectAllRight.toString(),
      );
    }, variant: TargetPlatformVariant.desktop());
    group('macOS only', () {
      testWidgets('pageUp scrolls 80% of viewport dimension upwards', (WidgetTester tester) async {
        const SingleActivator pageUp = SingleActivator(LogicalKeyboardKey.pageUp);

        controller.text = longText;
        controller.selection = TextSelection.collapsed(offset: controller.text.length);

        await tester.pumpWidget(buildEditableText(style: const TextStyle(fontSize: 12)));
        await tester.pumpAndSettle();

        final double initialScrollOffset = scrollController.offset;

        expect(initialScrollOffset, scrollController.position.maxScrollExtent);
        await sendKeyCombination(tester, pageUp);
        await tester.pump();

        expect(controller.text, longText);
        expect(
          controller.selection,
          TextSelection.collapsed(offset: controller.text.length), // selection stays the same.
          reason: pageUp.toString(),
        );

        // default page up/down scroll increment is 80% of viewport dimension.
        final double newOffset = initialScrollOffset - (0.8 * scrollController.position.viewportDimension);

        expect(scrollController.offset, newOffset);
      }, variant: macOSOnly);

      testWidgets('pageUp + shift scrolls upwards and modifies selection', (WidgetTester tester) async {
        const SingleActivator pageUp = SingleActivator(LogicalKeyboardKey.pageUp, shift: true);

        controller.text = longText;
        controller.selection = TextSelection.collapsed(offset: controller.text.length);

        await tester.pumpWidget(buildEditableText(style: const TextStyle(fontSize: 12)));
        await tester.pumpAndSettle();

        final double initialScrollOffset = scrollController.offset;

        expect(initialScrollOffset, scrollController.position.maxScrollExtent);
        await sendKeyCombination(tester, pageUp);
        await tester.pump();

        expect(controller.text, longText);
        expect(
          controller.selection,
          TextSelection(baseOffset: controller.text.length, extentOffset: 232),
          reason: pageUp.toString(),
        );

        expect(scrollController.offset, lessThan(initialScrollOffset));
      }, variant: macOSOnly);

      testWidgets('pageDown scrolls 80% of viewport dimension downwards', (WidgetTester tester) async {
        const SingleActivator pageDown = SingleActivator(LogicalKeyboardKey.pageDown);

        controller.text = longText;
        controller.selection = const TextSelection.collapsed(offset: 0);

        await tester.pumpWidget(buildEditableText(style: const TextStyle(fontSize: 12)));
        await tester.pumpAndSettle();

        final double initialScrollOffset = scrollController.offset;

        expect(initialScrollOffset, 0);
        await sendKeyCombination(tester, pageDown);
        await tester.pump();

        expect(controller.text, longText);
        expect(
          controller.selection,
          const TextSelection.collapsed(offset: 0), // selection stays the same.
          reason: pageDown.toString(),
        );

        // default page up/down scroll increment is 80% of viewport dimension.
        final double newOffset = initialScrollOffset + (0.8 * scrollController.position.viewportDimension);

        expect(scrollController.offset, newOffset);
      }, variant: macOSOnly);

      testWidgets('pageDown + shift scrolls downwards and modifies selection', (WidgetTester tester) async {
        const SingleActivator pageDown = SingleActivator(LogicalKeyboardKey.pageDown, shift: true);

        controller.text = longText;
        controller.selection = const TextSelection.collapsed(offset: 0);

        await tester.pumpWidget(buildEditableText(style: const TextStyle(fontSize: 12)));
        await tester.pumpAndSettle();

        final double initialScrollOffset = scrollController.offset;

        expect(initialScrollOffset, 0);
        await sendKeyCombination(tester, pageDown);
        await tester.pump();

        expect(controller.text, longText);
        expect(
          controller.selection,
          const TextSelection(baseOffset: 0, extentOffset: 238),
          reason: pageDown.toString(),
        );

        expect(scrollController.offset, greaterThan(initialScrollOffset));
      }, variant: macOSOnly);

      testWidgets('end scrolls to the end of the text field', (WidgetTester tester) async {
        const SingleActivator end = SingleActivator(LogicalKeyboardKey.end);

        controller.text = longText;
        controller.selection = const TextSelection.collapsed(offset: 0);

        await tester.pumpWidget(buildEditableText(style: const TextStyle(fontSize: 12)));
        await tester.pumpAndSettle();

        final double initialScrollOffset = scrollController.offset;

        expect(initialScrollOffset, 0);
        await sendKeyCombination(tester, end);
        await tester.pump();

        expect(controller.text, longText);
        expect(
          controller.selection,
          const TextSelection.collapsed(offset: 0), // selection stays the same.
          reason: end.toString(),
        );

        // scrolls to end.
        final double newOffset = scrollController.position.maxScrollExtent;

        expect(scrollController.offset, newOffset);
      }, variant: macOSOnly);

      testWidgets('end + shift scrolls to the end of the text field and selects everything', (WidgetTester tester) async {
        const SingleActivator end = SingleActivator(LogicalKeyboardKey.end, shift: true);

        controller.text = longText;
        controller.selection = const TextSelection.collapsed(offset: 0);

        await tester.pumpWidget(buildEditableText(style: const TextStyle(fontSize: 12)));
        await tester.pumpAndSettle();

        final double initialScrollOffset = scrollController.offset;

        expect(initialScrollOffset, 0);
        await sendKeyCombination(tester, end);
        await tester.pump();

        expect(controller.text, longText);
        expect(
          controller.selection,
          TextSelection(baseOffset: 0, extentOffset: controller.text.length), // selection changes.
          reason: end.toString(),
        );

        // scrolls to end.
        final double newOffset = scrollController.position.maxScrollExtent;

        expect(scrollController.offset, newOffset);
      }, variant: macOSOnly);

      testWidgets('home scrolls to the beginning of the text field', (WidgetTester tester) async {
        const SingleActivator home = SingleActivator(LogicalKeyboardKey.home);

        controller.text = longText;
        controller.selection = TextSelection.collapsed(offset: controller.text.length);

        await tester.pumpWidget(buildEditableText(style: const TextStyle(fontSize: 12)));
        await tester.pumpAndSettle();

        final double initialScrollOffset = scrollController.offset;

        expect(initialScrollOffset, scrollController.position.maxScrollExtent);
        await sendKeyCombination(tester, home);
        await tester.pump();

        expect(controller.text, longText);
        expect(
          controller.selection,
          TextSelection.collapsed(offset: controller.text.length), // selection stays the same.
          reason: home.toString(),
        );

        // scrolls to beginning.
        const double newOffset = 0;

        expect(scrollController.offset, newOffset);
      }, variant: macOSOnly);

      testWidgets('home + shift scrolls to the beginning of text field and selects everything', (WidgetTester tester) async {
          const SingleActivator home = SingleActivator(LogicalKeyboardKey.home, shift: true);

          controller.text = longText;
          controller.selection = TextSelection.collapsed(offset: controller.text.length);

          await tester.pumpWidget(buildEditableText(style: const TextStyle(fontSize: 12)));
          await tester.pumpAndSettle();

          final double initialScrollOffset = scrollController.offset;

          expect(initialScrollOffset, scrollController.position.maxScrollExtent);
          await sendKeyCombination(tester, home);
          await tester.pump();

          expect(controller.text, longText);
          expect(
            controller.selection,
            TextSelection(baseOffset: controller.text.length, extentOffset: 0), // selection changes.
            reason: home.toString(),
          );

          // scrolls to beginning.
          const double newOffset = 0;

          expect(scrollController.offset, newOffset);
        }, variant: macOSOnly);
      });

    group('non-macOS', () {
      testWidgets('pageUp scrolls up and modifies selection', (WidgetTester tester) async {
        const SingleActivator pageUp = SingleActivator(LogicalKeyboardKey.pageUp);

        final int initialSelectionOffset = controller.text.length;

        controller.text = longText;
        controller.selection = TextSelection.collapsed(offset: initialSelectionOffset);

        await tester.pumpWidget(buildEditableText(style: const TextStyle(fontSize: 12)));
        await tester.pumpAndSettle();

        final double initialScrollOffset = scrollController.offset;

        expect(initialScrollOffset, scrollController.position.maxScrollExtent);
        await sendKeyCombination(tester, pageUp);
        await tester.pump();

        expect(controller.text, longText);
        expect(controller.selection.isCollapsed, isTrue);
        expect(controller.selection.baseOffset, lessThan(initialSelectionOffset));
        expect(scrollController.offset, lessThan(initialScrollOffset));
      }, variant: desktopExceptMacOS);

      testWidgets('pageUp + shift scrolls up and modifies selection', (WidgetTester tester) async {
        const SingleActivator pageUp = SingleActivator(LogicalKeyboardKey.pageUp, shift: true);

        final int initialSelectionOffset = controller.text.length;

        controller.text = longText;
        controller.selection = TextSelection.collapsed(offset: initialSelectionOffset);

        await tester.pumpWidget(buildEditableText(style: const TextStyle(fontSize: 12)));
        await tester.pumpAndSettle();

        final double initialScrollOffset = scrollController.offset;

        expect(initialScrollOffset, scrollController.position.maxScrollExtent);
        await sendKeyCombination(tester, pageUp);
        await tester.pump();

        expect(controller.text, longText);
        expect(controller.selection.isCollapsed, isFalse);
        expect(controller.selection.baseOffset, initialSelectionOffset);
        expect(controller.selection.extentOffset, lessThan(initialSelectionOffset));
        expect(scrollController.offset, lessThan(initialScrollOffset));
      }, variant: desktopExceptMacOS);

      testWidgets('pageDown scrolls down and modifies selection', (WidgetTester tester) async {
        const SingleActivator pageDown = SingleActivator(LogicalKeyboardKey.pageDown);

        const int initialSelectionOffset = 0;

        controller.text = longText;
        controller.selection = const TextSelection.collapsed(offset: initialSelectionOffset);

        await tester.pumpWidget(buildEditableText(style: const TextStyle(fontSize: 12)));
        await tester.pumpAndSettle();

        final double initialScrollOffset = scrollController.offset;

        expect(initialScrollOffset, 0);
        await sendKeyCombination(tester, pageDown);
        await tester.pump();

        expect(controller.text, longText);
        expect(controller.selection.isCollapsed, isTrue);
        expect(controller.selection.baseOffset, greaterThan(initialSelectionOffset));
        expect(scrollController.offset, greaterThan(initialScrollOffset));
      }, variant: desktopExceptMacOS);

      testWidgets('pageDown + shift scrolls down and modifies selection', (WidgetTester tester) async {
        const SingleActivator pageDown = SingleActivator(LogicalKeyboardKey.pageDown, shift: true);

        const int initialSelectionOffset = 0;

        controller.text = longText;
        controller.selection = const TextSelection.collapsed(offset: initialSelectionOffset);

        await tester.pumpWidget(buildEditableText(style: const TextStyle(fontSize: 12)));
        await tester.pumpAndSettle();

        final double initialScrollOffset = scrollController.offset;

        expect(initialScrollOffset, 0);
        await sendKeyCombination(tester, pageDown);
        await tester.pump();

        expect(controller.text, longText);
        expect(controller.selection.isCollapsed, isFalse);
        expect(controller.selection.baseOffset, initialSelectionOffset);
        expect(controller.selection.extentOffset, greaterThan(initialSelectionOffset));
        expect(scrollController.offset, greaterThan(initialScrollOffset));
      }, variant: desktopExceptMacOS);

      testWidgets('end moves selection to the end of the line, no scroll', (WidgetTester tester) async {
        const SingleActivator end = SingleActivator(LogicalKeyboardKey.end);
        const int initialSelectionOffset = 0;

        controller.text = longText;
        controller.selection = const TextSelection.collapsed(offset: initialSelectionOffset);

        await tester.pumpWidget(buildEditableText(style: const TextStyle(fontSize: 12)));
        await tester.pumpAndSettle();

        final double initialScrollOffset = scrollController.offset;

        expect(initialScrollOffset, 0);
        await sendKeyCombination(tester, end);
        await tester.pump();

        expect(controller.text, longText);
        expect(controller.selection.isCollapsed, isTrue);
        expect(controller.selection.baseOffset, greaterThan(initialSelectionOffset));
        expect(scrollController.offset, initialScrollOffset); // no scroll.
      }, variant: desktopExceptMacOS);

      testWidgets('end + shift highlights selection to the end of the line, no scroll', (WidgetTester tester) async {
        const SingleActivator end = SingleActivator(LogicalKeyboardKey.end, shift: true);
        const int initialSelectionOffset = 0;

        controller.text = longText;
        controller.selection = const TextSelection.collapsed(offset: initialSelectionOffset);

        await tester.pumpWidget(buildEditableText(style: const TextStyle(fontSize: 12)));
        await tester.pumpAndSettle();

        final double initialScrollOffset = scrollController.offset;

        expect(initialScrollOffset, 0);
        await sendKeyCombination(tester, end);
        await tester.pump();

        expect(controller.text, longText);
        expect(controller.selection.isCollapsed, isFalse);
        expect(controller.selection.baseOffset, initialSelectionOffset);
        expect(controller.selection.extentOffset, greaterThan(initialSelectionOffset));
        expect(scrollController.offset, initialScrollOffset); // no scroll.
      }, variant: desktopExceptMacOS);

      testWidgets('home moves selection to the beginning of the line, no scroll', (WidgetTester tester) async {
        const SingleActivator home = SingleActivator(LogicalKeyboardKey.home);
        final int initialSelectionOffset = controller.text.length;

        controller.text = longText;
        controller.selection = TextSelection.collapsed(offset: initialSelectionOffset);

        await tester.pumpWidget(buildEditableText(style: const TextStyle(fontSize: 12)));
        await tester.pumpAndSettle();

        final double initialScrollOffset = scrollController.offset;

        expect(initialScrollOffset, scrollController.position.maxScrollExtent);
        await sendKeyCombination(tester, home);
        await tester.pump();

        expect(controller.text, longText);
        expect(controller.selection.isCollapsed, isTrue);
        expect(controller.selection.baseOffset, lessThan(initialSelectionOffset));
        expect(scrollController.offset, initialScrollOffset); // no scroll.
      }, variant: desktopExceptMacOS);

      testWidgets('home + shift highlights selection to the beginning of the line, no scroll', (WidgetTester tester) async {
        const SingleActivator home = SingleActivator(LogicalKeyboardKey.home, shift: true);
        final int initialSelectionOffset = controller.text.length;

        controller.text = longText;
        controller.selection = TextSelection.collapsed(offset: initialSelectionOffset);

        await tester.pumpWidget(buildEditableText(style: const TextStyle(fontSize: 12)));
        await tester.pumpAndSettle();

        final double initialScrollOffset = scrollController.offset;

        expect(initialScrollOffset, scrollController.position.maxScrollExtent);
        await sendKeyCombination(tester, home);
        await tester.pump();

        expect(controller.text, longText);
        expect(controller.selection.isCollapsed, isFalse);
        expect(controller.selection.baseOffset, initialSelectionOffset);
        expect(controller.selection.extentOffset, lessThan(initialSelectionOffset));
        expect(scrollController.offset, initialScrollOffset); // no scroll.
      }, variant: desktopExceptMacOS);

      testWidgets('end + ctrl scrolls to the end of the text field and changes selection on Windows', (WidgetTester tester) async {
        const SingleActivator end = SingleActivator(LogicalKeyboardKey.end, control: true);

        controller.text = longText;
        controller.selection = const TextSelection.collapsed(offset: 0);

        await tester.pumpWidget(buildEditableText(style: const TextStyle(fontSize: 12)));
        await tester.pumpAndSettle();

        final double initialScrollOffset = scrollController.offset;

        expect(initialScrollOffset, 0);
        await sendKeyCombination(tester, end);
        await tester.pump();

        expect(controller.text, longText);
        expect(
          controller.selection,
          TextSelection.collapsed(offset: controller.text.length), // selection goes to end.
          reason: end.toString(),
        );

        // scrolls to end.
        final double newOffset = scrollController.position.maxScrollExtent;

        expect(scrollController.offset, newOffset);
      }, variant: TargetPlatformVariant.only(TargetPlatform.windows));

      testWidgets('end + shift + ctrl scrolls to the end of the text field and highlights everything on Windows', (WidgetTester tester) async {
        const SingleActivator end = SingleActivator(LogicalKeyboardKey.end, control: true, shift: true);

        controller.text = longText;
        controller.selection = const TextSelection.collapsed(offset: 0);

        await tester.pumpWidget(buildEditableText(style: const TextStyle(fontSize: 12)));
        await tester.pumpAndSettle();

        final double initialScrollOffset = scrollController.offset;

        expect(initialScrollOffset, 0);
        await sendKeyCombination(tester, end);
        await tester.pump();

        expect(controller.text, longText);
        expect(
          controller.selection,
          TextSelection(baseOffset: 0, extentOffset: controller.text.length), // selection goes to end.
          reason: end.toString(),
        );

        // scrolls to end.
        final double newOffset = scrollController.position.maxScrollExtent;

        expect(scrollController.offset, newOffset);
      }, variant: TargetPlatformVariant.only(TargetPlatform.windows));

      testWidgets('home + ctrl scrolls to the beginning of the text field and changes selection on Windows', (WidgetTester tester) async {
        const SingleActivator home = SingleActivator(LogicalKeyboardKey.home, control: true);

        controller.text = longText;
        controller.selection = TextSelection.collapsed(offset: controller.text.length);

        await tester.pumpWidget(buildEditableText(style: const TextStyle(fontSize: 12)));
        await tester.pumpAndSettle();

        final double initialScrollOffset = scrollController.offset;

        expect(initialScrollOffset, scrollController.position.maxScrollExtent);
        await sendKeyCombination(tester, home);
        await tester.pump();

        expect(controller.text, longText);
        expect(
          controller.selection,
          const TextSelection.collapsed(offset: 0), // selection goes to beginning.
          reason: home.toString(),
        );

        // scrolls to beginning.
        const double newOffset = 0;

        expect(scrollController.offset, newOffset);
      }, variant: TargetPlatformVariant.only(TargetPlatform.windows));

      testWidgets('home + shift + ctrl scrolls to the beginning of the text field and highlights everything on Windows', (WidgetTester tester) async {
            const SingleActivator home = SingleActivator(LogicalKeyboardKey.home, control: true, shift: true);

            controller.text = longText;
            controller.selection = TextSelection.collapsed(offset: controller.text.length);

            await tester.pumpWidget(buildEditableText(style: const TextStyle(fontSize: 12)));
            await tester.pumpAndSettle();

            final double initialScrollOffset = scrollController.offset;

            expect(initialScrollOffset, scrollController.position.maxScrollExtent);
            await sendKeyCombination(tester, home);
            await tester.pump();

            expect(controller.text, longText);
            expect(
              controller.selection,
              TextSelection(baseOffset: controller.text.length, extentOffset: 0), // selection goes to beginning.
              reason: home.toString(),
            );

            // scrolls to beginning.
            const double newOffset = 0;

            expect(scrollController.offset, newOffset);
          }, variant: TargetPlatformVariant.only(TargetPlatform.windows));
    });
  }, skip: !kIsWeb); // [intended] specific tests target web.
}
