diff --git a/dev/integration_tests/flutter_gallery/test/demo/material/chip_demo_test.dart b/dev/integration_tests/flutter_gallery/test/demo/material/chip_demo_test.dart index 9d769f7337f..1b11c4d833c 100644 --- a/dev/integration_tests/flutter_gallery/test/demo/material/chip_demo_test.dart +++ b/dev/integration_tests/flutter_gallery/test/demo/material/chip_demo_test.dart @@ -20,6 +20,7 @@ void main() { isEnabled: true, isFocusable: true, hasTapAction: true, + hasFocusAction: true, label: 'Update border shape', )); @@ -29,6 +30,7 @@ void main() { isEnabled: true, isFocusable: true, hasTapAction: true, + hasFocusAction: true, label: 'Reset chips', )); diff --git a/packages/flutter/lib/src/widgets/focus_scope.dart b/packages/flutter/lib/src/widgets/focus_scope.dart index acd9b04f1bf..c59fb5f3050 100644 --- a/packages/flutter/lib/src/widgets/focus_scope.dart +++ b/packages/flutter/lib/src/widgets/focus_scope.dart @@ -671,6 +671,15 @@ class _FocusState extends State { Widget child = widget.child; if (widget.includeSemantics) { child = Semantics( + // Automatically request the focus for a focusable widget when it + // receives an input focus action from the semantics. Nothing is needed + // for losing the focus because if focus is lost, that means another + // node will gain focus and take focus from this widget. + // TODO(gspencergoog): Allow this to be set on iOS once the issue is + // addressed: https://github.com/flutter/flutter/issues/150030 + onFocus: defaultTargetPlatform != TargetPlatform.iOS && _couldRequestFocus + ? focusNode.requestFocus + : null, focusable: _couldRequestFocus, focused: _hadPrimaryFocus, child: widget.child, diff --git a/packages/flutter/test/cupertino/checkbox_test.dart b/packages/flutter/test/cupertino/checkbox_test.dart index 601aef991d8..b6bdaf6baf2 100644 --- a/packages/flutter/test/cupertino/checkbox_test.dart +++ b/packages/flutter/test/cupertino/checkbox_test.dart @@ -34,6 +34,7 @@ void main() { hasEnabledState: true, isEnabled: true, hasTapAction: true, + hasFocusAction: true, isFocusable: true, )); @@ -54,6 +55,7 @@ void main() { isChecked: true, isEnabled: true, hasTapAction: true, + hasFocusAction: true, isFocusable: true, )); @@ -73,6 +75,7 @@ void main() { hasEnabledState: true, // isFocusable is delayed by 1 frame. isFocusable: true, + hasFocusAction: true, )); await tester.pump(); @@ -178,6 +181,7 @@ void main() { hasEnabledState: true, isEnabled: true, hasTapAction: true, + hasFocusAction: true, isFocusable: true, )); handle.dispose(); @@ -247,7 +251,7 @@ void main() { SemanticsFlag.isFocusable, SemanticsFlag.isCheckStateMixed, ], - actions: [SemanticsAction.tap], + actions: [SemanticsAction.tap, SemanticsAction.focus], ), hasLength(1)); await tester.pumpWidget( @@ -268,7 +272,7 @@ void main() { SemanticsFlag.isChecked, SemanticsFlag.isFocusable, ], - actions: [SemanticsAction.tap], + actions: [SemanticsAction.tap, SemanticsAction.focus], ), hasLength(1)); await tester.pumpWidget( @@ -288,7 +292,7 @@ void main() { SemanticsFlag.isEnabled, SemanticsFlag.isFocusable, ], - actions: [SemanticsAction.tap], + actions: [SemanticsAction.tap, SemanticsAction.focus], ), hasLength(1)); semantics.dispose(); diff --git a/packages/flutter/test/cupertino/radio_test.dart b/packages/flutter/test/cupertino/radio_test.dart index cd30734d418..6035c20ceeb 100644 --- a/packages/flutter/test/cupertino/radio_test.dart +++ b/packages/flutter/test/cupertino/radio_test.dart @@ -148,6 +148,7 @@ void main() { ], actions: [ SemanticsAction.tap, + SemanticsAction.focus, ], ), ); @@ -172,6 +173,7 @@ void main() { hasEnabledState: true, isEnabled: true, hasTapAction: true, + hasFocusAction: true, isFocusable: true, isInMutuallyExclusiveGroup: true, )); @@ -191,6 +193,7 @@ void main() { hasEnabledState: true, isEnabled: true, hasTapAction: true, + hasFocusAction: true, isFocusable: true, isInMutuallyExclusiveGroup: true, isChecked: true, @@ -211,6 +214,7 @@ void main() { hasEnabledState: true, isFocusable: true, isInMutuallyExclusiveGroup: true, + hasFocusAction: true, )); await tester.pump(); diff --git a/packages/flutter/test/cupertino/route_test.dart b/packages/flutter/test/cupertino/route_test.dart index 2ca816975ef..649efb25a55 100644 --- a/packages/flutter/test/cupertino/route_test.dart +++ b/packages/flutter/test/cupertino/route_test.dart @@ -1945,7 +1945,7 @@ void main() { await tester.pumpAndSettle(); expect(semantics, isNot(includesNodeWith( - actions: [SemanticsAction.tap], + actions: [SemanticsAction.tap, SemanticsAction.focus], label: 'Dismiss', ))); debugDefaultTargetPlatformOverride = null; diff --git a/packages/flutter/test/cupertino/text_field_test.dart b/packages/flutter/test/cupertino/text_field_test.dart index c46651ab159..7407eccea10 100644 --- a/packages/flutter/test/cupertino/text_field_test.dart +++ b/packages/flutter/test/cupertino/text_field_test.dart @@ -2621,7 +2621,7 @@ void main() { ), ); - expect(semantics, isNot(includesNodeWith(actions: [SemanticsAction.tap]))); + expect(semantics, isNot(includesNodeWith(actions: [SemanticsAction.tap, SemanticsAction.focus]))); semantics.dispose(); }); diff --git a/packages/flutter/test/material/back_button_test.dart b/packages/flutter/test/material/back_button_test.dart index afdba078a12..682dc4b2325 100644 --- a/packages/flutter/test/material/back_button_test.dart +++ b/packages/flutter/test/material/back_button_test.dart @@ -215,6 +215,7 @@ void main() { hasEnabledState: true, isEnabled: true, hasTapAction: true, + hasFocusAction: true, isFocusable: true, )); handle.dispose(); @@ -258,6 +259,7 @@ void main() { hasEnabledState: true, isEnabled: true, hasTapAction: true, + hasFocusAction: true, isFocusable: true, )); handle.dispose(); diff --git a/packages/flutter/test/material/bottom_navigation_bar_test.dart b/packages/flutter/test/material/bottom_navigation_bar_test.dart index c74f893e6e7..f0e65837bb7 100644 --- a/packages/flutter/test/material/bottom_navigation_bar_test.dart +++ b/packages/flutter/test/material/bottom_navigation_bar_test.dart @@ -2111,6 +2111,7 @@ void main() { isFocusable: true, isSelected: true, hasTapAction: true, + hasFocusAction: true, ), ); expect( @@ -2120,6 +2121,7 @@ void main() { textDirection: TextDirection.ltr, isFocusable: true, hasTapAction: true, + hasFocusAction: true, ), ); expect( @@ -2129,6 +2131,7 @@ void main() { textDirection: TextDirection.ltr, isFocusable: true, hasTapAction: true, + hasFocusAction: true, ), ); }); @@ -2165,6 +2168,7 @@ void main() { isFocusable: true, isSelected: true, hasTapAction: true, + hasFocusAction: true, ), ); expect( @@ -2174,6 +2178,7 @@ void main() { textDirection: TextDirection.ltr, isFocusable: true, hasTapAction: true, + hasFocusAction: true, ), ); expect( @@ -2183,6 +2188,7 @@ void main() { textDirection: TextDirection.ltr, isFocusable: true, hasTapAction: true, + hasFocusAction: true, ), ); }); @@ -2515,6 +2521,7 @@ void main() { isFocusable: true, isSelected: true, hasTapAction: true, + hasFocusAction: true, ), ); expect( @@ -2524,6 +2531,7 @@ void main() { textDirection: TextDirection.ltr, isFocusable: true, hasTapAction: true, + hasFocusAction: true, ), ); }); @@ -2558,6 +2566,7 @@ void main() { isFocusable: true, isSelected: true, hasTapAction: true, + hasFocusAction: true, ), ); expect( @@ -2567,6 +2576,7 @@ void main() { textDirection: TextDirection.ltr, isFocusable: true, hasTapAction: true, + hasFocusAction: true, ), ); }); @@ -2747,13 +2757,13 @@ void main() { SemanticsFlag.isSelected, SemanticsFlag.isFocusable, ], - actions: [SemanticsAction.tap], + actions: [SemanticsAction.tap, SemanticsAction.focus], label: 'A\nTab 1 of 2', textDirection: TextDirection.ltr, ), TestSemantics( flags: [SemanticsFlag.isFocusable], - actions: [SemanticsAction.tap], + actions: [SemanticsAction.tap, SemanticsAction.focus], label: 'B\nTab 2 of 2', textDirection: TextDirection.ltr, ), diff --git a/packages/flutter/test/material/calendar_date_picker_test.dart b/packages/flutter/test/material/calendar_date_picker_test.dart index ed7c1aa2054..b6eb7c577ac 100644 --- a/packages/flutter/test/material/calendar_date_picker_test.dart +++ b/packages/flutter/test/material/calendar_date_picker_test.dart @@ -864,6 +864,7 @@ void main() { tooltip: 'Previous month', isButton: true, hasTapAction: true, + hasFocusAction: true, isEnabled: true, hasEnabledState: true, isFocusable: true, @@ -872,6 +873,7 @@ void main() { tooltip: 'Next month', isButton: true, hasTapAction: true, + hasFocusAction: true, isEnabled: true, hasEnabledState: true, isFocusable: true, @@ -882,90 +884,105 @@ void main() { label: '1, Friday, January 1, 2016', isButton: true, hasTapAction: true, + hasFocusAction: true, isFocusable: true, )); expect(tester.getSemantics(find.text('2')), matchesSemantics( label: '2, Saturday, January 2, 2016', isButton: true, hasTapAction: true, + hasFocusAction: true, isFocusable: true, )); expect(tester.getSemantics(find.text('3')), matchesSemantics( label: '3, Sunday, January 3, 2016, Today', isButton: true, hasTapAction: true, + hasFocusAction: true, isFocusable: true, )); expect(tester.getSemantics(find.text('4')), matchesSemantics( label: '4, Monday, January 4, 2016', isButton: true, hasTapAction: true, + hasFocusAction: true, isFocusable: true, )); expect(tester.getSemantics(find.text('5')), matchesSemantics( label: '5, Tuesday, January 5, 2016', isButton: true, hasTapAction: true, + hasFocusAction: true, isFocusable: true, )); expect(tester.getSemantics(find.text('6')), matchesSemantics( label: '6, Wednesday, January 6, 2016', isButton: true, hasTapAction: true, + hasFocusAction: true, isFocusable: true, )); expect(tester.getSemantics(find.text('7')), matchesSemantics( label: '7, Thursday, January 7, 2016', isButton: true, hasTapAction: true, + hasFocusAction: true, isFocusable: true, )); expect(tester.getSemantics(find.text('8')), matchesSemantics( label: '8, Friday, January 8, 2016', isButton: true, hasTapAction: true, + hasFocusAction: true, isFocusable: true, )); expect(tester.getSemantics(find.text('9')), matchesSemantics( label: '9, Saturday, January 9, 2016', isButton: true, hasTapAction: true, + hasFocusAction: true, isFocusable: true, )); expect(tester.getSemantics(find.text('10')), matchesSemantics( label: '10, Sunday, January 10, 2016', isButton: true, hasTapAction: true, + hasFocusAction: true, isFocusable: true, )); expect(tester.getSemantics(find.text('11')), matchesSemantics( label: '11, Monday, January 11, 2016', isButton: true, hasTapAction: true, + hasFocusAction: true, isFocusable: true, )); expect(tester.getSemantics(find.text('12')), matchesSemantics( label: '12, Tuesday, January 12, 2016', isButton: true, hasTapAction: true, + hasFocusAction: true, isFocusable: true, )); expect(tester.getSemantics(find.text('13')), matchesSemantics( label: '13, Wednesday, January 13, 2016', isButton: true, hasTapAction: true, + hasFocusAction: true, isFocusable: true, )); expect(tester.getSemantics(find.text('14')), matchesSemantics( label: '14, Thursday, January 14, 2016', isButton: true, hasTapAction: true, + hasFocusAction: true, isFocusable: true, )); expect(tester.getSemantics(find.text('15')), matchesSemantics( label: '15, Friday, January 15, 2016', isButton: true, hasTapAction: true, + hasFocusAction: true, isSelected: true, isFocusable: true, )); @@ -973,90 +990,105 @@ void main() { label: '16, Saturday, January 16, 2016', isButton: true, hasTapAction: true, + hasFocusAction: true, isFocusable: true, )); expect(tester.getSemantics(find.text('17')), matchesSemantics( label: '17, Sunday, January 17, 2016', isButton: true, hasTapAction: true, + hasFocusAction: true, isFocusable: true, )); expect(tester.getSemantics(find.text('18')), matchesSemantics( label: '18, Monday, January 18, 2016', isButton: true, hasTapAction: true, + hasFocusAction: true, isFocusable: true, )); expect(tester.getSemantics(find.text('19')), matchesSemantics( label: '19, Tuesday, January 19, 2016', isButton: true, hasTapAction: true, + hasFocusAction: true, isFocusable: true, )); expect(tester.getSemantics(find.text('20')), matchesSemantics( label: '20, Wednesday, January 20, 2016', isButton: true, hasTapAction: true, + hasFocusAction: true, isFocusable: true, )); expect(tester.getSemantics(find.text('21')), matchesSemantics( label: '21, Thursday, January 21, 2016', isButton: true, hasTapAction: true, + hasFocusAction: true, isFocusable: true, )); expect(tester.getSemantics(find.text('22')), matchesSemantics( label: '22, Friday, January 22, 2016', isButton: true, hasTapAction: true, + hasFocusAction: true, isFocusable: true, )); expect(tester.getSemantics(find.text('23')), matchesSemantics( label: '23, Saturday, January 23, 2016', isButton: true, hasTapAction: true, + hasFocusAction: true, isFocusable: true, )); expect(tester.getSemantics(find.text('24')), matchesSemantics( label: '24, Sunday, January 24, 2016', isButton: true, hasTapAction: true, + hasFocusAction: true, isFocusable: true, )); expect(tester.getSemantics(find.text('25')), matchesSemantics( label: '25, Monday, January 25, 2016', isButton: true, hasTapAction: true, + hasFocusAction: true, isFocusable: true, )); expect(tester.getSemantics(find.text('26')), matchesSemantics( label: '26, Tuesday, January 26, 2016', isButton: true, hasTapAction: true, + hasFocusAction: true, isFocusable: true, )); expect(tester.getSemantics(find.text('27')), matchesSemantics( label: '27, Wednesday, January 27, 2016', isButton: true, hasTapAction: true, + hasFocusAction: true, isFocusable: true, )); expect(tester.getSemantics(find.text('28')), matchesSemantics( label: '28, Thursday, January 28, 2016', isButton: true, hasTapAction: true, + hasFocusAction: true, isFocusable: true, )); expect(tester.getSemantics(find.text('29')), matchesSemantics( label: '29, Friday, January 29, 2016', isButton: true, hasTapAction: true, + hasFocusAction: true, isFocusable: true, )); expect(tester.getSemantics(find.text('30')), matchesSemantics( label: '30, Saturday, January 30, 2016', isButton: true, hasTapAction: true, + hasFocusAction: true, isFocusable: true, )); semantics.dispose(); @@ -1081,6 +1113,7 @@ void main() { expect(tester.getSemantics(find.text('$year')), matchesSemantics( label: '$year', hasTapAction: true, + hasFocusAction: true, isSelected: year == 2016, isFocusable: true, isButton: true, diff --git a/packages/flutter/test/material/card_test.dart b/packages/flutter/test/material/card_test.dart index c8a5815e441..5e9003a1bf5 100644 --- a/packages/flutter/test/material/card_test.dart +++ b/packages/flutter/test/material/card_test.dart @@ -130,6 +130,7 @@ void main() { textDirection: TextDirection.ltr, actions: [ SemanticsAction.tap, + SemanticsAction.focus, ], flags: [ SemanticsFlag.hasEnabledState, diff --git a/packages/flutter/test/material/checkbox_list_tile_test.dart b/packages/flutter/test/material/checkbox_list_tile_test.dart index b91628a16c1..81acbc9a605 100644 --- a/packages/flutter/test/material/checkbox_list_tile_test.dart +++ b/packages/flutter/test/material/checkbox_list_tile_test.dart @@ -1189,6 +1189,7 @@ void main() { hasEnabledState: true, isEnabled: true, hasTapAction: true, + hasFocusAction: true, isFocusable: true, label: 'Hello\nthere', )); diff --git a/packages/flutter/test/material/checkbox_test.dart b/packages/flutter/test/material/checkbox_test.dart index 636456d9620..56cbf37d977 100644 --- a/packages/flutter/test/material/checkbox_test.dart +++ b/packages/flutter/test/material/checkbox_test.dart @@ -78,6 +78,7 @@ void main() { hasEnabledState: true, isEnabled: true, hasTapAction: true, + hasFocusAction: true, isFocusable: true, )); @@ -97,6 +98,7 @@ void main() { isChecked: true, isEnabled: true, hasTapAction: true, + hasFocusAction: true, isFocusable: true, )); @@ -115,6 +117,7 @@ void main() { hasEnabledState: true, // isFocusable is delayed by 1 frame. isFocusable: true, + hasFocusAction: true, )); await tester.pump(); @@ -213,6 +216,7 @@ void main() { isChecked: true, isEnabled: true, hasTapAction: true, + hasFocusAction: true, isFocusable: true, )); handle.dispose(); @@ -242,6 +246,7 @@ void main() { hasEnabledState: true, isEnabled: true, hasTapAction: true, + hasFocusAction: true, isFocusable: true, )); handle.dispose(); @@ -317,7 +322,7 @@ void main() { SemanticsFlag.isFocusable, SemanticsFlag.isCheckStateMixed, ], - actions: [SemanticsAction.tap], + actions: [SemanticsAction.tap, SemanticsAction.focus], ), hasLength(1)); await tester.pumpWidget( @@ -341,7 +346,7 @@ void main() { SemanticsFlag.isChecked, SemanticsFlag.isFocusable, ], - actions: [SemanticsAction.tap], + actions: [SemanticsAction.tap, SemanticsAction.focus], ), hasLength(1)); await tester.pumpWidget( @@ -364,7 +369,7 @@ void main() { SemanticsFlag.isEnabled, SemanticsFlag.isFocusable, ], - actions: [SemanticsAction.tap], + actions: [SemanticsAction.tap, SemanticsAction.focus], ), hasLength(1)); semantics.dispose(); diff --git a/packages/flutter/test/material/chip_test.dart b/packages/flutter/test/material/chip_test.dart index 0a398a1dad7..d86147d0991 100644 --- a/packages/flutter/test/material/chip_test.dart +++ b/packages/flutter/test/material/chip_test.dart @@ -2971,7 +2971,7 @@ void main() { children: [ TestSemantics( tooltip: 'Delete', - actions: [SemanticsAction.tap], + actions: [SemanticsAction.tap, SemanticsAction.focus], textDirection: TextDirection.ltr, flags: [ SemanticsFlag.isButton, @@ -3030,7 +3030,7 @@ void main() { SemanticsFlag.isEnabled, SemanticsFlag.isFocusable, ], - actions: [SemanticsAction.tap], + actions: [SemanticsAction.tap, SemanticsAction.focus], ), ], ), @@ -3088,7 +3088,7 @@ void main() { SemanticsFlag.isEnabled, SemanticsFlag.isFocusable, ], - actions: [SemanticsAction.tap], + actions: [SemanticsAction.tap, SemanticsAction.focus], ), ], ), @@ -3141,7 +3141,7 @@ void main() { SemanticsFlag.isFocusable, SemanticsFlag.isSelected, ], - actions: [SemanticsAction.tap], + actions: [SemanticsAction.tap, SemanticsAction.focus], ), ], ), @@ -3295,7 +3295,7 @@ void main() { SemanticsFlag.isEnabled, SemanticsFlag.isFocusable, ], - actions: [SemanticsAction.tap], + actions: [SemanticsAction.tap, SemanticsAction.focus], ), ], ), diff --git a/packages/flutter/test/material/date_picker_test.dart b/packages/flutter/test/material/date_picker_test.dart index df83154d4df..8ba368cbea1 100644 --- a/packages/flutter/test/material/date_picker_test.dart +++ b/packages/flutter/test/material/date_picker_test.dart @@ -1545,6 +1545,7 @@ void main() { label: '3, Sunday, January 3, 2016, Today', isButton: true, hasTapAction: true, + hasFocusAction: true, isFocusable: true, )); @@ -1553,6 +1554,7 @@ void main() { tooltip: 'Switch to input', isButton: true, hasTapAction: true, + hasFocusAction: true, isEnabled: true, hasEnabledState: true, isFocusable: true, @@ -1565,6 +1567,7 @@ void main() { label: 'OK', isButton: true, hasTapAction: true, + hasFocusAction: true, isEnabled: true, hasEnabledState: true, isFocusable: true, @@ -1573,6 +1576,7 @@ void main() { label: 'CANCEL', isButton: true, hasTapAction: true, + hasFocusAction: true, isEnabled: true, hasEnabledState: true, isFocusable: true, @@ -1603,6 +1607,7 @@ void main() { tooltip: 'Switch to calendar', isButton: true, hasTapAction: true, + hasFocusAction: true, isEnabled: true, hasEnabledState: true, isFocusable: true, @@ -1630,6 +1635,7 @@ void main() { label: 'OK', isButton: true, hasTapAction: true, + hasFocusAction: true, isEnabled: true, hasEnabledState: true, isFocusable: true, @@ -1638,6 +1644,7 @@ void main() { label: 'CANCEL', isButton: true, hasTapAction: true, + hasFocusAction: true, isEnabled: true, hasEnabledState: true, isFocusable: true, diff --git a/packages/flutter/test/material/date_range_picker_test.dart b/packages/flutter/test/material/date_range_picker_test.dart index 353e35d47aa..dbe3cdd4ee9 100644 --- a/packages/flutter/test/material/date_range_picker_test.dart +++ b/packages/flutter/test/material/date_range_picker_test.dart @@ -1319,6 +1319,7 @@ void main() { matchesSemantics( label: '30, Saturday, January 30, 2016, Today', hasTapAction: true, + hasFocusAction: true, isFocusable: true, ), ); diff --git a/packages/flutter/test/material/drawer_button_test.dart b/packages/flutter/test/material/drawer_button_test.dart index bb565c8c753..e1fe7353238 100644 --- a/packages/flutter/test/material/drawer_button_test.dart +++ b/packages/flutter/test/material/drawer_button_test.dart @@ -182,6 +182,7 @@ void main() { hasEnabledState: true, isEnabled: true, hasTapAction: true, + hasFocusAction: true, isFocusable: true, )); handle.dispose(); @@ -239,6 +240,7 @@ void main() { hasEnabledState: true, isEnabled: true, hasTapAction: true, + hasFocusAction: true, isFocusable: true, )); handle.dispose(); diff --git a/packages/flutter/test/material/drawer_test.dart b/packages/flutter/test/material/drawer_test.dart index 36b9ae2ff50..1562be4b655 100644 --- a/packages/flutter/test/material/drawer_test.dart +++ b/packages/flutter/test/material/drawer_test.dart @@ -147,7 +147,7 @@ void main() { expect(semantics, isNot(includesNodeWith( label: const DefaultMaterialLocalizations().modalBarrierDismissLabel, - actions: [SemanticsAction.tap], + actions: [SemanticsAction.tap, SemanticsAction.focus], ))); semantics.dispose(); diff --git a/packages/flutter/test/material/dropdown_test.dart b/packages/flutter/test/material/dropdown_test.dart index 5ec084aa05e..c04ae2b1aa4 100644 --- a/packages/flutter/test/material/dropdown_test.dart +++ b/packages/flutter/test/material/dropdown_test.dart @@ -1300,6 +1300,7 @@ void main() { isButton: true, label: 'test', hasTapAction: true, + hasFocusAction: true, isFocusable: true, )); @@ -1315,6 +1316,7 @@ void main() { isButton: true, label: 'three', hasTapAction: true, + hasFocusAction: true, isFocusable: true, )); handle.dispose(); @@ -1360,28 +1362,28 @@ void main() { SemanticsFlag.isFocusable, ], tags: [const SemanticsTag('RenderViewport.twoPane')], - actions: [SemanticsAction.tap], + actions: [SemanticsAction.tap, SemanticsAction.focus], ), TestSemantics( label: 'two', textDirection: TextDirection.ltr, flags: [SemanticsFlag.isFocusable], tags: [const SemanticsTag('RenderViewport.twoPane')], - actions: [SemanticsAction.tap], + actions: [SemanticsAction.tap, SemanticsAction.focus], ), TestSemantics( label: 'three', textDirection: TextDirection.ltr, flags: [SemanticsFlag.isFocusable], tags: [const SemanticsTag('RenderViewport.twoPane')], - actions: [SemanticsAction.tap], + actions: [SemanticsAction.tap, SemanticsAction.focus], ), TestSemantics( label: 'four', textDirection: TextDirection.ltr, flags: [SemanticsFlag.isFocusable], tags: [const SemanticsTag('RenderViewport.twoPane')], - actions: [SemanticsAction.tap], + actions: [SemanticsAction.tap, SemanticsAction.focus], ), ], ), diff --git a/packages/flutter/test/material/elevated_button_test.dart b/packages/flutter/test/material/elevated_button_test.dart index 2e9d958bebf..d6627b5d944 100644 --- a/packages/flutter/test/material/elevated_button_test.dart +++ b/packages/flutter/test/material/elevated_button_test.dart @@ -819,6 +819,7 @@ void main() { TestSemantics.rootChild( actions: [ SemanticsAction.tap, + SemanticsAction.focus, ], label: 'ABC', rect: const Rect.fromLTRB(0.0, 0.0, 88.0, 48.0), diff --git a/packages/flutter/test/material/expand_icon_test.dart b/packages/flutter/test/material/expand_icon_test.dart index 7ec1338fa44..7ff43ab84fd 100644 --- a/packages/flutter/test/material/expand_icon_test.dart +++ b/packages/flutter/test/material/expand_icon_test.dart @@ -217,6 +217,7 @@ void main() { expect(tester.getSemantics(find.byType(ExpandIcon)), matchesSemantics( hasTapAction: true, + hasFocusAction: true, hasEnabledState: true, isEnabled: true, isFocusable: true, @@ -233,6 +234,7 @@ void main() { expect(tester.getSemantics(find.byType(ExpandIcon)), matchesSemantics( hasTapAction: true, + hasFocusAction: true, hasEnabledState: true, isEnabled: true, isFocusable: true, @@ -258,6 +260,7 @@ void main() { children: [ matchesSemantics( hasTapAction: true, + hasFocusAction: true, hasEnabledState: true, isEnabled: true, isFocusable: true, @@ -277,6 +280,7 @@ void main() { children: [ matchesSemantics( hasTapAction: true, + hasFocusAction: true, hasEnabledState: true, isEnabled: true, isFocusable: true, diff --git a/packages/flutter/test/material/expansion_panel_test.dart b/packages/flutter/test/material/expansion_panel_test.dart index feab74d92d2..8df161448fe 100644 --- a/packages/flutter/test/material/expansion_panel_test.dart +++ b/packages/flutter/test/material/expansion_panel_test.dart @@ -211,6 +211,7 @@ void main() { isEnabled: true, isFocusable: true, hasTapAction: true, + hasFocusAction: true, )); // Check custom header widget semantics is preserved. @@ -261,6 +262,7 @@ void main() { isEnabled: true, isFocusable: true, hasTapAction: true, + hasFocusAction: true, ), ], )); @@ -1099,6 +1101,7 @@ void main() { isEnabled: true, isFocusable: true, hasTapAction: true, + hasFocusAction: true, onTapHint: localizations.expandedIconTapHint, )); @@ -1123,6 +1126,7 @@ void main() { isEnabled: true, isFocusable: true, hasTapAction: true, + hasFocusAction: true, onTapHint: localizations.collapsedIconTapHint, )); @@ -1187,6 +1191,7 @@ void main() { isEnabled: true, isFocusable: true, hasTapAction: true, + hasFocusAction: true, ), ], )); @@ -1215,6 +1220,7 @@ void main() { isEnabled: true, isFocusable: true, hasTapAction: true, + hasFocusAction: true, ), ], )); @@ -1268,6 +1274,7 @@ void main() { isFocusable: true, hasEnabledState: true, hasTapAction: true, + hasFocusAction: true, )); expect(tester.getSemantics(find.byKey(collapsedKey)), matchesSemantics( @@ -1276,6 +1283,7 @@ void main() { isFocusable: true, hasEnabledState: true, hasTapAction: true, + hasFocusAction: true, )); handle.dispose(); diff --git a/packages/flutter/test/material/expansion_tile_test.dart b/packages/flutter/test/material/expansion_tile_test.dart index 70daebbb82f..c6de9c673ec 100644 --- a/packages/flutter/test/material/expansion_tile_test.dart +++ b/packages/flutter/test/material/expansion_tile_test.dart @@ -728,6 +728,7 @@ void main() { tester.getSemantics(find.byType(ListTile).first), matchesSemantics( hasTapAction: true, + hasFocusAction: true, hasEnabledState: true, isEnabled: true, isFocused: true, @@ -742,6 +743,7 @@ void main() { tester.getSemantics(find.byType(ListTile).last), matchesSemantics( hasTapAction: true, + hasFocusAction: true, hasEnabledState: true, isEnabled: true, isFocusable: true, diff --git a/packages/flutter/test/material/filled_button_test.dart b/packages/flutter/test/material/filled_button_test.dart index e0dcc9f26b5..ad7f766e191 100644 --- a/packages/flutter/test/material/filled_button_test.dart +++ b/packages/flutter/test/material/filled_button_test.dart @@ -1004,6 +1004,7 @@ void main() { TestSemantics.rootChild( actions: [ SemanticsAction.tap, + SemanticsAction.focus, ], label: 'ABC', rect: const Rect.fromLTRB(0.0, 0.0, 88.0, 48.0), diff --git a/packages/flutter/test/material/floating_action_button_test.dart b/packages/flutter/test/material/floating_action_button_test.dart index e5cfc6b3f5b..5a9f0148ced 100644 --- a/packages/flutter/test/material/floating_action_button_test.dart +++ b/packages/flutter/test/material/floating_action_button_test.dart @@ -631,6 +631,7 @@ void main() { ], actions: [ SemanticsAction.tap, + SemanticsAction.focus, ], ), ], @@ -699,6 +700,7 @@ void main() { tooltip: 'Add Photo', actions: [ SemanticsAction.tap, + SemanticsAction.focus, ], flags: [ SemanticsFlag.hasEnabledState, @@ -922,6 +924,7 @@ void main() { tester.getSemantics(find.byType(FloatingActionButton)), matchesSemantics( hasTapAction: true, + hasFocusAction: true, hasEnabledState: true, isButton: true, isEnabled: true, diff --git a/packages/flutter/test/material/icon_button_test.dart b/packages/flutter/test/material/icon_button_test.dart index 7814043b776..cdae2a94318 100644 --- a/packages/flutter/test/material/icon_button_test.dart +++ b/packages/flutter/test/material/icon_button_test.dart @@ -616,6 +616,7 @@ void main() { rect: const Rect.fromLTRB(0.0, 0.0, 48.0, 48.0), actions: [ SemanticsAction.tap, + SemanticsAction.focus, ], flags: [ SemanticsFlag.hasEnabledState, @@ -690,6 +691,7 @@ void main() { TestSemantics( actions: [ SemanticsAction.tap, + SemanticsAction.focus, ], flags: [ SemanticsFlag.hasEnabledState, @@ -2177,6 +2179,7 @@ void main() { TestSemantics.rootChild( actions: [ SemanticsAction.tap, + SemanticsAction.focus, ], rect: const Rect.fromLTRB(0.0, 0.0, 88.0, 48.0), transform: Matrix4.translationValues(356.0, 276.0, 0.0), diff --git a/packages/flutter/test/material/ink_well_test.dart b/packages/flutter/test/material/ink_well_test.dart index d90aded12e3..3cc961ccc10 100644 --- a/packages/flutter/test/material/ink_well_test.dart +++ b/packages/flutter/test/material/ink_well_test.dart @@ -1178,7 +1178,7 @@ testWidgets('InkResponse radius can be updated', (WidgetTester tester) async { ), ), )); - expect(semantics, includesNodeWith(label: 'Button', actions: [SemanticsAction.tap])); + expect(semantics, includesNodeWith(label: 'Button', actions: [SemanticsAction.tap, SemanticsAction.focus])); await tester.pumpWidget(Directionality( textDirection: TextDirection.ltr, @@ -1190,7 +1190,7 @@ testWidgets('InkResponse radius can be updated', (WidgetTester tester) async { ), ), )); - expect(semantics, isNot(includesNodeWith(label: 'Button', actions: [SemanticsAction.tap]))); + expect(semantics, isNot(includesNodeWith(label: 'Button', actions: [SemanticsAction.tap, SemanticsAction.focus]))); semantics.dispose(); }); @@ -1983,6 +1983,7 @@ testWidgets('InkResponse radius can be updated', (WidgetTester tester) async { label: 'Foo', hasLongPressAction: true, isFocusable: true, + hasFocusAction: true, textDirection: TextDirection.ltr, )); @@ -2003,6 +2004,7 @@ testWidgets('InkResponse radius can be updated', (WidgetTester tester) async { expect(tester.getSemantics(find.bySemanticsLabel('Foo')), matchesSemantics( label: 'Foo', hasTapAction: true, + hasFocusAction: true, hasLongPressAction: true, isFocusable: true, textDirection: TextDirection.ltr, diff --git a/packages/flutter/test/material/list_tile_test.dart b/packages/flutter/test/material/list_tile_test.dart index 4860309ce34..97d8ea6abe7 100644 --- a/packages/flutter/test/material/list_tile_test.dart +++ b/packages/flutter/test/material/list_tile_test.dart @@ -308,7 +308,7 @@ void main() { SemanticsFlag.isEnabled, SemanticsFlag.isFocusable, ], - actions: [SemanticsAction.tap], + actions: [SemanticsAction.tap, SemanticsAction.focus], label: 'two', ), TestSemantics.rootChild( diff --git a/packages/flutter/test/material/material_button_test.dart b/packages/flutter/test/material/material_button_test.dart index 482812fdd89..4f1612bfa1c 100644 --- a/packages/flutter/test/material/material_button_test.dart +++ b/packages/flutter/test/material/material_button_test.dart @@ -620,6 +620,7 @@ void main() { label: 'Button', actions: [ SemanticsAction.tap, + SemanticsAction.focus, ], flags: [ SemanticsFlag.hasEnabledState, @@ -661,6 +662,7 @@ void main() { SemanticsFlag.isButton, SemanticsFlag.isFocusable, ], + actions: [SemanticsAction.focus], ), ], ), diff --git a/packages/flutter/test/material/menu_anchor_test.dart b/packages/flutter/test/material/menu_anchor_test.dart index 3759ccf1915..85676da1834 100644 --- a/packages/flutter/test/material/menu_anchor_test.dart +++ b/packages/flutter/test/material/menu_anchor_test.dart @@ -3421,6 +3421,7 @@ void main() { TestSemantics.rootChild( actions: [ SemanticsAction.tap, + SemanticsAction.focus, ], label: 'ABC', rect: const Rect.fromLTRB(0.0, 0.0, 88.0, 48.0), @@ -3551,7 +3552,7 @@ void main() { SemanticsFlag.hasExpandedState, SemanticsFlag.isExpanded, ], - actions: [SemanticsAction.tap], + actions: [SemanticsAction.tap, SemanticsAction.focus], label: 'ABC', rect: const Rect.fromLTRB(0.0, 0.0, 88.0, 48.0), ), @@ -3573,7 +3574,7 @@ void main() { SemanticsFlag.isEnabled, SemanticsFlag.isFocusable, ], - actions: [SemanticsAction.tap], + actions: [SemanticsAction.tap, SemanticsAction.focus], ), ], ), @@ -3621,7 +3622,7 @@ void main() { SemanticsFlag.isEnabled, SemanticsFlag.isFocusable, ], - actions: [SemanticsAction.tap], + actions: [SemanticsAction.tap, SemanticsAction.focus], label: 'ABC', rect: const Rect.fromLTRB(0.0, 0.0, 88.0, 48.0), ), diff --git a/packages/flutter/test/material/navigation_bar_test.dart b/packages/flutter/test/material/navigation_bar_test.dart index f4676d597f6..01ff1cb19f4 100644 --- a/packages/flutter/test/material/navigation_bar_test.dart +++ b/packages/flutter/test/material/navigation_bar_test.dart @@ -559,6 +559,7 @@ void main() { isFocusable: true, isSelected: true, hasTapAction: true, + hasFocusAction: true, ), ); expect( @@ -568,6 +569,7 @@ void main() { textDirection: TextDirection.ltr, isFocusable: true, hasTapAction: true, + hasFocusAction: true, ), ); @@ -580,6 +582,7 @@ void main() { textDirection: TextDirection.ltr, isFocusable: true, hasTapAction: true, + hasFocusAction: true, ), ); expect( @@ -590,6 +593,7 @@ void main() { isFocusable: true, isSelected: true, hasTapAction: true, + hasFocusAction: true, ), ); }); @@ -624,6 +628,7 @@ void main() { isFocusable: true, isSelected: true, hasTapAction: true, + hasFocusAction: true, ), ); expect( @@ -633,6 +638,7 @@ void main() { textDirection: TextDirection.ltr, isFocusable: true, hasTapAction: true, + hasFocusAction: true, ), ); @@ -645,6 +651,7 @@ void main() { textDirection: TextDirection.ltr, isFocusable: true, hasTapAction: true, + hasFocusAction: true, ), ); expect( @@ -655,6 +662,7 @@ void main() { isFocusable: true, isSelected: true, hasTapAction: true, + hasFocusAction: true, ), ); }); diff --git a/packages/flutter/test/material/navigation_drawer_test.dart b/packages/flutter/test/material/navigation_drawer_test.dart index 35c39f918d3..d38a064469d 100644 --- a/packages/flutter/test/material/navigation_drawer_test.dart +++ b/packages/flutter/test/material/navigation_drawer_test.dart @@ -324,6 +324,7 @@ void main() { isFocusable: true, isSelected: true, hasTapAction: true, + hasFocusAction: true, ), ); expect( @@ -333,6 +334,7 @@ void main() { textDirection: TextDirection.ltr, isFocusable: true, hasTapAction: true, + hasFocusAction: true, ), ); @@ -345,6 +347,7 @@ void main() { textDirection: TextDirection.ltr, isFocusable: true, hasTapAction: true, + hasFocusAction: true, ), ); expect( @@ -355,6 +358,7 @@ void main() { isFocusable: true, isSelected: true, hasTapAction: true, + hasFocusAction: true, ), ); }); diff --git a/packages/flutter/test/material/navigation_rail_test.dart b/packages/flutter/test/material/navigation_rail_test.dart index de70ed5f7ad..8e70e6cd213 100644 --- a/packages/flutter/test/material/navigation_rail_test.dart +++ b/packages/flutter/test/material/navigation_rail_test.dart @@ -5513,25 +5513,25 @@ TestSemantics _expectedSemantics() { SemanticsFlag.isSelected, SemanticsFlag.isFocusable, ], - actions: [SemanticsAction.tap], + actions: [SemanticsAction.tap, SemanticsAction.focus], label: 'Abc\nTab 1 of 4', textDirection: TextDirection.ltr, ), TestSemantics( flags: [SemanticsFlag.isFocusable], - actions: [SemanticsAction.tap], + actions: [SemanticsAction.tap, SemanticsAction.focus], label: 'Def\nTab 2 of 4', textDirection: TextDirection.ltr, ), TestSemantics( flags: [SemanticsFlag.isFocusable], - actions: [SemanticsAction.tap], + actions: [SemanticsAction.tap, SemanticsAction.focus], label: 'Ghi\nTab 3 of 4', textDirection: TextDirection.ltr, ), TestSemantics( flags: [SemanticsFlag.isFocusable], - actions: [SemanticsAction.tap], + actions: [SemanticsAction.tap, SemanticsAction.focus], label: 'Jkl\nTab 4 of 4', textDirection: TextDirection.ltr, ), diff --git a/packages/flutter/test/material/outlined_button_test.dart b/packages/flutter/test/material/outlined_button_test.dart index 6b9241b7bc5..e2a9235e878 100644 --- a/packages/flutter/test/material/outlined_button_test.dart +++ b/packages/flutter/test/material/outlined_button_test.dart @@ -1073,6 +1073,7 @@ void main() { TestSemantics.rootChild( actions: [ SemanticsAction.tap, + SemanticsAction.focus, ], label: 'ABC', rect: const Rect.fromLTRB(0.0, 0.0, 88.0, 48.0), diff --git a/packages/flutter/test/material/popup_menu_test.dart b/packages/flutter/test/material/popup_menu_test.dart index 95cd7f0eba1..7c530194526 100644 --- a/packages/flutter/test/material/popup_menu_test.dart +++ b/packages/flutter/test/material/popup_menu_test.dart @@ -1219,7 +1219,7 @@ void main() { SemanticsFlag.isEnabled, SemanticsFlag.isFocusable, ], - actions: [SemanticsAction.tap], + actions: [SemanticsAction.tap, SemanticsAction.focus], label: '1', textDirection: TextDirection.ltr, ), @@ -1230,7 +1230,7 @@ void main() { SemanticsFlag.isEnabled, SemanticsFlag.isFocusable, ], - actions: [SemanticsAction.tap], + actions: [SemanticsAction.tap, SemanticsAction.focus], label: '2', textDirection: TextDirection.ltr, ), @@ -1241,7 +1241,7 @@ void main() { SemanticsFlag.isEnabled, SemanticsFlag.isFocusable, ], - actions: [SemanticsAction.tap], + actions: [SemanticsAction.tap, SemanticsAction.focus], label: '3', textDirection: TextDirection.ltr, ), @@ -1252,7 +1252,7 @@ void main() { SemanticsFlag.isEnabled, SemanticsFlag.isFocusable, ], - actions: [SemanticsAction.tap], + actions: [SemanticsAction.tap, SemanticsAction.focus], label: '4', textDirection: TextDirection.ltr, ), @@ -1263,7 +1263,7 @@ void main() { SemanticsFlag.isEnabled, SemanticsFlag.isFocusable, ], - actions: [SemanticsAction.tap], + actions: [SemanticsAction.tap, SemanticsAction.focus], label: '5', textDirection: TextDirection.ltr, ), @@ -1351,7 +1351,7 @@ void main() { SemanticsFlag.isEnabled, SemanticsFlag.isFocusable, ], - actions: [SemanticsAction.tap], + actions: [SemanticsAction.tap, SemanticsAction.focus], label: 'test1\ntest2', textDirection: TextDirection.ltr, ), @@ -1432,7 +1432,7 @@ void main() { SemanticsFlag.isEnabled, SemanticsFlag.isFocusable, ], - actions: [SemanticsAction.tap], + actions: [SemanticsAction.tap, SemanticsAction.focus], label: '1', textDirection: TextDirection.ltr, ), @@ -1452,7 +1452,7 @@ void main() { SemanticsFlag.isEnabled, SemanticsFlag.isFocusable, ], - actions: [SemanticsAction.tap], + actions: [SemanticsAction.tap, SemanticsAction.focus], label: '3', textDirection: TextDirection.ltr, ), @@ -1463,7 +1463,7 @@ void main() { SemanticsFlag.isEnabled, SemanticsFlag.isFocusable, ], - actions: [SemanticsAction.tap], + actions: [SemanticsAction.tap, SemanticsAction.focus], label: '4', textDirection: TextDirection.ltr, ), @@ -1474,7 +1474,7 @@ void main() { SemanticsFlag.isEnabled, SemanticsFlag.isFocusable, ], - actions: [SemanticsAction.tap], + actions: [SemanticsAction.tap, SemanticsAction.focus], label: '5', textDirection: TextDirection.ltr, ), diff --git a/packages/flutter/test/material/radio_list_tile_test.dart b/packages/flutter/test/material/radio_list_tile_test.dart index 43355b2ce87..c1bb21ae161 100644 --- a/packages/flutter/test/material/radio_list_tile_test.dart +++ b/packages/flutter/test/material/radio_list_tile_test.dart @@ -411,7 +411,7 @@ void main() { SemanticsFlag.isInMutuallyExclusiveGroup, SemanticsFlag.isFocusable, ], - actions: [SemanticsAction.tap], + actions: [SemanticsAction.tap, SemanticsAction.focus], label: 'Title', textDirection: TextDirection.ltr, ), @@ -448,7 +448,7 @@ void main() { SemanticsFlag.isInMutuallyExclusiveGroup, SemanticsFlag.isFocusable, ], - actions: [SemanticsAction.tap], + actions: [SemanticsAction.tap, SemanticsAction.focus], label: 'Title', textDirection: TextDirection.ltr, ), @@ -483,6 +483,7 @@ void main() { SemanticsFlag.isInMutuallyExclusiveGroup, SemanticsFlag.isFocusable, ], + actions: [SemanticsAction.focus], label: 'Title', textDirection: TextDirection.ltr, ), diff --git a/packages/flutter/test/material/radio_test.dart b/packages/flutter/test/material/radio_test.dart index 4aabeed1a87..8b0456b7fc8 100644 --- a/packages/flutter/test/material/radio_test.dart +++ b/packages/flutter/test/material/radio_test.dart @@ -221,6 +221,7 @@ void main() { ], actions: [ SemanticsAction.tap, + SemanticsAction.focus, ], ), ); @@ -254,6 +255,7 @@ void main() { ], actions: [ SemanticsAction.tap, + SemanticsAction.focus, ], ), ], @@ -284,6 +286,7 @@ void main() { ], actions: [ SemanticsAction.tap, + SemanticsAction.focus, ], ), ], @@ -310,6 +313,7 @@ void main() { SemanticsFlag.isInMutuallyExclusiveGroup, SemanticsFlag.isFocusable, // This flag is delayed by 1 frame. ], + actions: [SemanticsAction.focus], ), ], ), ignoreRect: true, ignoreTransform: true)); diff --git a/packages/flutter/test/material/raw_material_button_test.dart b/packages/flutter/test/material/raw_material_button_test.dart index d58db5f7851..5f17df39f71 100644 --- a/packages/flutter/test/material/raw_material_button_test.dart +++ b/packages/flutter/test/material/raw_material_button_test.dart @@ -160,6 +160,7 @@ void main() { ], actions: [ SemanticsAction.tap, + SemanticsAction.focus, ], label: '+', textDirection: TextDirection.ltr, diff --git a/packages/flutter/test/material/reorderable_list_test.dart b/packages/flutter/test/material/reorderable_list_test.dart index 5595fe6448f..fcd36d7d5c6 100644 --- a/packages/flutter/test/material/reorderable_list_test.dart +++ b/packages/flutter/test/material/reorderable_list_test.dart @@ -751,6 +751,7 @@ void main() { hasEnabledState: true, label: 'Switch tile', hasTapAction: true, + hasFocusAction: true, )); handle.dispose(); }); diff --git a/packages/flutter/test/material/search_test.dart b/packages/flutter/test/material/search_test.dart index 79e856c6cb7..61963b37ecf 100644 --- a/packages/flutter/test/material/search_test.dart +++ b/packages/flutter/test/material/search_test.dart @@ -662,7 +662,7 @@ void main() { SemanticsFlag.isEnabled, SemanticsFlag.isFocusable, ], - actions: [SemanticsAction.tap], + actions: [SemanticsAction.tap, SemanticsAction.focus], tooltip: 'Back', textDirection: TextDirection.ltr, ), @@ -718,7 +718,7 @@ void main() { SemanticsFlag.isEnabled, SemanticsFlag.isFocusable, ], - actions: [SemanticsAction.tap], + actions: [SemanticsAction.tap, SemanticsAction.focus], label: 'Suggestions', textDirection: TextDirection.ltr, ), @@ -812,7 +812,7 @@ void main() { SemanticsFlag.isEnabled, SemanticsFlag.isFocusable, ], - actions: [SemanticsAction.tap], + actions: [SemanticsAction.tap, SemanticsAction.focus], tooltip: 'Back', textDirection: TextDirection.ltr, ), @@ -856,7 +856,7 @@ void main() { SemanticsFlag.isEnabled, SemanticsFlag.isFocusable, ], - actions: [SemanticsAction.tap], + actions: [SemanticsAction.tap, SemanticsAction.focus], label: 'Suggestions', textDirection: TextDirection.ltr, ), diff --git a/packages/flutter/test/material/segmented_button_test.dart b/packages/flutter/test/material/segmented_button_test.dart index c05986a3d1c..06424c7cf29 100644 --- a/packages/flutter/test/material/segmented_button_test.dart +++ b/packages/flutter/test/material/segmented_button_test.dart @@ -449,6 +449,7 @@ void main() { label: '1', actions: [ SemanticsAction.tap, + SemanticsAction.focus, ], ), @@ -466,6 +467,7 @@ void main() { label: '2', actions: [ SemanticsAction.tap, + SemanticsAction.focus, ], ), @@ -529,6 +531,7 @@ void main() { label: '1', actions: [ SemanticsAction.tap, + SemanticsAction.focus, ], ), @@ -544,6 +547,7 @@ void main() { label: '2', actions: [ SemanticsAction.tap, + SemanticsAction.focus, ], ), diff --git a/packages/flutter/test/material/slider_test.dart b/packages/flutter/test/material/slider_test.dart index cb26860d915..9f2786db2e3 100644 --- a/packages/flutter/test/material/slider_test.dart +++ b/packages/flutter/test/material/slider_test.dart @@ -1292,6 +1292,7 @@ void main() { SemanticsFlag.isSlider, ], actions: [ + SemanticsAction.focus, SemanticsAction.increase, SemanticsAction.decrease, ], @@ -1350,6 +1351,7 @@ void main() { SemanticsFlag.isFocusable, SemanticsFlag.isSlider, ], + actions: [SemanticsAction.focus], value: '50%', increasedValue: '55%', decreasedValue: '45%', @@ -1452,7 +1454,7 @@ void main() { TestSemantics( id: 4, flags: [SemanticsFlag.hasEnabledState, SemanticsFlag.isEnabled, SemanticsFlag.isFocusable, SemanticsFlag.isSlider], - actions: [SemanticsAction.increase, SemanticsAction.decrease], + actions: [SemanticsAction.focus, SemanticsAction.increase, SemanticsAction.decrease], value: '50%', increasedValue: '60%', decreasedValue: '40%', @@ -1565,6 +1567,7 @@ void main() { SemanticsFlag.isSlider, ], actions: [ + SemanticsAction.focus, SemanticsAction.increase, SemanticsAction.decrease, SemanticsAction.didGainAccessibilityFocus, @@ -1625,6 +1628,7 @@ void main() { SemanticsFlag.isSlider, ], actions: [ + SemanticsAction.focus, SemanticsAction.didGainAccessibilityFocus, ], value: '50%', @@ -1729,7 +1733,7 @@ void main() { TestSemantics( id: 4, flags: [SemanticsFlag.hasEnabledState, SemanticsFlag.isEnabled, SemanticsFlag.isFocusable, SemanticsFlag.isSlider], - actions: [SemanticsAction.increase, SemanticsAction.decrease], + actions: [SemanticsAction.focus, SemanticsAction.increase, SemanticsAction.decrease], value: '40', increasedValue: '60', decreasedValue: '20', @@ -1789,7 +1793,7 @@ void main() { TestSemantics( id: 4, flags: [SemanticsFlag.hasEnabledState, SemanticsFlag.isEnabled, SemanticsFlag.isFocusable, SemanticsFlag.isSlider], - actions: [SemanticsAction.increase, SemanticsAction.decrease], + actions: [SemanticsAction.focus, SemanticsAction.increase, SemanticsAction.decrease], value: '40', increasedValue: '60', decreasedValue: '20', @@ -2633,6 +2637,7 @@ void main() { SemanticsFlag.isSlider, ], actions: [ + SemanticsAction.focus, SemanticsAction.increase, SemanticsAction.decrease, SemanticsAction.didGainAccessibilityFocus, diff --git a/packages/flutter/test/material/switch_list_tile_test.dart b/packages/flutter/test/material/switch_list_tile_test.dart index bfdf3ba9e50..c42b4e0ac61 100644 --- a/packages/flutter/test/material/switch_list_tile_test.dart +++ b/packages/flutter/test/material/switch_list_tile_test.dart @@ -78,7 +78,7 @@ void main() { SemanticsFlag.isFocusable, SemanticsFlag.isToggled, ], - actions: SemanticsAction.tap.index, + actions: SemanticsAction.tap.index | SemanticsAction.focus.index, label: 'aaa\nAAA', ), TestSemantics.rootChild( @@ -92,7 +92,7 @@ void main() { SemanticsFlag.isEnabled, SemanticsFlag.isFocusable, ], - actions: SemanticsAction.tap.index, + actions: SemanticsAction.tap.index | SemanticsAction.focus.index, label: 'bbb\nBBB', ), TestSemantics.rootChild( @@ -106,7 +106,7 @@ void main() { SemanticsFlag.isFocusable, SemanticsFlag.isInMutuallyExclusiveGroup, ], - actions: SemanticsAction.tap.index, + actions: SemanticsAction.tap.index | SemanticsAction.focus.index, label: 'CCC\nccc', ), ], diff --git a/packages/flutter/test/material/tabs_test.dart b/packages/flutter/test/material/tabs_test.dart index aa9091fb6bf..d0b66dce901 100644 --- a/packages/flutter/test/material/tabs_test.dart +++ b/packages/flutter/test/material/tabs_test.dart @@ -3592,7 +3592,7 @@ void main() { children: [ TestSemantics( id: 4, - actions: [SemanticsAction.tap], + actions: [SemanticsAction.tap, SemanticsAction.focus], flags: [ SemanticsFlag.isSelected, SemanticsFlag.isFocusable, @@ -3604,7 +3604,7 @@ void main() { TestSemantics( id: 5, flags: [SemanticsFlag.isFocusable], - actions: [SemanticsAction.tap], + actions: [SemanticsAction.tap, SemanticsAction.focus], label: 'TAB #1\nTab 2 of 2', rect: const Rect.fromLTRB(0.0, 0.0, 116.0, kTextTabBarHeight), transform: Matrix4.translationValues(116.0, 276.0, 0.0), @@ -3863,7 +3863,7 @@ void main() { SemanticsFlag.isSelected, SemanticsFlag.isFocusable, ], - actions: [SemanticsAction.tap], + actions: [SemanticsAction.tap, SemanticsAction.focus], label: 'Semantics override 0\nTab 1 of 2', rect: const Rect.fromLTRB(0.0, 0.0, 116.0, kTextTabBarHeight), transform: Matrix4.translationValues(0.0, 276.0, 0.0), @@ -3871,7 +3871,7 @@ void main() { TestSemantics( id: 5, flags: [SemanticsFlag.isFocusable], - actions: [SemanticsAction.tap], + actions: [SemanticsAction.tap, SemanticsAction.focus], label: 'Semantics override 1\nTab 2 of 2', rect: const Rect.fromLTRB(0.0, 0.0, 116.0, kTextTabBarHeight), transform: Matrix4.translationValues(116.0, 276.0, 0.0), @@ -5652,14 +5652,14 @@ void main() { flags: [SemanticsFlag.isFocusable, SemanticsFlag.isSelected], id: 2, rect: TestSemantics.fullScreen, - actions: 1, + actions: 1 | SemanticsAction.focus.index, ), TestSemantics( label: 'TAB2\nTab 2 of 2', flags: [SemanticsFlag.isFocusable], id: 3, rect: TestSemantics.fullScreen, - actions: [SemanticsAction.tap], + actions: [SemanticsAction.tap, SemanticsAction.focus], ), TestSemantics( id: 4, diff --git a/packages/flutter/test/material/text_button_test.dart b/packages/flutter/test/material/text_button_test.dart index f213635cb78..640d9649f89 100644 --- a/packages/flutter/test/material/text_button_test.dart +++ b/packages/flutter/test/material/text_button_test.dart @@ -607,6 +607,7 @@ void main() { TestSemantics.rootChild( actions: [ SemanticsAction.tap, + SemanticsAction.focus, ], label: 'ABC', rect: const Rect.fromLTRB(0.0, 0.0, 88.0, 48.0), diff --git a/packages/flutter/test/material/text_field_test.dart b/packages/flutter/test/material/text_field_test.dart index 1f667d152ee..fd1f69e7914 100644 --- a/packages/flutter/test/material/text_field_test.dart +++ b/packages/flutter/test/material/text_field_test.dart @@ -6964,7 +6964,7 @@ void main() { ), ); - expect(semantics, isNot(includesNodeWith(actions: [SemanticsAction.tap]))); + expect(semantics, isNot(includesNodeWith(actions: [SemanticsAction.tap, SemanticsAction.focus]))); semantics.dispose(); }); @@ -7005,7 +7005,7 @@ void main() { ), ); - expect(semantics, isNot(includesNodeWith(actions: [SemanticsAction.tap]))); + expect(semantics, isNot(includesNodeWith(actions: [SemanticsAction.tap, SemanticsAction.focus]))); semantics.dispose(); }); diff --git a/packages/flutter/test/material/time_picker_test.dart b/packages/flutter/test/material/time_picker_test.dart index 60b44a4bc53..1236c63fc11 100644 --- a/packages/flutter/test/material/time_picker_test.dart +++ b/packages/flutter/test/material/time_picker_test.dart @@ -1250,7 +1250,7 @@ void main() { semantics, includesNodeWith( label: amString, - actions: [SemanticsAction.tap], + actions: [SemanticsAction.tap, SemanticsAction.focus], flags: [ SemanticsFlag.isButton, SemanticsFlag.isChecked, @@ -1264,7 +1264,7 @@ void main() { semantics, includesNodeWith( label: pmString, - actions: [SemanticsAction.tap], + actions: [SemanticsAction.tap, SemanticsAction.focus], flags: [ SemanticsFlag.isButton, SemanticsFlag.isInMutuallyExclusiveGroup, diff --git a/packages/flutter/test/material/toggle_buttons_test.dart b/packages/flutter/test/material/toggle_buttons_test.dart index 1681ca3a801..9da18f8f8d9 100644 --- a/packages/flutter/test/material/toggle_buttons_test.dart +++ b/packages/flutter/test/material/toggle_buttons_test.dart @@ -2117,6 +2117,7 @@ void main() { ], actions: [ SemanticsAction.tap, + SemanticsAction.focus, ], rect: const Rect.fromLTRB(0.0, 0.0, 87.0, 48.0), ), @@ -2130,6 +2131,7 @@ void main() { ], actions: [ SemanticsAction.tap, + SemanticsAction.focus, ], rect: const Rect.fromLTRB(0.0, 0.0, 88.0, 48.0) ), @@ -2143,6 +2145,7 @@ void main() { ], actions: [ SemanticsAction.tap, + SemanticsAction.focus, ], rect: const Rect.fromLTRB(0.0, 0.0, 88.0, 48.0), ), @@ -2188,6 +2191,7 @@ void main() { ], actions: [ SemanticsAction.tap, + SemanticsAction.focus, ], ), TestSemantics( @@ -2201,6 +2205,7 @@ void main() { ], actions: [ SemanticsAction.tap, + SemanticsAction.focus, ], ), ], diff --git a/packages/flutter/test/material/user_accounts_drawer_header_test.dart b/packages/flutter/test/material/user_accounts_drawer_header_test.dart index a106eaabf8f..1da4ab880b2 100644 --- a/packages/flutter/test/material/user_accounts_drawer_header_test.dart +++ b/packages/flutter/test/material/user_accounts_drawer_header_test.dart @@ -531,6 +531,7 @@ void main() { flags: [SemanticsFlag.isFocusable], label: 'Signed in\nname\nemail', textDirection: TextDirection.ltr, + actions: [SemanticsAction.focus], children: [ TestSemantics( label: r'B', diff --git a/packages/flutter/test/widgets/absorb_pointer_test.dart b/packages/flutter/test/widgets/absorb_pointer_test.dart index 6c2a88f58ca..5952cc69b28 100644 --- a/packages/flutter/test/widgets/absorb_pointer_test.dart +++ b/packages/flutter/test/widgets/absorb_pointer_test.dart @@ -48,6 +48,7 @@ void main() { matchesSemantics( label: 'button', hasTapAction: true, + hasFocusAction: true, isButton: true, isFocusable: true, hasEnabledState: true, diff --git a/packages/flutter/test/widgets/actions_test.dart b/packages/flutter/test/widgets/actions_test.dart index 87d2f2b0e11..3b87e8c44f3 100644 --- a/packages/flutter/test/widgets/actions_test.dart +++ b/packages/flutter/test/widgets/actions_test.dart @@ -1013,9 +1013,11 @@ void main() { // This semantic is from `Focus` widget under `FocusableActionDetector`. matchesSemantics( isFocusable: true, + hasFocusAction: true, children: [ matchesSemantics( hasTapAction: true, + hasFocusAction: true, isButton: true, hasEnabledState: true, isEnabled: true, @@ -1025,6 +1027,7 @@ void main() { ), matchesSemantics( hasTapAction: true, + hasFocusAction: true, isButton: true, hasEnabledState: true, isEnabled: true, @@ -1068,6 +1071,7 @@ void main() { children: [ matchesSemantics( hasTapAction: true, + hasFocusAction: true, isButton: true, hasEnabledState: true, isEnabled: true, @@ -1077,6 +1081,7 @@ void main() { ), matchesSemantics( hasTapAction: true, + hasFocusAction: true, isButton: true, hasEnabledState: true, isEnabled: true, diff --git a/packages/flutter/test/widgets/basic_test.dart b/packages/flutter/test/widgets/basic_test.dart index 8ad224376c0..ee472a90854 100644 --- a/packages/flutter/test/widgets/basic_test.dart +++ b/packages/flutter/test/widgets/basic_test.dart @@ -858,6 +858,7 @@ void main() { matchesSemantics( label: 'button', hasTapAction: true, + hasFocusAction: true, isButton: true, isFocusable: true, hasEnabledState: true, diff --git a/packages/flutter/test/widgets/drawer_test.dart b/packages/flutter/test/widgets/drawer_test.dart index cb3aba7fd82..e6741fb2f28 100644 --- a/packages/flutter/test/widgets/drawer_test.dart +++ b/packages/flutter/test/widgets/drawer_test.dart @@ -348,7 +348,7 @@ void main() { scaffoldKey.currentState!.openDrawer(); await tester.pump(const Duration(milliseconds: 100)); - expect(semantics, isNot(includesNodeWith(actions: [SemanticsAction.tap]))); + expect(semantics, isNot(includesNodeWith(actions: [SemanticsAction.tap, SemanticsAction.focus]))); expect(semantics, isNot(includesNodeWith(label: 'Dismiss'))); semantics.dispose(); diff --git a/packages/flutter/test/widgets/focus_scope_test.dart b/packages/flutter/test/widgets/focus_scope_test.dart index 13b25fe370b..ad5514c9091 100644 --- a/packages/flutter/test/widgets/focus_scope_test.dart +++ b/packages/flutter/test/widgets/focus_scope_test.dart @@ -1999,6 +1999,47 @@ void main() { ), ); }); + + testWidgets('Focus widget gains input focus when it gains accessibility focus', (WidgetTester tester) async { + final SemanticsTester semantics = SemanticsTester(tester); + final SemanticsOwner semanticsOwner = tester.binding.pipelineOwner.semanticsOwner!; + final FocusNode focusNode = FocusNode(); + addTearDown(focusNode.dispose); + await tester.pumpWidget( + Directionality( + textDirection: TextDirection.rtl, + child: Focus( + focusNode: focusNode, + child: const Text('Test'), + ), + ), + ); + + expect( + semantics, + hasSemantics( + TestSemantics.root( + children: [ + TestSemantics( + id: 1, + flags: [SemanticsFlag.isFocusable], + actions: [SemanticsAction.focus], + label: 'Test', + textDirection: TextDirection.rtl, + ), + ], + ), + ignoreRect: true, + ignoreTransform: true, + ), + ); + + expect(focusNode.hasFocus, isFalse); + semanticsOwner.performAction(1, SemanticsAction.focus); + await tester.pumpAndSettle(); + expect(focusNode.hasFocus, isTrue); + semantics.dispose(); + }); }); group('ExcludeFocus', () { diff --git a/packages/flutter/test/widgets/focus_traversal_test.dart b/packages/flutter/test/widgets/focus_traversal_test.dart index 9d9f2157305..27ef9d5b3c1 100644 --- a/packages/flutter/test/widgets/focus_traversal_test.dart +++ b/packages/flutter/test/widgets/focus_traversal_test.dart @@ -3182,6 +3182,9 @@ void main() { flags: [ SemanticsFlag.isFocusable, ], + actions: [ + SemanticsAction.focus, + ], ), ], ); diff --git a/packages/flutter/test/widgets/gesture_detector_semantics_test.dart b/packages/flutter/test/widgets/gesture_detector_semantics_test.dart index 4632cf53bc5..d2de0566303 100644 --- a/packages/flutter/test/widgets/gesture_detector_semantics_test.dart +++ b/packages/flutter/test/widgets/gesture_detector_semantics_test.dart @@ -333,7 +333,7 @@ void main() { ); expect(semantics, isNot(includesNodeWith( - actions: [SemanticsAction.tap], + actions: [SemanticsAction.tap, SemanticsAction.focus], ))); semantics.dispose(); diff --git a/packages/flutter/test/widgets/selectable_region_test.dart b/packages/flutter/test/widgets/selectable_region_test.dart index 6877d6f9b7a..c1710f8dd36 100644 --- a/packages/flutter/test/widgets/selectable_region_test.dart +++ b/packages/flutter/test/widgets/selectable_region_test.dart @@ -260,7 +260,7 @@ void main() { SemanticsFlag.isEnabled, SemanticsFlag.isFocusable ], - actions: [SemanticsAction.tap], + actions: [SemanticsAction.tap, SemanticsAction.focus], label: 'Button', textDirection: TextDirection.ltr, ), diff --git a/packages/flutter/test/widgets/semantics_tester.dart b/packages/flutter/test/widgets/semantics_tester.dart index 014137f6584..e71bb142d66 100644 --- a/packages/flutter/test/widgets/semantics_tester.dart +++ b/packages/flutter/test/widgets/semantics_tester.dart @@ -269,7 +269,10 @@ class TestSemantics { final int actionsBitmask = actions is int ? actions as int : (actions as List).fold(0, (int bitmask, SemanticsAction action) => bitmask | action.index); - if (actionsBitmask != nodeData.actions) { + // TODO(gspencergoog): Remove focus filter once customer tests have been + // updated with the proper actions information for focus. + // https://github.com/flutter/flutter/issues/149842 + if ((actionsBitmask & ~SemanticsAction.focus.index) != (nodeData.actions & ~SemanticsAction.focus.index)) { return fail('expected node id $id to have actions $actions but found actions ${nodeData.actions}.'); } @@ -523,9 +526,16 @@ class SemanticsTester { if (textDirection != null && node.textDirection != textDirection) { return false; } + if (actions != null) { - final int expectedActions = actions.fold(0, (int value, SemanticsAction action) => value | action.index); - final int actualActions = node.getSemanticsData().actions; + // TODO(gspencergoog): Remove focus filter once customer tests have been + // updated with the proper actions information for focus. + // https://github.com/flutter/flutter/issues/149842 + final List nonFocusActions = actions.where( + (SemanticsAction action) => action != SemanticsAction.focus + ).toList(); + final int expectedActions = nonFocusActions.fold(0, (int value, SemanticsAction action) => value | action.index); + final int actualActions = node.getSemanticsData().actions & ~SemanticsAction.focus.index; if (expectedActions != actualActions) { return false; } @@ -647,11 +657,14 @@ class SemanticsTester { static String _actionsToSemanticsActionExpression(dynamic actions) { Iterable list; + // TODO(gspencergoog): Remove focus filter once customer tests have been + // updated with the proper actions information for focus. + // https://github.com/flutter/flutter/issues/149842 if (actions is int) { list = SemanticsAction.values - .where((SemanticsAction action) => (action.index & actions) != 0); + .where((SemanticsAction action) => action != SemanticsAction.focus && (action.index & actions) != 0); } else { - list = actions as List; + list = (actions as List).where((SemanticsAction action) => action != SemanticsAction.focus); } return '[${list.join(', ')}]'; } @@ -874,7 +887,10 @@ class _IncludesNodeWith extends Matcher { if (value != null) 'value "$value"', if (hint != null) 'hint "$hint"', if (textDirection != null) ' (${textDirection!.name})', - if (actions != null) 'actions "${actions!.join(', ')}"', + // TODO(gspencergoog): Remove focus filter once customer tests have been + // updated with the proper actions information for focus. + // https://github.com/flutter/flutter/issues/149842 + if (actions != null) 'actions "${actions!.where((SemanticsAction action) => action != SemanticsAction.focus).join(', ')}"', if (flags != null) 'flags "${flags!.join(', ')}"', if (tags != null) 'tags "${tags!.join(', ')}"', if (scrollPosition != null) 'scrollPosition "$scrollPosition"', diff --git a/packages/flutter_test/lib/src/matchers.dart b/packages/flutter_test/lib/src/matchers.dart index 6e955a4fdb2..dfe8f2ea0d1 100644 --- a/packages/flutter_test/lib/src/matchers.dart +++ b/packages/flutter_test/lib/src/matchers.dart @@ -674,6 +674,7 @@ Matcher matchesSemantics({ bool isExpanded = false, // Actions // bool hasTapAction = false, + bool hasFocusAction = false, bool hasLongPressAction = false, bool hasScrollLeftAction = false, bool hasScrollRightAction = false, @@ -753,6 +754,7 @@ Matcher matchesSemantics({ isExpanded: isExpanded, // Actions hasTapAction: hasTapAction, + hasFocusAction: hasFocusAction, hasLongPressAction: hasLongPressAction, hasScrollLeftAction: hasScrollLeftAction, hasScrollRightAction: hasScrollRightAction, @@ -860,6 +862,7 @@ Matcher containsSemantics({ bool? isExpanded, // Actions bool? hasTapAction, + bool? hasFocusAction, bool? hasLongPressAction, bool? hasScrollLeftAction, bool? hasScrollRightAction, @@ -939,6 +942,7 @@ Matcher containsSemantics({ isExpanded: isExpanded, // Actions hasTapAction: hasTapAction, + hasFocusAction: hasFocusAction, hasLongPressAction: hasLongPressAction, hasScrollLeftAction: hasScrollLeftAction, hasScrollRightAction: hasScrollRightAction, @@ -2259,6 +2263,11 @@ class _MatchesSemanticsData extends Matcher { required bool? isExpanded, // Actions required bool? hasTapAction, + // TODO(gspencergoog): Once this has landed, and customer tests have been + // updated, remove the ignore below. + // https://github.com/flutter/flutter/issues/149842 + // ignore: avoid_unused_constructor_parameters + required bool? hasFocusAction, required bool? hasLongPressAction, required bool? hasScrollLeftAction, required bool? hasScrollRightAction, @@ -2317,6 +2326,9 @@ class _MatchesSemanticsData extends Matcher { }, actions = { if (hasTapAction != null) SemanticsAction.tap: hasTapAction, + // TODO(gspencergoog): Once this has landed, and customer tests have + // been updated, add a line here that adds handling for + // hasFocusAction. https://github.com/flutter/flutter/issues/149842 if (hasLongPressAction != null) SemanticsAction.longPress: hasLongPressAction, if (hasScrollLeftAction != null) SemanticsAction.scrollLeft: hasScrollLeftAction, if (hasScrollRightAction != null) SemanticsAction.scrollRight: hasScrollRightAction, @@ -2379,8 +2391,8 @@ class _MatchesSemanticsData extends Matcher { final Map flags; @override - Description describe(Description description) { - description.add('has semantics'); + Description describe(Description description, [String? index]) { + description.add('${index == null ? '' : 'Child $index '}has semantics'); if (label != null) { description.add(' with label: $label'); } @@ -2414,12 +2426,19 @@ class _MatchesSemanticsData extends Matcher { if (tooltip != null) { description.add(' with tooltip: $tooltip'); } - if (actions.isNotEmpty) { - final List expectedActions = actions.entries + // TODO(gspencergoog): Remove filter once customer tests have been updated + // with the proper actions information for focus. + // https://github.com/flutter/flutter/issues/149842 + final Map nonFocusActions = + Map.fromEntries(actions.entries.where( + (MapEntry e) => e.key != SemanticsAction.focus + )); + if (nonFocusActions.isNotEmpty) { + final List expectedActions = nonFocusActions.entries .where((MapEntry e) => e.value) .map((MapEntry e) => e.key) .toList(); - final List notExpectedActions = actions.entries + final List notExpectedActions = nonFocusActions.entries .where((MapEntry e) => !e.value) .map((MapEntry e) => e.key) .toList(); @@ -2479,9 +2498,15 @@ class _MatchesSemanticsData extends Matcher { description.add(' with custom hints: $hintOverrides'); } if (children != null) { - description.add(' with children:\n'); - for (final _MatchesSemanticsData child in children!.cast<_MatchesSemanticsData>()) { - child.describe(description); + description.add(' with children:\n '); + final List<_MatchesSemanticsData> childMatches = children!.cast<_MatchesSemanticsData>(); + int childIndex = 1; + for (final _MatchesSemanticsData child in childMatches) { + child.describe(description, index != null ? '$index:$childIndex': '$childIndex'); + if (child != childMatches.last) { + description.add('\n '); + } + childIndex += 1; } } return description; @@ -2592,10 +2617,17 @@ class _MatchesSemanticsData extends Matcher { if (maxValueLength != null && maxValueLength != data.maxValueLength) { return failWithDescription(matchState, 'maxValueLength was: ${data.maxValueLength}'); } - if (actions.isNotEmpty) { + // TODO(gspencergoog): Remove filter once customer tests have been updated + // with the proper actions information for focus. + // https://github.com/flutter/flutter/issues/149842 + final Map nonFocusActions = + Map.fromEntries(actions.entries.where( + (MapEntry e) => e.key != SemanticsAction.focus + )); + if (nonFocusActions.isNotEmpty) { final List unexpectedActions = []; final List missingActions = []; - for (final MapEntry actionEntry in actions.entries) { + for (final MapEntry actionEntry in nonFocusActions.entries) { final ui.SemanticsAction action = actionEntry.key; final bool actionExpected = actionEntry.value; final bool actionPresent = (action.index & data.actions) == action.index; diff --git a/packages/flutter_test/test/matchers_test.dart b/packages/flutter_test/test/matchers_test.dart index 1825755da86..d1fb1472433 100644 --- a/packages/flutter_test/test/matchers_test.dart +++ b/packages/flutter_test/test/matchers_test.dart @@ -747,6 +747,7 @@ void main() { hasDidGainAccessibilityFocusAction: true, hasDidLoseAccessibilityFocusAction: true, hasDismissAction: true, + hasFocusAction: true, customActions: [action], )); }); @@ -1035,6 +1036,7 @@ void main() { hasDidGainAccessibilityFocusAction: true, hasDidLoseAccessibilityFocusAction: true, hasDismissAction: true, + hasFocusAction: true, customActions: [action], ), ); @@ -1128,6 +1130,7 @@ void main() { hasDidGainAccessibilityFocusAction: false, hasDidLoseAccessibilityFocusAction: false, hasDismissAction: false, + hasFocusAction: false, ), ); });