// 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/semantics.dart';
import 'package:flutter/services.dart';
import 'package:flutter/widgets.dart';
import 'package:flutter_test/flutter_test.dart';

import 'semantics_tester.dart';

void main() {
  group('FocusScope', () {
    testWidgets('Can focus', (WidgetTester tester) async {
      final GlobalKey<TestFocusState> key = GlobalKey();

      await tester.pumpWidget(
        TestFocus(key: key),
      );

      expect(key.currentState!.focusNode.hasFocus, isFalse);

      FocusScope.of(key.currentContext!).requestFocus(key.currentState!.focusNode);
      await tester.pumpAndSettle();

      expect(key.currentState!.focusNode.hasFocus, isTrue);
      expect(find.text('A FOCUSED'), findsOneWidget);
    });

    testWidgets('Can unfocus', (WidgetTester tester) async {
      final GlobalKey<TestFocusState> keyA = GlobalKey();
      final GlobalKey<TestFocusState> keyB = GlobalKey();
      await tester.pumpWidget(
        Column(
          children: <Widget>[
            TestFocus(key: keyA),
            TestFocus(key: keyB, name: 'b'),
          ],
        ),
      );

      expect(keyA.currentState!.focusNode.hasFocus, isFalse);
      expect(find.text('a'), findsOneWidget);
      expect(keyB.currentState!.focusNode.hasFocus, isFalse);
      expect(find.text('b'), findsOneWidget);

      FocusScope.of(keyA.currentContext!).requestFocus(keyA.currentState!.focusNode);
      await tester.pumpAndSettle();

      expect(keyA.currentState!.focusNode.hasFocus, isTrue);
      expect(find.text('A FOCUSED'), findsOneWidget);
      expect(keyB.currentState!.focusNode.hasFocus, isFalse);
      expect(find.text('b'), findsOneWidget);

      // Set focus to the "B" node to unfocus the "A" node.
      FocusScope.of(keyB.currentContext!).requestFocus(keyB.currentState!.focusNode);
      await tester.pumpAndSettle();

      expect(keyA.currentState!.focusNode.hasFocus, isFalse);
      expect(find.text('a'), findsOneWidget);
      expect(keyB.currentState!.focusNode.hasFocus, isTrue);
      expect(find.text('B FOCUSED'), findsOneWidget);
    });

    testWidgets('Autofocus works', (WidgetTester tester) async {
      final GlobalKey<TestFocusState> keyA = GlobalKey();
      final GlobalKey<TestFocusState> keyB = GlobalKey();
      await tester.pumpWidget(
        Column(
          children: <Widget>[
            TestFocus(key: keyA),
            TestFocus(key: keyB, name: 'b', autofocus: true),
          ],
        ),
      );

      await tester.pump();

      expect(keyA.currentState!.focusNode.hasFocus, isFalse);
      expect(find.text('a'), findsOneWidget);
      expect(keyB.currentState!.focusNode.hasFocus, isTrue);
      expect(find.text('B FOCUSED'), findsOneWidget);
    });

    testWidgets('Can have multiple focused children and they update accordingly', (WidgetTester tester) async {
      final GlobalKey<TestFocusState> keyA = GlobalKey();
      final GlobalKey<TestFocusState> keyB = GlobalKey();

      await tester.pumpWidget(
        Column(
          children: <Widget>[
            TestFocus(
              key: keyA,
              autofocus: true,
            ),
            TestFocus(
              key: keyB,
              name: 'b',
            ),
          ],
        ),
      );

      // Autofocus is delayed one frame.
      await tester.pump();
      expect(keyA.currentState!.focusNode.hasFocus, isTrue);
      expect(find.text('A FOCUSED'), findsOneWidget);
      expect(keyB.currentState!.focusNode.hasFocus, isFalse);
      expect(find.text('b'), findsOneWidget);
      await tester.tap(find.text('A FOCUSED'));
      await tester.pump();
      expect(keyA.currentState!.focusNode.hasFocus, isTrue);
      expect(find.text('A FOCUSED'), findsOneWidget);
      expect(keyB.currentState!.focusNode.hasFocus, isFalse);
      expect(find.text('b'), findsOneWidget);
      await tester.tap(find.text('b'));
      await tester.pump();
      expect(keyA.currentState!.focusNode.hasFocus, isFalse);
      expect(find.text('a'), findsOneWidget);
      expect(keyB.currentState!.focusNode.hasFocus, isTrue);
      expect(find.text('B FOCUSED'), findsOneWidget);
      await tester.tap(find.text('a'));
      await tester.pump();
      expect(keyA.currentState!.focusNode.hasFocus, isTrue);
      expect(find.text('A FOCUSED'), findsOneWidget);
      expect(keyB.currentState!.focusNode.hasFocus, isFalse);
      expect(find.text('b'), findsOneWidget);
    });

    // This moves a focus node first into a focus scope that is added to its
    // parent, and then out of that focus scope again.
    testWidgets('Can move focus in and out of FocusScope', (WidgetTester tester) async {
      final FocusScopeNode parentFocusScope = FocusScopeNode(debugLabel: 'Parent Scope Node');
      final FocusScopeNode childFocusScope = FocusScopeNode(debugLabel: 'Child Scope Node');
      final GlobalKey<TestFocusState> key = GlobalKey();

      // Initially create the focus inside of the parent FocusScope.
      await tester.pumpWidget(
        FocusScope(
          debugLabel: 'Parent Scope',
          node: parentFocusScope,
          autofocus: true,
          child: Column(
            children: <Widget>[
              TestFocus(
                key: key,
                debugLabel: 'Child',
              ),
            ],
          ),
        ),
      );

      expect(key.currentState!.focusNode.hasFocus, isFalse);
      expect(find.text('a'), findsOneWidget);
      FocusScope.of(key.currentContext!).requestFocus(key.currentState!.focusNode);
      await tester.pumpAndSettle();

      expect(key.currentState!.focusNode.hasFocus, isTrue);
      expect(find.text('A FOCUSED'), findsOneWidget);

      expect(parentFocusScope, hasAGoodToStringDeep);
      expect(
        parentFocusScope.toStringDeep(),
        equalsIgnoringHashCodes(
          'FocusScopeNode#00000(Parent Scope Node [IN FOCUS PATH])\n'
          ' │ context: FocusScope\n'
          ' │ IN FOCUS PATH\n'
          ' │ focusedChildren: FocusNode#00000(Child [PRIMARY FOCUS])\n'
          ' │\n'
          ' └─Child 1: FocusNode#00000(Child [PRIMARY FOCUS])\n'
          '     context: Focus\n'
          '     PRIMARY FOCUS\n',
        ),
      );

      expect(FocusManager.instance.rootScope, hasAGoodToStringDeep);
      expect(
        FocusManager.instance.rootScope.toStringDeep(minLevel: DiagnosticLevel.info),
        equalsIgnoringHashCodes(
          'FocusScopeNode#00000(Root Focus Scope [IN FOCUS PATH])\n'
          ' │ IN FOCUS PATH\n'
          ' │ focusedChildren: FocusScopeNode#00000(Parent Scope Node [IN FOCUS\n'
          ' │   PATH])\n'
          ' │\n'
          ' └─Child 1: FocusScopeNode#00000(Parent Scope Node [IN FOCUS PATH])\n'
          '   │ context: FocusScope\n'
          '   │ IN FOCUS PATH\n'
          '   │ focusedChildren: FocusNode#00000(Child [PRIMARY FOCUS])\n'
          '   │\n'
          '   └─Child 1: FocusNode#00000(Child [PRIMARY FOCUS])\n'
          '       context: Focus\n'
          '       PRIMARY FOCUS\n',
        ),
      );

      // Add the child focus scope to the focus tree.
      final FocusAttachment childAttachment = childFocusScope.attach(key.currentContext);
      parentFocusScope.setFirstFocus(childFocusScope);
      await tester.pumpAndSettle();
      expect(childFocusScope.isFirstFocus, isTrue);

      // Now add the child focus scope with no child focusable in it to the tree.
      await tester.pumpWidget(
        FocusScope(
          debugLabel: 'Parent Scope',
          node: parentFocusScope,
          child: Column(
            children: <Widget>[
              TestFocus(
                key: key,
                debugLabel: 'Child',
              ),
              FocusScope(
                debugLabel: 'Child Scope',
                node: childFocusScope,
                child: Container(),
              ),
            ],
          ),
        ),
      );

      expect(key.currentState!.focusNode.hasFocus, isFalse);
      expect(find.text('a'), findsOneWidget);

      // Now move the existing focus node into the child focus scope.
      await tester.pumpWidget(
        FocusScope(
          debugLabel: 'Parent Scope',
          node: parentFocusScope,
          child: Column(
            children: <Widget>[
              FocusScope(
                debugLabel: 'Child Scope',
                node: childFocusScope,
                child: TestFocus(
                  key: key,
                  debugLabel: 'Child',
                ),
              ),
            ],
          ),
        ),
      );

      await tester.pumpAndSettle();

      expect(key.currentState!.focusNode.hasFocus, isFalse);
      expect(find.text('a'), findsOneWidget);

      // Now remove the child focus scope.
      await tester.pumpWidget(
        FocusScope(
          debugLabel: 'Parent Scope',
          node: parentFocusScope,
          child: Column(
            children: <Widget>[
              TestFocus(
                key: key,
                debugLabel: 'Child',
              ),
            ],
          ),
        ),
      );

      await tester.pumpAndSettle();
      expect(key.currentState!.focusNode.hasFocus, isFalse);
      expect(find.text('a'), findsOneWidget);

      // Must detach the child because we had to attach it in order to call
      // setFirstFocus before adding to the widget.
      childAttachment.detach();
    });

    testWidgets('Setting first focus requests focus for the scope properly.', (WidgetTester tester) async {
      final FocusScopeNode parentFocusScope = FocusScopeNode(debugLabel: 'Parent Scope Node');
      final FocusScopeNode childFocusScope1 = FocusScopeNode(debugLabel: 'Child Scope Node 1');
      final FocusScopeNode childFocusScope2 = FocusScopeNode(debugLabel: 'Child Scope Node 2');
      final GlobalKey<TestFocusState> keyA = GlobalKey(debugLabel: 'Key A');
      final GlobalKey<TestFocusState> keyB = GlobalKey(debugLabel: 'Key B');
      final GlobalKey<TestFocusState> keyC = GlobalKey(debugLabel: 'Key C');

      await tester.pumpWidget(
        FocusScope(
          debugLabel: 'Parent Scope',
          node: parentFocusScope,
          child: Column(
            children: <Widget>[
              FocusScope(
                debugLabel: 'Child Scope 1',
                node: childFocusScope1,
                child: Column(
                  children: <Widget>[
                    TestFocus(
                      key: keyA,
                      autofocus: true,
                      debugLabel: 'Child A',
                    ),
                    TestFocus(
                      key: keyB,
                      name: 'b',
                      debugLabel: 'Child B',
                    ),
                  ],
                ),
              ),
              FocusScope(
                debugLabel: 'Child Scope 2',
                node: childFocusScope2,
                child: TestFocus(
                  key: keyC,
                  name: 'c',
                  debugLabel: 'Child C',
                ),
              ),
            ],
          ),
        ),
      );

      await tester.pumpAndSettle();

      expect(keyA.currentState!.focusNode.hasFocus, isTrue);
      expect(find.text('A FOCUSED'), findsOneWidget);

      parentFocusScope.setFirstFocus(childFocusScope2);
      await tester.pumpAndSettle();

      expect(keyA.currentState!.focusNode.hasFocus, isFalse);
      expect(find.text('a'), findsOneWidget);

      parentFocusScope.setFirstFocus(childFocusScope1);
      await tester.pumpAndSettle();

      expect(keyA.currentState!.focusNode.hasFocus, isTrue);
      expect(find.text('A FOCUSED'), findsOneWidget);

      keyB.currentState!.focusNode.requestFocus();
      await tester.pumpAndSettle();

      expect(keyB.currentState!.focusNode.hasFocus, isTrue);
      expect(find.text('B FOCUSED'), findsOneWidget);
      expect(parentFocusScope.isFirstFocus, isTrue);
      expect(childFocusScope1.isFirstFocus, isTrue);

      parentFocusScope.setFirstFocus(childFocusScope2);
      await tester.pumpAndSettle();

      expect(keyB.currentState!.focusNode.hasFocus, isFalse);
      expect(find.text('b'), findsOneWidget);
      expect(parentFocusScope.isFirstFocus, isTrue);
      expect(childFocusScope1.isFirstFocus, isFalse);
      expect(childFocusScope2.isFirstFocus, isTrue);

      keyC.currentState!.focusNode.requestFocus();
      await tester.pumpAndSettle();

      expect(keyB.currentState!.focusNode.hasFocus, isFalse);
      expect(find.text('b'), findsOneWidget);
      expect(keyC.currentState!.focusNode.hasFocus, isTrue);
      expect(find.text('C FOCUSED'), findsOneWidget);
      expect(parentFocusScope.isFirstFocus, isTrue);
      expect(childFocusScope1.isFirstFocus, isFalse);
      expect(childFocusScope2.isFirstFocus, isTrue);

      childFocusScope1.requestFocus();
      await tester.pumpAndSettle();
      expect(keyB.currentState!.focusNode.hasFocus, isTrue);
      expect(find.text('B FOCUSED'), findsOneWidget);
      expect(keyC.currentState!.focusNode.hasFocus, isFalse);
      expect(find.text('c'), findsOneWidget);
      expect(parentFocusScope.isFirstFocus, isTrue);
      expect(childFocusScope1.isFirstFocus, isTrue);
      expect(childFocusScope2.isFirstFocus, isFalse);
    });

    testWidgets('Removing focused widget moves focus to next widget', (WidgetTester tester) async {
      final GlobalKey<TestFocusState> keyA = GlobalKey();
      final GlobalKey<TestFocusState> keyB = GlobalKey();

      await tester.pumpWidget(
        Column(
          children: <Widget>[
            TestFocus(
              key: keyA,
            ),
            TestFocus(
              key: keyB,
              name: 'b',
            ),
          ],
        ),
      );

      FocusScope.of(keyA.currentContext!).requestFocus(keyA.currentState!.focusNode);

      await tester.pumpAndSettle();

      expect(keyA.currentState!.focusNode.hasFocus, isTrue);
      expect(find.text('A FOCUSED'), findsOneWidget);
      expect(keyB.currentState!.focusNode.hasFocus, isFalse);
      expect(find.text('b'), findsOneWidget);

      await tester.pumpWidget(
        Column(
          children: <Widget>[
            TestFocus(
              key: keyB,
              name: 'b',
            ),
          ],
        ),
      );

      await tester.pump();

      expect(keyB.currentState!.focusNode.hasFocus, isFalse);
      expect(find.text('b'), findsOneWidget);
    });

    testWidgets('Adding a new FocusScope attaches the child it to its parent.', (WidgetTester tester) async {
      final GlobalKey<TestFocusState> keyA = GlobalKey();
      final FocusScopeNode parentFocusScope = FocusScopeNode(debugLabel: 'Parent Scope Node');
      final FocusScopeNode childFocusScope = FocusScopeNode(debugLabel: 'Child Scope Node');

      await tester.pumpWidget(
        FocusScope(
          node: childFocusScope,
          child: TestFocus(
            debugLabel: 'Child',
            key: keyA,
          ),
        ),
      );

      FocusScope.of(keyA.currentContext!).requestFocus(keyA.currentState!.focusNode);
      expect(FocusScope.of(keyA.currentContext!), equals(childFocusScope));
      expect(Focus.of(keyA.currentContext!, scopeOk: true), equals(childFocusScope));
      FocusManager.instance.rootScope.setFirstFocus(FocusScope.of(keyA.currentContext!));

      await tester.pumpAndSettle();

      expect(keyA.currentState!.focusNode.hasFocus, isTrue);
      expect(find.text('A FOCUSED'), findsOneWidget);
      expect(childFocusScope.isFirstFocus, isTrue);

      await tester.pumpWidget(
        FocusScope(
          node: parentFocusScope,
          child: FocusScope(
            node: childFocusScope,
            child: TestFocus(
              debugLabel: 'Child',
              key: keyA,
            ),
          ),
        ),
      );

      await tester.pump();
      expect(childFocusScope.isFirstFocus, isTrue);
      // Node keeps it's focus when moved to the new scope.
      expect(keyA.currentState!.focusNode.hasFocus, isTrue);
      expect(find.text('A FOCUSED'), findsOneWidget);
    });

    testWidgets('Setting parentNode determines focus tree hierarchy.', (WidgetTester tester) async {
      final FocusNode topNode = FocusNode(debugLabel: 'Top');
      final FocusNode parentNode = FocusNode(debugLabel: 'Parent');
      final FocusNode childNode = FocusNode(debugLabel: 'Child');
      final FocusNode insertedNode = FocusNode(debugLabel: 'Inserted');

      await tester.pumpWidget(
        FocusScope(
          child: Focus.withExternalFocusNode(
            focusNode: topNode,
            child: Column(
              children: <Widget>[
                Focus.withExternalFocusNode(
                  focusNode: parentNode,
                  child: const SizedBox(),
                ),
                Focus.withExternalFocusNode(
                  focusNode: childNode,
                  parentNode: parentNode,
                  autofocus: true,
                  child: const SizedBox(),
                )
              ],
            ),
          ),
        ),
      );
      await tester.pump();

      expect(childNode.hasPrimaryFocus, isTrue);
      expect(parentNode.hasFocus, isTrue);
      expect(topNode.hasFocus, isTrue);

      // Check that inserting a Focus in between doesn't reparent the child.
      await tester.pumpWidget(
        FocusScope(
          child: Focus.withExternalFocusNode(
            focusNode: topNode,
            child: Column(
              children: <Widget>[
                Focus.withExternalFocusNode(
                  focusNode: parentNode,
                  child: const SizedBox(),
                ),
                Focus.withExternalFocusNode(
                  focusNode: insertedNode,
                  child: Focus.withExternalFocusNode(
                    focusNode: childNode,
                    parentNode: parentNode,
                    autofocus: true,
                    child: const SizedBox(),
                  ),
                )
              ],
            ),
          ),
        ),
      );
      await tester.pump();

      expect(childNode.hasPrimaryFocus, isTrue);
      expect(parentNode.hasFocus, isTrue);
      expect(topNode.hasFocus, isTrue);
      expect(insertedNode.hasFocus, isFalse);
    });

    testWidgets('Setting parentNode determines focus scope tree hierarchy.', (WidgetTester tester) async {
      final FocusScopeNode topNode = FocusScopeNode(debugLabel: 'Top');
      final FocusScopeNode parentNode = FocusScopeNode(debugLabel: 'Parent');
      final FocusScopeNode childNode = FocusScopeNode(debugLabel: 'Child');
      final FocusScopeNode insertedNode = FocusScopeNode(debugLabel: 'Inserted');

      await tester.pumpWidget(
        FocusScope.withExternalFocusNode(
            focusScopeNode: topNode,
            child: Column(
              children: <Widget>[
                FocusScope.withExternalFocusNode(
                  focusScopeNode: parentNode,
                  child: const SizedBox(),
                ),
                FocusScope.withExternalFocusNode(
                  focusScopeNode: childNode,
                  parentNode: parentNode,
                  child: const Focus(
                    autofocus: true,
                    child: SizedBox(),
                  ),
                )
              ],
            ),
          ),
      );
      await tester.pump();

      expect(childNode.hasFocus, isTrue);
      expect(parentNode.hasFocus, isTrue);
      expect(topNode.hasFocus, isTrue);

      // Check that inserting a Focus in between doesn't reparent the child.
      await tester.pumpWidget(
        FocusScope.withExternalFocusNode(
            focusScopeNode: topNode,
            child: Column(
              children: <Widget>[
                FocusScope.withExternalFocusNode(
                  focusScopeNode: parentNode,
                  child: const SizedBox(),
                ),
                FocusScope.withExternalFocusNode(
                  focusScopeNode: insertedNode,
                  child: FocusScope.withExternalFocusNode(
                    focusScopeNode: childNode,
                    parentNode: parentNode,
                    child: const Focus(
                    autofocus: true,
                    child: SizedBox(),
                  ),
                  ),
                )
              ],
            ),
          ),
      );
      await tester.pump();

      expect(childNode.hasFocus, isTrue);
      expect(parentNode.hasFocus, isTrue);
      expect(topNode.hasFocus, isTrue);
      expect(insertedNode.hasFocus, isFalse);
    });

    // Arguably, this isn't correct behavior, but it is what happens now.
    testWidgets("Removing focused widget doesn't move focus to next widget within FocusScope", (WidgetTester tester) async {
      final GlobalKey<TestFocusState> keyA = GlobalKey();
      final GlobalKey<TestFocusState> keyB = GlobalKey();
      final FocusScopeNode parentFocusScope = FocusScopeNode(debugLabel: 'Parent Scope');

      await tester.pumpWidget(
        FocusScope(
          debugLabel: 'Parent Scope',
          node: parentFocusScope,
          autofocus: true,
          child: Column(
            children: <Widget>[
              TestFocus(
                debugLabel: 'Widget A',
                key: keyA,
              ),
              TestFocus(
                debugLabel: 'Widget B',
                key: keyB,
                name: 'b',
              ),
            ],
          ),
        ),
      );

      FocusScope.of(keyA.currentContext!).requestFocus(keyA.currentState!.focusNode);
      final FocusScopeNode scope = FocusScope.of(keyA.currentContext!);
      FocusManager.instance.rootScope.setFirstFocus(scope);

      await tester.pumpAndSettle();

      expect(keyA.currentState!.focusNode.hasFocus, isTrue);
      expect(find.text('A FOCUSED'), findsOneWidget);
      expect(keyB.currentState!.focusNode.hasFocus, isFalse);
      expect(find.text('b'), findsOneWidget);

      await tester.pumpWidget(
        FocusScope(
          node: parentFocusScope,
          child: Column(
            children: <Widget>[
              TestFocus(
                key: keyB,
                name: 'b',
              ),
            ],
          ),
        ),
      );

      await tester.pump();

      expect(keyB.currentState!.focusNode.hasFocus, isFalse);
      expect(find.text('b'), findsOneWidget);
    });

    testWidgets('Removing a FocusScope removes its node from the tree', (WidgetTester tester) async {
      final GlobalKey<TestFocusState> keyA = GlobalKey();
      final GlobalKey<TestFocusState> keyB = GlobalKey();
      final GlobalKey<TestFocusState> scopeKeyA = GlobalKey();
      final GlobalKey<TestFocusState> scopeKeyB = GlobalKey();
      final FocusScopeNode parentFocusScope = FocusScopeNode(debugLabel: 'Parent Scope');

      // This checks both FocusScopes that have their own nodes, as well as those
      // that use external nodes.
      await tester.pumpWidget(
        FocusTraversalGroup(
          child: Column(
            children: <Widget>[
              FocusScope(
                key: scopeKeyA,
                node: parentFocusScope,
                child: Column(
                  children: <Widget>[
                    TestFocus(
                      debugLabel: 'Child A',
                      key: keyA,
                    ),
                  ],
                ),
              ),
              FocusScope(
                key: scopeKeyB,
                child: Column(
                  children: <Widget>[
                    TestFocus(
                      debugLabel: 'Child B',
                      key: keyB,
                      name: 'b',
                    ),
                  ],
                ),
              ),
            ],
          ),
        ),
      );

      FocusScope.of(keyB.currentContext!).requestFocus(keyB.currentState!.focusNode);
      FocusScope.of(keyA.currentContext!).requestFocus(keyA.currentState!.focusNode);
      final FocusScopeNode aScope = FocusScope.of(keyA.currentContext!);
      final FocusScopeNode bScope = FocusScope.of(keyB.currentContext!);
      FocusManager.instance.rootScope.setFirstFocus(bScope);
      FocusManager.instance.rootScope.setFirstFocus(aScope);

      await tester.pumpAndSettle();

      expect(FocusScope.of(keyA.currentContext!).isFirstFocus, isTrue);
      expect(keyA.currentState!.focusNode.hasFocus, isTrue);
      expect(find.text('A FOCUSED'), findsOneWidget);
      expect(keyB.currentState!.focusNode.hasFocus, isFalse);
      expect(find.text('b'), findsOneWidget);

      await tester.pumpWidget(Container());

      expect(FocusManager.instance.rootScope.children, isEmpty);
    });

    // By "pinned", it means kept in the tree by a GlobalKey.
    testWidgets("Removing pinned focused scope doesn't move focus to focused widget within next FocusScope", (WidgetTester tester) async {
      final GlobalKey<TestFocusState> keyA = GlobalKey();
      final GlobalKey<TestFocusState> keyB = GlobalKey();
      final GlobalKey<TestFocusState> scopeKeyA = GlobalKey();
      final GlobalKey<TestFocusState> scopeKeyB = GlobalKey();
      final FocusScopeNode parentFocusScope1 = FocusScopeNode(debugLabel: 'Parent Scope 1');
      final FocusScopeNode parentFocusScope2 = FocusScopeNode(debugLabel: 'Parent Scope 2');

      await tester.pumpWidget(
        FocusTraversalGroup(
          child: Column(
            children: <Widget>[
              FocusScope(
                key: scopeKeyA,
                node: parentFocusScope1,
                child: Column(
                  children: <Widget>[
                    TestFocus(
                      debugLabel: 'Child A',
                      key: keyA,
                    ),
                  ],
                ),
              ),
              FocusScope(
                key: scopeKeyB,
                node: parentFocusScope2,
                child: Column(
                  children: <Widget>[
                    TestFocus(
                      debugLabel: 'Child B',
                      key: keyB,
                      name: 'b',
                    ),
                  ],
                ),
              ),
            ],
          ),
        ),
      );

      FocusScope.of(keyB.currentContext!).requestFocus(keyB.currentState!.focusNode);
      FocusScope.of(keyA.currentContext!).requestFocus(keyA.currentState!.focusNode);
      final FocusScopeNode bScope = FocusScope.of(keyB.currentContext!);
      final FocusScopeNode aScope = FocusScope.of(keyA.currentContext!);
      FocusManager.instance.rootScope.setFirstFocus(bScope);
      FocusManager.instance.rootScope.setFirstFocus(aScope);

      await tester.pumpAndSettle();

      expect(FocusScope.of(keyA.currentContext!).isFirstFocus, isTrue);
      expect(keyA.currentState!.focusNode.hasFocus, isTrue);
      expect(find.text('A FOCUSED'), findsOneWidget);
      expect(keyB.currentState!.focusNode.hasFocus, isFalse);
      expect(find.text('b'), findsOneWidget);

      await tester.pumpWidget(
        FocusTraversalGroup(
          child: Column(
            children: <Widget>[
              FocusScope(
                key: scopeKeyB,
                node: parentFocusScope2,
                child: Column(
                  children: <Widget>[
                    TestFocus(
                      debugLabel: 'Child B',
                      key: keyB,
                      name: 'b',
                      autofocus: true,
                    ),
                  ],
                ),
              ),
            ],
          ),
        ),
      );

      await tester.pump();

      expect(keyB.currentState!.focusNode.hasFocus, isTrue);
      expect(find.text('B FOCUSED'), findsOneWidget);
    });

    testWidgets("Removing unpinned focused scope doesn't move focus to focused widget within next FocusScope", (WidgetTester tester) async {
      final GlobalKey<TestFocusState> keyA = GlobalKey();
      final GlobalKey<TestFocusState> keyB = GlobalKey();
      final FocusScopeNode parentFocusScope1 = FocusScopeNode(debugLabel: 'Parent Scope 1');
      final FocusScopeNode parentFocusScope2 = FocusScopeNode(debugLabel: 'Parent Scope 2');

      await tester.pumpWidget(
        FocusTraversalGroup(
          child: Column(
            children: <Widget>[
              FocusScope(
                node: parentFocusScope1,
                child: Column(
                  children: <Widget>[
                    TestFocus(
                      debugLabel: 'Child A',
                      key: keyA,
                    ),
                  ],
                ),
              ),
              FocusScope(
                node: parentFocusScope2,
                child: Column(
                  children: <Widget>[
                    TestFocus(
                      debugLabel: 'Child B',
                      key: keyB,
                      name: 'b',
                    ),
                  ],
                ),
              ),
            ],
          ),
        ),
      );

      FocusScope.of(keyB.currentContext!).requestFocus(keyB.currentState!.focusNode);
      FocusScope.of(keyA.currentContext!).requestFocus(keyA.currentState!.focusNode);
      final FocusScopeNode bScope = FocusScope.of(keyB.currentContext!);
      final FocusScopeNode aScope = FocusScope.of(keyA.currentContext!);
      FocusManager.instance.rootScope.setFirstFocus(bScope);
      FocusManager.instance.rootScope.setFirstFocus(aScope);

      await tester.pumpAndSettle();

      expect(FocusScope.of(keyA.currentContext!).isFirstFocus, isTrue);
      expect(keyA.currentState!.focusNode.hasFocus, isTrue);
      expect(find.text('A FOCUSED'), findsOneWidget);
      expect(keyB.currentState!.focusNode.hasFocus, isFalse);
      expect(find.text('b'), findsOneWidget);

      await tester.pumpWidget(
        FocusTraversalGroup(
          child: Column(
            children: <Widget>[
              FocusScope(
                node: parentFocusScope2,
                child: Column(
                  children: <Widget>[
                    TestFocus(
                      debugLabel: 'Child B',
                      key: keyB,
                      name: 'b',
                      autofocus: true,
                    ),
                  ],
                ),
              ),
            ],
          ),
        ),
      );
      await tester.pump();

      expect(keyB.currentState!.focusNode.hasFocus, isTrue);
      expect(find.text('B FOCUSED'), findsOneWidget);
    });

    testWidgets('Moving widget from one scope to another retains focus', (WidgetTester tester) async {
      final FocusScopeNode parentFocusScope1 = FocusScopeNode();
      final FocusScopeNode parentFocusScope2 = FocusScopeNode();
      final GlobalKey<TestFocusState> keyA = GlobalKey();
      final GlobalKey<TestFocusState> keyB = GlobalKey();

      await tester.pumpWidget(
        Column(
          children: <Widget>[
            FocusScope(
              node: parentFocusScope1,
              child: Column(
                children: <Widget>[
                  TestFocus(
                    key: keyA,
                  ),
                ],
              ),
            ),
            FocusScope(
              node: parentFocusScope2,
              child: Column(
                children: <Widget>[
                  TestFocus(
                    key: keyB,
                    name: 'b',
                  ),
                ],
              ),
            ),
          ],
        ),
      );

      FocusScope.of(keyA.currentContext!).requestFocus(keyA.currentState!.focusNode);
      final FocusScopeNode aScope = FocusScope.of(keyA.currentContext!);
      FocusManager.instance.rootScope.setFirstFocus(aScope);

      await tester.pumpAndSettle();

      expect(keyA.currentState!.focusNode.hasFocus, isTrue);
      expect(find.text('A FOCUSED'), findsOneWidget);
      expect(keyB.currentState!.focusNode.hasFocus, isFalse);
      expect(find.text('b'), findsOneWidget);

      await tester.pumpWidget(
        Column(
          children: <Widget>[
            FocusScope(
              node: parentFocusScope1,
              child: Column(
                children: <Widget>[
                  TestFocus(
                    key: keyB,
                    name: 'b',
                  ),
                ],
              ),
            ),
            FocusScope(
              node: parentFocusScope2,
              child: Column(
                children: <Widget>[
                  TestFocus(
                    key: keyA,
                  ),
                ],
              ),
            ),
          ],
        ),
      );

      await tester.pump();

      expect(keyA.currentState!.focusNode.hasFocus, isTrue);
      expect(find.text('A FOCUSED'), findsOneWidget);
      expect(keyB.currentState!.focusNode.hasFocus, isFalse);
      expect(find.text('b'), findsOneWidget);
    });

    testWidgets('Moving FocusScopeNodes retains focus', (WidgetTester tester) async {
      final FocusScopeNode parentFocusScope1 = FocusScopeNode(debugLabel: 'Scope 1');
      final FocusScopeNode parentFocusScope2 = FocusScopeNode(debugLabel: 'Scope 2');
      final GlobalKey<TestFocusState> keyA = GlobalKey();
      final GlobalKey<TestFocusState> keyB = GlobalKey();

      await tester.pumpWidget(
        Column(
          children: <Widget>[
            FocusScope(
              node: parentFocusScope1,
              child: Column(
                children: <Widget>[
                  TestFocus(
                    debugLabel: 'Child A',
                    key: keyA,
                  ),
                ],
              ),
            ),
            FocusScope(
              node: parentFocusScope2,
              child: Column(
                children: <Widget>[
                  TestFocus(
                    debugLabel: 'Child B',
                    key: keyB,
                    name: 'b',
                  ),
                ],
              ),
            ),
          ],
        ),
      );

      FocusScope.of(keyA.currentContext!).requestFocus(keyA.currentState!.focusNode);
      final FocusScopeNode aScope = FocusScope.of(keyA.currentContext!);
      FocusManager.instance.rootScope.setFirstFocus(aScope);

      await tester.pumpAndSettle();

      expect(keyA.currentState!.focusNode.hasFocus, isTrue);
      expect(find.text('A FOCUSED'), findsOneWidget);
      expect(keyB.currentState!.focusNode.hasFocus, isFalse);
      expect(find.text('b'), findsOneWidget);

      // This just swaps the FocusScopeNodes that the FocusScopes have in them.
      await tester.pumpWidget(
        Column(
          children: <Widget>[
            FocusScope(
              node: parentFocusScope2,
              child: Column(
                children: <Widget>[
                  TestFocus(
                    debugLabel: 'Child A',
                    key: keyA,
                  ),
                ],
              ),
            ),
            FocusScope(
              node: parentFocusScope1,
              child: Column(
                children: <Widget>[
                  TestFocus(
                    debugLabel: 'Child B',
                    key: keyB,
                    name: 'b',
                  ),
                ],
              ),
            ),
          ],
        ),
      );

      await tester.pump();

      expect(keyA.currentState!.focusNode.hasFocus, isTrue);
      expect(find.text('A FOCUSED'), findsOneWidget);
      expect(keyB.currentState!.focusNode.hasFocus, isFalse);
      expect(find.text('b'), findsOneWidget);
    });

    testWidgets('Can focus root node.', (WidgetTester tester) async {
      final GlobalKey key1 = GlobalKey(debugLabel: '1');
      await tester.pumpWidget(
        Focus(
          key: key1,
          child: Container(),
        ),
      );

      final Element firstElement = tester.element(find.byKey(key1));
      final FocusScopeNode rootNode = FocusScope.of(firstElement);
      rootNode.requestFocus();

      await tester.pump();

      expect(rootNode.hasFocus, isTrue);
      expect(rootNode, equals(firstElement.owner!.focusManager.rootScope));
    });

    testWidgets('Can autofocus a node.', (WidgetTester tester) async {
      final FocusNode focusNode = FocusNode(debugLabel: 'Test Node');
      await tester.pumpWidget(
        Focus(
          focusNode: focusNode,
          child: Container(),
        ),
      );

      await tester.pump();
      expect(focusNode.hasPrimaryFocus, isFalse);

      await tester.pumpWidget(
        Focus(
          autofocus: true,
          focusNode: focusNode,
          child: Container(),
        ),
      );

      await tester.pump();
      expect(focusNode.hasPrimaryFocus, isTrue);
    });

    testWidgets("Won't autofocus a node if one is already focused.", (WidgetTester tester) async {
      final FocusNode focusNodeA = FocusNode(debugLabel: 'Test Node A');
      final FocusNode focusNodeB = FocusNode(debugLabel: 'Test Node B');
      await tester.pumpWidget(
        Column(
          children: <Widget>[
            Focus(
              focusNode: focusNodeA,
              autofocus: true,
              child: Container(),
            ),
          ],
        ),
      );

      await tester.pump();
      expect(focusNodeA.hasPrimaryFocus, isTrue);

      await tester.pumpWidget(
        Column(
          children: <Widget>[
            Focus(
              focusNode: focusNodeA,
              child: Container(),
            ),
            Focus(
              focusNode: focusNodeB,
              autofocus: true,
              child: Container(),
            ),
          ],
        ),
      );

      await tester.pump();
      expect(focusNodeB.hasPrimaryFocus, isFalse);
      expect(focusNodeA.hasPrimaryFocus, isTrue);
    });

    testWidgets("FocusScope doesn't update the focusNode attributes when the widget updates if withExternalFocusNode is used", (WidgetTester tester) async {
      final GlobalKey key1 = GlobalKey(debugLabel: '1');
      final FocusScopeNode focusScopeNode = FocusScopeNode();
      bool? keyEventHandled;
      KeyEventResult handleCallback(FocusNode node, RawKeyEvent event) {
        keyEventHandled = true;
        return KeyEventResult.handled;
      }
      KeyEventResult handleEventCallback(FocusNode node, KeyEvent event) {
        keyEventHandled = true;
        return KeyEventResult.handled;
      }
      KeyEventResult ignoreCallback(FocusNode node, RawKeyEvent event) => KeyEventResult.ignored;
      KeyEventResult ignoreEventCallback(FocusNode node, KeyEvent event) => KeyEventResult.ignored;
      focusScopeNode.onKey = ignoreCallback;
      focusScopeNode.onKeyEvent = ignoreEventCallback;
      focusScopeNode.descendantsAreFocusable = false;
      focusScopeNode.descendantsAreTraversable = false;
      focusScopeNode.skipTraversal = false;
      focusScopeNode.canRequestFocus = true;
      FocusScope focusScopeWidget = FocusScope.withExternalFocusNode(
        focusScopeNode: focusScopeNode,
        child: Container(key: key1),
      );
      await tester.pumpWidget(focusScopeWidget);
      expect(focusScopeNode.onKey, equals(ignoreCallback));
      expect(focusScopeNode.onKeyEvent, equals(ignoreEventCallback));
      expect(focusScopeNode.descendantsAreFocusable, isFalse);
      expect(focusScopeNode.descendantsAreTraversable, isFalse);
      expect(focusScopeNode.skipTraversal, isFalse);
      expect(focusScopeNode.canRequestFocus, isTrue);
      expect(focusScopeWidget.onKey, equals(focusScopeNode.onKey));
      expect(focusScopeWidget.onKeyEvent, equals(focusScopeNode.onKeyEvent));
      expect(focusScopeWidget.descendantsAreFocusable, equals(focusScopeNode.descendantsAreFocusable));
      expect(focusScopeWidget.descendantsAreTraversable, equals(focusScopeNode.descendantsAreTraversable));
      expect(focusScopeWidget.skipTraversal, equals(focusScopeNode.skipTraversal));
      expect(focusScopeWidget.canRequestFocus, equals(focusScopeNode.canRequestFocus));

      FocusScope.of(key1.currentContext!).requestFocus();
      await tester.pump();
      await tester.sendKeyEvent(LogicalKeyboardKey.enter);
      expect(keyEventHandled, isNull);

      focusScopeNode.onKey = handleCallback;
      focusScopeNode.onKeyEvent = handleEventCallback;
      focusScopeNode.descendantsAreFocusable = true;
      focusScopeNode.descendantsAreTraversable = true;
      focusScopeWidget = FocusScope.withExternalFocusNode(
        focusScopeNode: focusScopeNode,
        child: Container(key: key1),
      );
      await tester.pumpWidget(focusScopeWidget);
      expect(focusScopeNode.onKey, equals(handleCallback));
      expect(focusScopeNode.onKeyEvent, equals(handleEventCallback));
      expect(focusScopeNode.descendantsAreFocusable, isTrue);
      expect(focusScopeNode.descendantsAreTraversable, isTrue);
      expect(focusScopeNode.skipTraversal, isFalse);
      expect(focusScopeNode.canRequestFocus, isTrue);
      expect(focusScopeWidget.onKey, equals(focusScopeNode.onKey));
      expect(focusScopeWidget.onKeyEvent, equals(focusScopeNode.onKeyEvent));
      expect(focusScopeWidget.descendantsAreFocusable, equals(focusScopeNode.descendantsAreFocusable));
      expect(focusScopeWidget.descendantsAreTraversable, equals(focusScopeNode.descendantsAreTraversable));
      expect(focusScopeWidget.skipTraversal, equals(focusScopeNode.skipTraversal));
      expect(focusScopeWidget.canRequestFocus, equals(focusScopeNode.canRequestFocus));

      await tester.sendKeyEvent(LogicalKeyboardKey.enter);
      expect(keyEventHandled, isTrue);
    });
  });

  group('Focus', () {
    testWidgets('Focus.of stops at the nearest Focus widget.', (WidgetTester tester) async {
      final GlobalKey key1 = GlobalKey(debugLabel: '1');
      final GlobalKey key2 = GlobalKey(debugLabel: '2');
      final GlobalKey key3 = GlobalKey(debugLabel: '3');
      final GlobalKey key4 = GlobalKey(debugLabel: '4');
      final GlobalKey key5 = GlobalKey(debugLabel: '5');
      final GlobalKey key6 = GlobalKey(debugLabel: '6');
      final FocusScopeNode scopeNode = FocusScopeNode();
      await tester.pumpWidget(
        FocusScope(
          key: key1,
          node: scopeNode,
          debugLabel: 'Key 1',
          child: Container(
            key: key2,
            child: Focus(
              debugLabel: 'Key 3',
              key: key3,
              child: Container(
                key: key4,
                child: Focus(
                  debugLabel: 'Key 5',
                  key: key5,
                  child: Container(
                    key: key6,
                  ),
                ),
              ),
            ),
          ),
        ),
      );
      final Element element1 = tester.element(find.byKey(key1));
      final Element element2 = tester.element(find.byKey(key2));
      final Element element3 = tester.element(find.byKey(key3));
      final Element element4 = tester.element(find.byKey(key4));
      final Element element5 = tester.element(find.byKey(key5));
      final Element element6 = tester.element(find.byKey(key6));
      final FocusNode root = element1.owner!.focusManager.rootScope;

      expect(Focus.maybeOf(element1), isNull);
      expect(Focus.maybeOf(element2), isNull);
      expect(Focus.maybeOf(element3), isNull);
      expect(Focus.of(element4).parent!.parent, equals(root));
      expect(Focus.of(element5).parent!.parent, equals(root));
      expect(Focus.of(element6).parent!.parent!.parent, equals(root));
    });
    testWidgets('Can traverse Focus children.', (WidgetTester tester) async {
      final GlobalKey key1 = GlobalKey(debugLabel: '1');
      final GlobalKey key2 = GlobalKey(debugLabel: '2');
      final GlobalKey key3 = GlobalKey(debugLabel: '3');
      final GlobalKey key4 = GlobalKey(debugLabel: '4');
      final GlobalKey key5 = GlobalKey(debugLabel: '5');
      final GlobalKey key6 = GlobalKey(debugLabel: '6');
      final GlobalKey key7 = GlobalKey(debugLabel: '7');
      final GlobalKey key8 = GlobalKey(debugLabel: '8');
      await tester.pumpWidget(
        Focus(
          child: Column(
            key: key1,
            children: <Widget>[
              Focus(
                key: key2,
                child: Focus(
                  key: key3,
                  child: Container(),
                ),
              ),
              Focus(
                key: key4,
                child: Focus(
                  key: key5,
                  child: Container(),
                ),
              ),
              Focus(
                key: key6,
                child: Column(
                  children: <Widget>[
                    Focus(
                      key: key7,
                      child: Container(),
                    ),
                    Focus(
                      key: key8,
                      child: Container(),
                    ),
                  ],
                ),
              ),
            ],
          ),
        ),
      );

      final Element firstScope = tester.element(find.byKey(key1));
      final List<FocusNode> nodes = <FocusNode>[];
      final List<Key> keys = <Key>[];
      bool visitor(FocusNode node) {
        nodes.add(node);
        keys.add(node.context!.widget.key!);
        return true;
      }

      await tester.pump();

      Focus.of(firstScope).descendants.forEach(visitor);
      expect(nodes.length, equals(7));
      expect(keys.length, equals(7));
      // Depth first.
      expect(keys, equals(<Key>[key3, key2, key5, key4, key7, key8, key6]));

      // Just traverses a sub-tree.
      final Element secondScope = tester.element(find.byKey(key7));
      nodes.clear();
      keys.clear();
      Focus.of(secondScope).descendants.forEach(visitor);
      expect(nodes.length, equals(2));
      expect(keys, equals(<Key>[key7, key8]));
    });

    testWidgets('Can set focus.', (WidgetTester tester) async {
      final GlobalKey key1 = GlobalKey(debugLabel: '1');
      late bool gotFocus;
      await tester.pumpWidget(
        Focus(
          onFocusChange: (bool focused) => gotFocus = focused,
          child: Container(key: key1),
        ),
      );

      final Element firstNode = tester.element(find.byKey(key1));
      final FocusNode node = Focus.of(firstNode);
      node.requestFocus();

      await tester.pump();

      expect(gotFocus, isTrue);
      expect(node.hasFocus, isTrue);
    });

    testWidgets('Focus is ignored when set to not focusable.', (WidgetTester tester) async {
      final GlobalKey key1 = GlobalKey(debugLabel: '1');
      bool? gotFocus;
      await tester.pumpWidget(
        Focus(
          canRequestFocus: false,
          onFocusChange: (bool focused) => gotFocus = focused,
          child: Container(key: key1),
        ),
      );

      final Element firstNode = tester.element(find.byKey(key1));
      final FocusNode node = Focus.of(firstNode);
      node.requestFocus();

      await tester.pump();

      expect(gotFocus, isNull);
      expect(node.hasFocus, isFalse);
    });

    testWidgets('Focus is lost when set to not focusable.', (WidgetTester tester) async {
      final GlobalKey key1 = GlobalKey(debugLabel: '1');
      bool? gotFocus;
      await tester.pumpWidget(
        Focus(
          autofocus: true,
          canRequestFocus: true,
          onFocusChange: (bool focused) => gotFocus = focused,
          child: Container(key: key1),
        ),
      );

      Element firstNode = tester.element(find.byKey(key1));
      FocusNode node = Focus.of(firstNode);
      node.requestFocus();

      await tester.pump();

      expect(gotFocus, isTrue);
      expect(node.hasFocus, isTrue);

      gotFocus = null;
      await tester.pumpWidget(
        Focus(
          canRequestFocus: false,
          onFocusChange: (bool focused) => gotFocus = focused,
          child: Container(key: key1),
        ),
      );

      firstNode = tester.element(find.byKey(key1));
      node = Focus.of(firstNode);
      node.requestFocus();

      await tester.pump();

      expect(gotFocus, false);
      expect(node.hasFocus, isFalse);
    });

    testWidgets('Child of unfocusable Focus can get focus.', (WidgetTester tester) async {
      final GlobalKey key1 = GlobalKey(debugLabel: '1');
      final GlobalKey key2 = GlobalKey(debugLabel: '2');
      final FocusNode focusNode = FocusNode();
      bool? gotFocus;
      await tester.pumpWidget(
        Focus(
          canRequestFocus: false,
          onFocusChange: (bool focused) => gotFocus = focused,
          child: Focus(key: key1, focusNode: focusNode, child: Container(key: key2)),
        ),
      );

      final Element childWidget = tester.element(find.byKey(key1));
      final FocusNode unfocusableNode = Focus.of(childWidget);
      unfocusableNode.requestFocus();

      await tester.pump();

      expect(gotFocus, isNull);
      expect(unfocusableNode.hasFocus, isFalse);

      final Element containerWidget = tester.element(find.byKey(key2));
      final FocusNode focusableNode = Focus.of(containerWidget);
      focusableNode.requestFocus();

      await tester.pump();

      expect(gotFocus, isTrue);
      expect(unfocusableNode.hasFocus, isTrue);
    });

    testWidgets('Nodes are removed when all Focuses are removed.', (WidgetTester tester) async {
      final GlobalKey key1 = GlobalKey(debugLabel: '1');
      late bool gotFocus;
      await tester.pumpWidget(
        FocusScope(
          child: Focus(
            onFocusChange: (bool focused) => gotFocus = focused,
            child: Container(key: key1),
          ),
        ),
      );

      final Element firstNode = tester.element(find.byKey(key1));
      final FocusNode node = Focus.of(firstNode);
      node.requestFocus();

      await tester.pump();

      expect(gotFocus, isTrue);
      expect(node.hasFocus, isTrue);

      await tester.pumpWidget(Container());

      expect(FocusManager.instance.rootScope.descendants, isEmpty);
    });

    testWidgets('Focus widgets set Semantics information about focus', (WidgetTester tester) async {
      final GlobalKey<TestFocusState> key = GlobalKey();

      await tester.pumpWidget(
        TestFocus(key: key),
      );

      final SemanticsNode semantics = tester.getSemantics(find.byKey(key));

      expect(key.currentState!.focusNode.hasFocus, isFalse);
      expect(semantics.hasFlag(SemanticsFlag.isFocused), isFalse);
      expect(semantics.hasFlag(SemanticsFlag.isFocusable), isTrue);

      FocusScope.of(key.currentContext!).requestFocus(key.currentState!.focusNode);
      await tester.pumpAndSettle();

      expect(key.currentState!.focusNode.hasFocus, isTrue);
      expect(semantics.hasFlag(SemanticsFlag.isFocused), isTrue);
      expect(semantics.hasFlag(SemanticsFlag.isFocusable), isTrue);

      key.currentState!.focusNode.canRequestFocus = false;
      await tester.pumpAndSettle();

      expect(key.currentState!.focusNode.hasFocus, isFalse);
      expect(key.currentState!.focusNode.canRequestFocus, isFalse);
      expect(semantics.hasFlag(SemanticsFlag.isFocused), isFalse);
      expect(semantics.hasFlag(SemanticsFlag.isFocusable), isFalse);
    });

    testWidgets('Setting canRequestFocus on focus node causes update.', (WidgetTester tester) async {
      final GlobalKey<TestFocusState> key = GlobalKey();

      final TestFocus testFocus = TestFocus(key: key);
      await tester.pumpWidget(
        testFocus,
      );

      await tester.pumpAndSettle();
      key.currentState!.built = false;
      key.currentState!.focusNode.canRequestFocus = false;
      await tester.pumpAndSettle();
      key.currentState!.built = true;

      expect(key.currentState!.focusNode.canRequestFocus, isFalse);
    });

    testWidgets('canRequestFocus causes descendants of scope to be skipped.', (WidgetTester tester) async {
      final GlobalKey scope1 = GlobalKey(debugLabel: 'scope1');
      final GlobalKey scope2 = GlobalKey(debugLabel: 'scope2');
      final GlobalKey focus1 = GlobalKey(debugLabel: 'focus1');
      final GlobalKey focus2 = GlobalKey(debugLabel: 'focus2');
      final GlobalKey container1 = GlobalKey(debugLabel: 'container');
      Future<void> pumpTest({
        bool allowScope1 = true,
        bool allowScope2 = true,
        bool allowFocus1 = true,
        bool allowFocus2 = true,
      }) async {
        await tester.pumpWidget(
          FocusScope(
            key: scope1,
            canRequestFocus: allowScope1,
            child: FocusScope(
              key: scope2,
              canRequestFocus: allowScope2,
              child: Focus(
                key: focus1,
                canRequestFocus: allowFocus1,
                child: Focus(
                  key: focus2,
                  canRequestFocus: allowFocus2,
                  child: Container(
                    key: container1,
                  ),
                ),
              ),
            ),
          ),
        );
        await tester.pump();
      }

      // Check childless node (focus2).
      await pumpTest();
      Focus.of(container1.currentContext!).requestFocus();
      await tester.pump();
      expect(Focus.of(container1.currentContext!).hasFocus, isTrue);
      await pumpTest(allowFocus2: false);
      expect(Focus.of(container1.currentContext!).hasFocus, isFalse);
      Focus.of(container1.currentContext!).requestFocus();
      await tester.pump();
      expect(Focus.of(container1.currentContext!).hasFocus, isFalse);
      await pumpTest();
      Focus.of(container1.currentContext!).requestFocus();
      await tester.pump();
      expect(Focus.of(container1.currentContext!).hasFocus, isTrue);

      // Check FocusNode with child (focus1). Shouldn't affect children.
      await pumpTest(allowFocus1: false);
      expect(Focus.of(container1.currentContext!).hasFocus, isTrue); // focus2 has focus.
      Focus.of(focus2.currentContext!).requestFocus(); // Try to focus focus1
      await tester.pump();
      expect(Focus.of(container1.currentContext!).hasFocus, isTrue); // focus2 still has focus.
      Focus.of(container1.currentContext!).requestFocus(); // Now try to focus focus2
      await tester.pump();
      expect(Focus.of(container1.currentContext!).hasFocus, isTrue);
      await pumpTest();
      // Try again, now that we've set focus1's canRequestFocus to true again.
      Focus.of(container1.currentContext!).unfocus();
      await tester.pump();
      expect(Focus.of(container1.currentContext!).hasFocus, isFalse);
      Focus.of(container1.currentContext!).requestFocus();
      await tester.pump();
      expect(Focus.of(container1.currentContext!).hasFocus, isTrue);

      // Check FocusScopeNode with only FocusNode children (scope2). Should affect children.
      await pumpTest(allowScope2: false);
      expect(Focus.of(container1.currentContext!).hasFocus, isFalse);
      FocusScope.of(focus1.currentContext!).requestFocus(); // Try to focus scope2
      await tester.pump();
      expect(Focus.of(container1.currentContext!).hasFocus, isFalse);
      Focus.of(focus2.currentContext!).requestFocus(); // Try to focus focus1
      await tester.pump();
      expect(Focus.of(container1.currentContext!).hasFocus, isFalse);
      Focus.of(container1.currentContext!).requestFocus(); // Try to focus focus2
      await tester.pump();
      expect(Focus.of(container1.currentContext!).hasFocus, isFalse);
      await pumpTest();
      // Try again, now that we've set scope2's canRequestFocus to true again.
      Focus.of(container1.currentContext!).requestFocus();
      await tester.pump();
      expect(Focus.of(container1.currentContext!).hasFocus, isTrue);

      // Check FocusScopeNode with both FocusNode children and FocusScope children (scope1). Should affect children.
      await pumpTest(allowScope1: false);
      expect(Focus.of(container1.currentContext!).hasFocus, isFalse);
      FocusScope.of(scope2.currentContext!).requestFocus(); // Try to focus scope1
      await tester.pump();
      expect(Focus.of(container1.currentContext!).hasFocus, isFalse);
      FocusScope.of(focus1.currentContext!).requestFocus(); // Try to focus scope2
      await tester.pump();
      expect(Focus.of(container1.currentContext!).hasFocus, isFalse);
      Focus.of(focus2.currentContext!).requestFocus(); // Try to focus focus1
      await tester.pump();
      expect(Focus.of(container1.currentContext!).hasFocus, isFalse);
      Focus.of(container1.currentContext!).requestFocus(); // Try to focus focus2
      await tester.pump();
      expect(Focus.of(container1.currentContext!).hasFocus, isFalse);
      await pumpTest();
      // Try again, now that we've set scope1's canRequestFocus to true again.
      Focus.of(container1.currentContext!).requestFocus();
      await tester.pump();
      expect(Focus.of(container1.currentContext!).hasFocus, isTrue);
    });

    testWidgets('skipTraversal works as expected.', (WidgetTester tester) async {
      final FocusScopeNode scope1 = FocusScopeNode(debugLabel: 'scope1');
      final FocusScopeNode scope2 = FocusScopeNode(debugLabel: 'scope2');
      final FocusNode focus1 = FocusNode(debugLabel: 'focus1');
      final FocusNode focus2 = FocusNode(debugLabel: 'focus2');

      Future<void> pumpTest({
        bool traverseScope1 = false,
        bool traverseScope2 = false,
        bool traverseFocus1 = false,
        bool traverseFocus2 = false,
      }) async {
        await tester.pumpWidget(
          FocusScope(
            node: scope1,
            skipTraversal: traverseScope1,
            child: FocusScope(
              node: scope2,
              skipTraversal: traverseScope2,
              child: Focus(
                focusNode: focus1,
                skipTraversal: traverseFocus1,
                child: Focus(
                  focusNode: focus2,
                  skipTraversal: traverseFocus2,
                  child: Container(),
                ),
              ),
            ),
          ),
        );
        await tester.pump();
      }

      await pumpTest();
      expect(scope1.traversalDescendants, equals(<FocusNode>[focus2, focus1, scope2]));

      // Check childless node (focus2).
      await pumpTest(traverseFocus2: true);
      expect(scope1.traversalDescendants, equals(<FocusNode>[focus1, scope2]));

      // Check FocusNode with child (focus1). Shouldn't affect children.
      await pumpTest(traverseFocus1: true);
      expect(scope1.traversalDescendants, equals(<FocusNode>[focus2, scope2]));

      // Check FocusScopeNode with only FocusNode children (scope2). Should affect children.
      await pumpTest(traverseScope2: true);
      expect(scope1.traversalDescendants, equals(<FocusNode>[focus2, focus1]));

      // Check FocusScopeNode with both FocusNode children and FocusScope children (scope1). Should affect children.
      await pumpTest(traverseScope1: true);
      expect(scope1.traversalDescendants, equals(<FocusNode>[focus2, focus1, scope2]));
    });
    testWidgets('descendantsAreFocusable works as expected.', (WidgetTester tester) async {
      final GlobalKey key1 = GlobalKey(debugLabel: '1');
      final GlobalKey key2 = GlobalKey(debugLabel: '2');
      final FocusNode focusNode = FocusNode();
      bool? gotFocus;
      await tester.pumpWidget(
        Focus(
          descendantsAreFocusable: false,
          child: Focus(
            onFocusChange: (bool focused) => gotFocus = focused,
            child: Focus(
              key: key1,
              focusNode: focusNode,
              child: Container(key: key2),
            ),
          ),
        ),
      );

      final Element childWidget = tester.element(find.byKey(key1));
      final FocusNode unfocusableNode = Focus.of(childWidget);
      final Element containerWidget = tester.element(find.byKey(key2));
      final FocusNode containerNode = Focus.of(containerWidget);

      unfocusableNode.requestFocus();
      await tester.pump();

      expect(gotFocus, isNull);
      expect(containerNode.hasFocus, isFalse);
      expect(unfocusableNode.hasFocus, isFalse);

      containerNode.requestFocus();
      await tester.pump();

      expect(gotFocus, isNull);
      expect(containerNode.hasFocus, isFalse);
      expect(unfocusableNode.hasFocus, isFalse);
    });

    testWidgets('descendantsAreTraversable works as expected.', (WidgetTester tester) async {
      final FocusScopeNode scopeNode = FocusScopeNode(debugLabel: 'scope');
      final FocusNode node1 = FocusNode(debugLabel: 'node 1');
      final FocusNode node2 = FocusNode(debugLabel: 'node 2');
      final FocusNode node3 = FocusNode(debugLabel: 'node 3');

      await tester.pumpWidget(
        FocusScope(
          node: scopeNode,
          child: Column(
            children: <Widget>[
              Focus(
                focusNode: node1,
                child: Container(),
              ),
              Focus(
                focusNode: node2,
                descendantsAreTraversable: false,
                child: Focus(
                  focusNode: node3,
                  child: Container(),
                )
              ),
            ],
          ),
        ),
      );
      await tester.pump();

      expect(scopeNode.traversalDescendants, equals(<FocusNode>[node1, node2]));
      expect(node2.traversalDescendants, equals(<FocusNode>[]));
    });

    testWidgets("Focus doesn't introduce a Semantics node when includeSemantics is false", (WidgetTester tester) async {
      final SemanticsTester semantics = SemanticsTester(tester);
      await tester.pumpWidget(Focus(includeSemantics: false, child: Container()));
      final TestSemantics expectedSemantics = TestSemantics.root();
      expect(semantics, hasSemantics(expectedSemantics));
    });

    testWidgets('Focus updates the onKey handler when the widget updates', (WidgetTester tester) async {
      final GlobalKey key1 = GlobalKey(debugLabel: '1');
      final FocusNode focusNode = FocusNode();
      bool? keyEventHandled;
      // ignore: prefer_function_declarations_over_variables
      final FocusOnKeyCallback handleCallback = (FocusNode node, RawKeyEvent event) {
        keyEventHandled = true;
        return KeyEventResult.handled;
      };
      // ignore: prefer_function_declarations_over_variables
      final FocusOnKeyCallback ignoreCallback = (FocusNode node, RawKeyEvent event) => KeyEventResult.ignored;
      Focus focusWidget = Focus(
        onKey: ignoreCallback, // This one does nothing.
        focusNode: focusNode,
        skipTraversal: true,
        canRequestFocus: true,
        child: Container(key: key1),
      );
      focusNode.onKeyEvent = null;
      await tester.pumpWidget(focusWidget);
      expect(focusNode.onKey, equals(ignoreCallback));
      expect(focusWidget.onKey, equals(focusNode.onKey));
      expect(focusWidget.onKeyEvent, equals(focusNode.onKeyEvent));
      expect(focusWidget.descendantsAreFocusable, equals(focusNode.descendantsAreFocusable));
      expect(focusWidget.skipTraversal, equals(focusNode.skipTraversal));
      expect(focusWidget.canRequestFocus, equals(focusNode.canRequestFocus));

      Focus.of(key1.currentContext!).requestFocus();
      await tester.pump();
      await tester.sendKeyEvent(LogicalKeyboardKey.enter);
      expect(keyEventHandled, isNull);

      focusWidget = Focus(
        onKey: handleCallback,
        focusNode: focusNode,
        skipTraversal: true,
        canRequestFocus: true,
        child: Container(key: key1),
      );
      await tester.pumpWidget(focusWidget);
      expect(focusNode.onKey, equals(handleCallback));
      expect(focusWidget.onKey, equals(focusNode.onKey));
      expect(focusWidget.onKeyEvent, equals(focusNode.onKeyEvent));
      expect(focusWidget.descendantsAreFocusable, equals(focusNode.descendantsAreFocusable));
      expect(focusWidget.skipTraversal, equals(focusNode.skipTraversal));
      expect(focusWidget.canRequestFocus, equals(focusNode.canRequestFocus));

      await tester.sendKeyEvent(LogicalKeyboardKey.enter);
      expect(keyEventHandled, isTrue);
    });

    testWidgets('Focus updates the onKeyEvent handler when the widget updates', (WidgetTester tester) async {
      final GlobalKey key1 = GlobalKey(debugLabel: '1');
      final FocusNode focusNode = FocusNode();
      bool? keyEventHandled;
      // ignore: prefer_function_declarations_over_variables
      final FocusOnKeyEventCallback handleEventCallback = (FocusNode node, KeyEvent event) {
        keyEventHandled = true;
        return KeyEventResult.handled;
      };
      // ignore: prefer_function_declarations_over_variables
      final FocusOnKeyEventCallback ignoreEventCallback = (FocusNode node, KeyEvent event) => KeyEventResult.ignored;
      Focus focusWidget = Focus(
        onKeyEvent: ignoreEventCallback, // This one does nothing.
        focusNode: focusNode,
        skipTraversal: true,
        canRequestFocus: true,
        child: Container(key: key1),
      );
      focusNode.onKeyEvent = null;
      await tester.pumpWidget(focusWidget);
      expect(focusNode.onKeyEvent, equals(ignoreEventCallback));
      expect(focusWidget.onKey, equals(focusNode.onKey));
      expect(focusWidget.onKeyEvent, equals(focusNode.onKeyEvent));
      expect(focusWidget.descendantsAreFocusable, equals(focusNode.descendantsAreFocusable));
      expect(focusWidget.skipTraversal, equals(focusNode.skipTraversal));
      expect(focusWidget.canRequestFocus, equals(focusNode.canRequestFocus));

      Focus.of(key1.currentContext!).requestFocus();
      await tester.pump();
      await tester.sendKeyEvent(LogicalKeyboardKey.enter);
      expect(keyEventHandled, isNull);

      focusWidget = Focus(
        onKeyEvent: handleEventCallback,
        focusNode: focusNode,
        skipTraversal: true,
        canRequestFocus: true,
        child: Container(key: key1),
      );
      await tester.pumpWidget(focusWidget);
      expect(focusNode.onKeyEvent, equals(handleEventCallback));
      expect(focusWidget.onKey, equals(focusNode.onKey));
      expect(focusWidget.onKeyEvent, equals(focusNode.onKeyEvent));
      expect(focusWidget.descendantsAreFocusable, equals(focusNode.descendantsAreFocusable));
      expect(focusWidget.skipTraversal, equals(focusNode.skipTraversal));
      expect(focusWidget.canRequestFocus, equals(focusNode.canRequestFocus));

      await tester.sendKeyEvent(LogicalKeyboardKey.enter);
      expect(keyEventHandled, isTrue);
    });

    testWidgets("Focus doesn't update the focusNode attributes when the widget updates if withExternalFocusNode is used", (WidgetTester tester) async {
      final GlobalKey key1 = GlobalKey(debugLabel: '1');
      final FocusNode focusNode = FocusNode();
      bool? keyEventHandled;
      // ignore: prefer_function_declarations_over_variables
      final FocusOnKeyCallback handleCallback = (FocusNode node, RawKeyEvent event) {
        keyEventHandled = true;
        return KeyEventResult.handled;
      };
      // ignore: prefer_function_declarations_over_variables
      final FocusOnKeyEventCallback handleEventCallback = (FocusNode node, KeyEvent event) {
        keyEventHandled = true;
        return KeyEventResult.handled;
      };
      // ignore: prefer_function_declarations_over_variables
      final FocusOnKeyCallback ignoreCallback = (FocusNode node, RawKeyEvent event) => KeyEventResult.ignored;
      // ignore: prefer_function_declarations_over_variables
      final FocusOnKeyEventCallback ignoreEventCallback = (FocusNode node, KeyEvent event) => KeyEventResult.ignored;
      focusNode.onKey = ignoreCallback;
      focusNode.onKeyEvent = ignoreEventCallback;
      focusNode.descendantsAreFocusable = false;
      focusNode.descendantsAreTraversable = false;
      focusNode.skipTraversal = false;
      focusNode.canRequestFocus = true;
      Focus focusWidget = Focus.withExternalFocusNode(
        focusNode: focusNode,
        child: Container(key: key1),
      );
      await tester.pumpWidget(focusWidget);
      expect(focusNode.onKey, equals(ignoreCallback));
      expect(focusNode.onKeyEvent, equals(ignoreEventCallback));
      expect(focusNode.descendantsAreFocusable, isFalse);
      expect(focusNode.descendantsAreTraversable, isFalse);
      expect(focusNode.skipTraversal, isFalse);
      expect(focusNode.canRequestFocus, isTrue);
      expect(focusWidget.onKey, equals(focusNode.onKey));
      expect(focusWidget.onKeyEvent, equals(focusNode.onKeyEvent));
      expect(focusWidget.descendantsAreFocusable, equals(focusNode.descendantsAreFocusable));
      expect(focusWidget.descendantsAreTraversable, equals(focusNode.descendantsAreTraversable));
      expect(focusWidget.skipTraversal, equals(focusNode.skipTraversal));
      expect(focusWidget.canRequestFocus, equals(focusNode.canRequestFocus));

      Focus.of(key1.currentContext!).requestFocus();
      await tester.pump();
      await tester.sendKeyEvent(LogicalKeyboardKey.enter);
      expect(keyEventHandled, isNull);

      focusNode.onKey = handleCallback;
      focusNode.onKeyEvent = handleEventCallback;
      focusNode.descendantsAreFocusable = true;
      focusNode.descendantsAreTraversable = true;
      focusWidget = Focus.withExternalFocusNode(
        focusNode: focusNode,
        child: Container(key: key1),
      );
      await tester.pumpWidget(focusWidget);
      expect(focusNode.onKey, equals(handleCallback));
      expect(focusNode.onKeyEvent, equals(handleEventCallback));
      expect(focusNode.descendantsAreFocusable, isTrue);
      expect(focusNode.descendantsAreTraversable, isTrue);
      expect(focusNode.skipTraversal, isFalse);
      expect(focusNode.canRequestFocus, isTrue);
      expect(focusWidget.onKey, equals(focusNode.onKey));
      expect(focusWidget.onKeyEvent, equals(focusNode.onKeyEvent));
      expect(focusWidget.descendantsAreFocusable, equals(focusNode.descendantsAreFocusable));
      expect(focusWidget.descendantsAreTraversable, equals(focusNode.descendantsAreTraversable));
      expect(focusWidget.skipTraversal, equals(focusNode.skipTraversal));
      expect(focusWidget.canRequestFocus, equals(focusNode.canRequestFocus));

      await tester.sendKeyEvent(LogicalKeyboardKey.enter);
      expect(keyEventHandled, isTrue);
    });

    testWidgets('Focus passes changes in attribute values to its focus node', (WidgetTester tester) async {
      await tester.pumpWidget(
        Focus(
          child: Container(),
        ),
      );
    });
  });

  group('ExcludeFocus', () {
    testWidgets("Descendants of ExcludeFocus aren't focusable.", (WidgetTester tester) async {
      final GlobalKey key1 = GlobalKey(debugLabel: '1');
      final GlobalKey key2 = GlobalKey(debugLabel: '2');
      final FocusNode focusNode = FocusNode();
      bool? gotFocus;
      await tester.pumpWidget(
        ExcludeFocus(
          child: Focus(
            onFocusChange: (bool focused) => gotFocus = focused,
            child: Focus(
              key: key1,
              focusNode: focusNode,
              child: Container(key: key2),
            ),
          ),
        ),
      );

      final Element childWidget = tester.element(find.byKey(key1));
      final FocusNode unfocusableNode = Focus.of(childWidget);
      final Element containerWidget = tester.element(find.byKey(key2));
      final FocusNode containerNode = Focus.of(containerWidget);

      unfocusableNode.requestFocus();
      await tester.pump();

      expect(gotFocus, isNull);
      expect(containerNode.hasFocus, isFalse);
      expect(unfocusableNode.hasFocus, isFalse);

      containerNode.requestFocus();
      await tester.pump();

      expect(gotFocus, isNull);
      expect(containerNode.hasFocus, isFalse);
      expect(unfocusableNode.hasFocus, isFalse);
    });
    // Regression test for https://github.com/flutter/flutter/issues/61700
    testWidgets("ExcludeFocus doesn't transfer focus to another descendant.", (WidgetTester tester) async {
      final FocusNode parentFocusNode = FocusNode(debugLabel: 'group');
      final FocusNode focusNode1 = FocusNode(debugLabel: 'node 1');
      final FocusNode focusNode2 = FocusNode(debugLabel: 'node 2');
      await tester.pumpWidget(
        ExcludeFocus(
          excluding: false,
          child: Focus(
            focusNode: parentFocusNode,
            child: Column(
              children: <Widget>[
                Focus(
                  autofocus: true,
                  focusNode: focusNode1,
                  child: Container(),
                ),
                Focus(
                  focusNode: focusNode2,
                  child: Container(),
                ),
              ],
            ),
          ),
        ),
      );

      await tester.pump();

      expect(parentFocusNode.hasFocus, isTrue);
      expect(focusNode1.hasPrimaryFocus, isTrue);
      expect(focusNode2.hasFocus, isFalse);

      // Move focus to the second node to create some focus history for the scope.
      focusNode2.requestFocus();
      await tester.pump();

      expect(parentFocusNode.hasFocus, isTrue);
      expect(focusNode1.hasFocus, isFalse);
      expect(focusNode2.hasPrimaryFocus, isTrue);

      // Now turn off the focus for the subtree.
      await tester.pumpWidget(
        ExcludeFocus(
          child: Focus(
            focusNode: parentFocusNode,
            child: Column(
              children: <Widget>[
                Focus(
                  autofocus: true,
                  focusNode: focusNode1,
                  child: Container(),
                ),
                Focus(
                  focusNode: focusNode2,
                  child: Container(),
                ),
              ],
            ),
          ),
        ),
      );
      await tester.pump();

      expect(focusNode1.hasFocus, isFalse);
      expect(focusNode2.hasFocus, isFalse);
      expect(parentFocusNode.hasFocus, isFalse);
      expect(parentFocusNode.enclosingScope!.hasPrimaryFocus, isTrue);
    });

    testWidgets("ExcludeFocus doesn't introduce a Semantics node", (WidgetTester tester) async {
      final SemanticsTester semantics = SemanticsTester(tester);
      await tester.pumpWidget(ExcludeFocus(child: Container()));
      final TestSemantics expectedSemantics = TestSemantics.root();
      expect(semantics, hasSemantics(expectedSemantics));
    });

    // Regression test for https://github.com/flutter/flutter/issues/92693
    testWidgets('Setting parent FocusScope.canRequestFocus to false, does not set descendant Focus._internalNode._canRequestFocus to false', (WidgetTester tester) async {
      final FocusNode childFocusNode = FocusNode(debugLabel: 'node 1');

      Widget buildFocusTree({required bool parentCanRequestFocus}) {
        return FocusScope(
          canRequestFocus: parentCanRequestFocus,
          child: Column(
            children: <Widget>[
              Focus(
                focusNode: childFocusNode,
                child: Container(),
              ),
            ],
          ),
        );
      }

      // childFocusNode.canRequestFocus is true when parent canRequestFocus is true
      await tester.pumpWidget(buildFocusTree(parentCanRequestFocus: true));
      expect(childFocusNode.canRequestFocus, isTrue);

      // childFocusNode.canRequestFocus is false when parent canRequestFocus is false
      await tester.pumpWidget(buildFocusTree(parentCanRequestFocus: false));
      expect(childFocusNode.canRequestFocus, isFalse);

      // childFocusNode.canRequestFocus is true again when parent canRequestFocus is changed back to true
      await tester.pumpWidget(buildFocusTree(parentCanRequestFocus: true));
      expect(childFocusNode.canRequestFocus, isTrue);
    });
  });
}

class TestFocus extends StatefulWidget {
  const TestFocus({
    super.key,
    this.debugLabel,
    this.name = 'a',
    this.autofocus = false,
    this.parentNode,
  });

  final String? debugLabel;
  final String name;
  final bool autofocus;
  final FocusNode? parentNode;

  @override
  TestFocusState createState() => TestFocusState();
}

class TestFocusState extends State<TestFocus> {
  late FocusNode focusNode;
  late String _label;
  bool built = false;

  @override
  void dispose() {
    focusNode.removeListener(_updateLabel);
    focusNode.dispose();
    super.dispose();
  }

  String get label => focusNode.hasFocus ? '${widget.name.toUpperCase()} FOCUSED' : widget.name.toLowerCase();

  @override
  void initState() {
    super.initState();
    focusNode = FocusNode(debugLabel: widget.debugLabel);
    _label = label;
    focusNode.addListener(_updateLabel);
  }

  void _updateLabel() {
    setState(() {
      _label = label;
    });
  }

  @override
  Widget build(BuildContext context) {
    built = true;
    return GestureDetector(
      onTap: () {
        FocusScope.of(context).requestFocus(focusNode);
      },
      child: Focus(
        autofocus: widget.autofocus,
        focusNode: focusNode,
        parentNode: widget.parentNode,
        debugLabel: widget.debugLabel,
        child: Text(
          _label,
          textDirection: TextDirection.ltr,
        ),
      ),
    );
  }
}
