diff --git a/packages/flutter/lib/src/rendering/object.dart b/packages/flutter/lib/src/rendering/object.dart index 1e035ec860c..b5c39afa12f 100644 --- a/packages/flutter/lib/src/rendering/object.dart +++ b/packages/flutter/lib/src/rendering/object.dart @@ -4789,7 +4789,9 @@ mixin SemanticsAnnotationsMixin on RenderObject { config.isSemanticBoundary = container; config.explicitChildNodes = explicitChildNodes; config.isBlockingUserActions = blockUserActions; - config.localeForSubtree = localeForSubtree; + if (localeForSubtree != null) { + config.localeForSubtree = localeForSubtree; + } assert( ((_properties.scopesRoute ?? false) && explicitChildNodes) || !(_properties.scopesRoute ?? false), diff --git a/packages/flutter/lib/src/semantics/semantics.dart b/packages/flutter/lib/src/semantics/semantics.dart index fb1182266d5..8bf5f290c9a 100644 --- a/packages/flutter/lib/src/semantics/semantics.dart +++ b/packages/flutter/lib/src/semantics/semantics.dart @@ -5006,12 +5006,9 @@ class SemanticsConfiguration { Locale? get localeForSubtree => _localeForSubtree; Locale? _localeForSubtree; set localeForSubtree(Locale? value) { - assert( - value == null || _isSemanticBoundary, - 'to set locale for subtree, this configuration must also be a semantics ' - 'boundary.', - ); + assert(value != null); _localeForSubtree = value; + _hasBeenAnnotated = true; } /// The locale of the resulting semantics node if this configuration formed @@ -6520,6 +6517,9 @@ class SemanticsConfiguration { if (_attributedValue.string.isNotEmpty && other._attributedValue.string.isNotEmpty) { return false; } + if (_localeForSubtree != other._localeForSubtree) { + return false; + } if (_hasExplicitRole && other._hasExplicitRole) { return false; } diff --git a/packages/flutter/lib/src/widgets/basic.dart b/packages/flutter/lib/src/widgets/basic.dart index 5fbd71bc9b7..779882d7495 100644 --- a/packages/flutter/lib/src/widgets/basic.dart +++ b/packages/flutter/lib/src/widgets/basic.dart @@ -4150,11 +4150,7 @@ sealed class _SemanticsBase extends SingleChildRenderObjectWidget { required this.blockUserActions, required this.localeForSubtree, required this.properties, - }) : assert( - localeForSubtree == null || container, - 'To assign locale for subtree, this widget needs to be a ' - 'container', - ); + }); /// Contains properties used by assistive technologies to make the application /// more accessible. diff --git a/packages/flutter/test/material/app_bar_test.dart b/packages/flutter/test/material/app_bar_test.dart index 0084d94c5ea..8bf52bb914b 100644 --- a/packages/flutter/test/material/app_bar_test.dart +++ b/packages/flutter/test/material/app_bar_test.dart @@ -1465,6 +1465,7 @@ void main() { label: 'Flexible Space', textDirection: TextDirection.ltr, ), + TestSemantics( id: 7, flags: [ diff --git a/packages/flutter/test/material/dropdown_test.dart b/packages/flutter/test/material/dropdown_test.dart index 6de331bee87..4b884d503b8 100644 --- a/packages/flutter/test/material/dropdown_test.dart +++ b/packages/flutter/test/material/dropdown_test.dart @@ -1453,75 +1453,84 @@ void main() { TestSemantics.root( children: [ TestSemantics.rootChild( - actions: [SemanticsAction.tap, SemanticsAction.dismiss], - label: 'Dismiss', - textDirection: TextDirection.ltr, children: [ TestSemantics( - role: SemanticsRole.menu, - flags: [SemanticsFlag.scopesRoute, SemanticsFlag.namesRoute], - label: 'Popup menu', children: [ TestSemantics( + role: SemanticsRole.menu, + flags: [SemanticsFlag.scopesRoute, SemanticsFlag.namesRoute], + label: 'Popup menu', children: [ TestSemantics( - flags: [SemanticsFlag.hasImplicitScrolling], children: [ TestSemantics( - role: SemanticsRole.menuItem, - label: 'one', - textDirection: TextDirection.ltr, - flags: [ - SemanticsFlag.isButton, - SemanticsFlag.isFocused, - SemanticsFlag.isFocusable, - ], - tags: [const SemanticsTag('RenderViewport.twoPane')], - actions: [ - SemanticsAction.tap, - SemanticsAction.focus, - ], - ), - TestSemantics( - role: SemanticsRole.menuItem, - label: 'two', - textDirection: TextDirection.ltr, - flags: [ - SemanticsFlag.isButton, - SemanticsFlag.isFocusable, - ], - tags: [const SemanticsTag('RenderViewport.twoPane')], - actions: [ - SemanticsAction.tap, - SemanticsAction.focus, - ], - ), - TestSemantics( - role: SemanticsRole.menuItem, - label: 'three', - textDirection: TextDirection.ltr, - flags: [ - SemanticsFlag.isButton, - SemanticsFlag.isFocusable, - ], - tags: [const SemanticsTag('RenderViewport.twoPane')], - actions: [ - SemanticsAction.tap, - SemanticsAction.focus, - ], - ), - TestSemantics( - role: SemanticsRole.menuItem, - label: 'four', - textDirection: TextDirection.ltr, - flags: [ - SemanticsFlag.isButton, - SemanticsFlag.isFocusable, - ], - tags: [const SemanticsTag('RenderViewport.twoPane')], - actions: [ - SemanticsAction.tap, - SemanticsAction.focus, + flags: [SemanticsFlag.hasImplicitScrolling], + children: [ + TestSemantics( + role: SemanticsRole.menuItem, + label: 'one', + textDirection: TextDirection.ltr, + flags: [ + SemanticsFlag.isButton, + SemanticsFlag.isFocused, + SemanticsFlag.isFocusable, + ], + tags: [ + const SemanticsTag('RenderViewport.twoPane'), + ], + actions: [ + SemanticsAction.tap, + SemanticsAction.focus, + ], + ), + TestSemantics( + role: SemanticsRole.menuItem, + label: 'two', + textDirection: TextDirection.ltr, + flags: [ + SemanticsFlag.isButton, + SemanticsFlag.isFocusable, + ], + tags: [ + const SemanticsTag('RenderViewport.twoPane'), + ], + actions: [ + SemanticsAction.tap, + SemanticsAction.focus, + ], + ), + TestSemantics( + role: SemanticsRole.menuItem, + label: 'three', + textDirection: TextDirection.ltr, + flags: [ + SemanticsFlag.isButton, + SemanticsFlag.isFocusable, + ], + tags: [ + const SemanticsTag('RenderViewport.twoPane'), + ], + actions: [ + SemanticsAction.tap, + SemanticsAction.focus, + ], + ), + TestSemantics( + role: SemanticsRole.menuItem, + label: 'four', + textDirection: TextDirection.ltr, + flags: [ + SemanticsFlag.isButton, + SemanticsFlag.isFocusable, + ], + tags: [ + const SemanticsTag('RenderViewport.twoPane'), + ], + actions: [ + SemanticsAction.tap, + SemanticsAction.focus, + ], + ), ], ), ], @@ -1530,6 +1539,11 @@ void main() { ), ], ), + TestSemantics( + actions: [SemanticsAction.tap, SemanticsAction.dismiss], + label: 'Dismiss', + textDirection: TextDirection.ltr, + ), ], ), ], diff --git a/packages/flutter/test/material/navigation_rail_test.dart b/packages/flutter/test/material/navigation_rail_test.dart index bae6f802bcc..9c5a15d2638 100644 --- a/packages/flutter/test/material/navigation_rail_test.dart +++ b/packages/flutter/test/material/navigation_rail_test.dart @@ -6196,10 +6196,14 @@ TestSemantics _expectedSemantics({bool scrollable = false}) { TestSemantics( children: [ TestSemantics( - flags: [SemanticsFlag.scopesRoute], children: [ - TestSemantics(children: destinations), - TestSemantics(label: 'body', textDirection: TextDirection.ltr), + TestSemantics( + flags: [SemanticsFlag.scopesRoute], + children: [ + TestSemantics(children: destinations), + TestSemantics(label: 'body', textDirection: TextDirection.ltr), + ], + ), ], ), ], diff --git a/packages/flutter/test/material/tabs_test.dart b/packages/flutter/test/material/tabs_test.dart index 68151d7d174..43dfdbc5bc0 100644 --- a/packages/flutter/test/material/tabs_test.dart +++ b/packages/flutter/test/material/tabs_test.dart @@ -6078,12 +6078,9 @@ void main() { final expectedSemantics = TestSemantics.root( children: [ TestSemantics.rootChild( - label: 'Tab 1 of 2', - id: 1, rect: TestSemantics.fullScreen, children: [ TestSemantics( - id: 2, role: SemanticsRole.tabBar, children: [ TestSemantics( @@ -6093,7 +6090,6 @@ void main() { SemanticsFlag.isSelected, SemanticsFlag.hasSelectedState, ], - id: 3, rect: TestSemantics.fullScreen, actions: 1 | SemanticsAction.focus.index, role: SemanticsRole.tab, @@ -6101,7 +6097,6 @@ void main() { TestSemantics( label: 'TAB2${kIsWeb ? '' : '\nTab 2 of 2'}', flags: [SemanticsFlag.isFocusable, SemanticsFlag.hasSelectedState], - id: 4, rect: TestSemantics.fullScreen, actions: [SemanticsAction.tap, SemanticsAction.focus], role: SemanticsRole.tab, @@ -6109,16 +6104,13 @@ void main() { ], ), TestSemantics( - id: 5, rect: TestSemantics.fullScreen, children: [ TestSemantics( - id: 7, rect: TestSemantics.fullScreen, actions: [SemanticsAction.scrollLeft], children: [ TestSemantics( - id: 6, rect: TestSemantics.fullScreen, label: 'PAGE1', role: SemanticsRole.tabPanel, @@ -6127,12 +6119,16 @@ void main() { ), ], ), + TestSemantics(label: 'Tab 1 of 2', textDirection: TextDirection.ltr), ], ), ], ); - expect(semantics, hasSemantics(expectedSemantics, ignoreRect: true, ignoreTransform: true)); + expect( + semantics, + hasSemantics(expectedSemantics, ignoreRect: true, ignoreTransform: true, ignoreId: true), + ); semantics.dispose(); }); diff --git a/packages/flutter/test/material/text_field_test.dart b/packages/flutter/test/material/text_field_test.dart index 069223cf30c..ca28dedf063 100644 --- a/packages/flutter/test/material/text_field_test.dart +++ b/packages/flutter/test/material/text_field_test.dart @@ -2003,32 +2003,36 @@ void main() { TestSemantics.root( children: [ TestSemantics( - id: 1, - flags: [ - SemanticsFlag.isTextField, - SemanticsFlag.isFocusable, - SemanticsFlag.hasEnabledState, - SemanticsFlag.isEnabled, - SemanticsFlag.isFocused, + children: [ + TestSemantics( + flags: [ + SemanticsFlag.isTextField, + SemanticsFlag.isFocusable, + SemanticsFlag.hasEnabledState, + SemanticsFlag.isEnabled, + SemanticsFlag.isFocused, + ], + actions: [ + SemanticsAction.tap, + SemanticsAction.focus, + SemanticsAction.moveCursorBackwardByCharacter, + SemanticsAction.setSelection, + SemanticsAction.paste, + SemanticsAction.setText, + SemanticsAction.moveCursorBackwardByWord, + ], + value: 'abcdefghi', + inputType: ui.SemanticsInputType.text, + currentValueLength: 9, + textDirection: TextDirection.ltr, + textSelection: const TextSelection.collapsed(offset: 9), + ), ], - actions: [ - SemanticsAction.tap, - SemanticsAction.focus, - SemanticsAction.moveCursorBackwardByCharacter, - SemanticsAction.setSelection, - SemanticsAction.paste, - SemanticsAction.setText, - SemanticsAction.moveCursorBackwardByWord, - ], - value: 'abcdefghi', - inputType: ui.SemanticsInputType.text, - currentValueLength: 9, - textDirection: TextDirection.ltr, - textSelection: const TextSelection.collapsed(offset: 9), ), ], ), ignoreRect: true, + ignoreId: true, ignoreTransform: true, ), ); @@ -5654,24 +5658,28 @@ void main() { hasSemantics( TestSemantics.root( children: [ - TestSemantics.rootChild(id: 2, textDirection: TextDirection.ltr, label: 'Prefix'), - TestSemantics.rootChild( - id: 1, - textDirection: TextDirection.ltr, - value: 'some text', - actions: [SemanticsAction.tap, SemanticsAction.focus], - inputType: ui.SemanticsInputType.text, - currentValueLength: 9, - flags: [ - SemanticsFlag.isTextField, - SemanticsFlag.isFocusable, - SemanticsFlag.hasEnabledState, - SemanticsFlag.isEnabled, + TestSemantics( + children: [ + TestSemantics(id: 2, textDirection: TextDirection.ltr, label: 'Prefix'), + TestSemantics( + textDirection: TextDirection.ltr, + value: 'some text', + actions: [SemanticsAction.tap, SemanticsAction.focus], + inputType: ui.SemanticsInputType.text, + currentValueLength: 9, + flags: [ + SemanticsFlag.isTextField, + SemanticsFlag.isFocusable, + SemanticsFlag.hasEnabledState, + SemanticsFlag.isEnabled, + ], + ), + TestSemantics(id: 3, textDirection: TextDirection.ltr, label: 'Suffix'), ], ), - TestSemantics.rootChild(id: 3, textDirection: TextDirection.ltr, label: 'Suffix'), ], ), + ignoreId: true, ignoreTransform: true, ignoreRect: true, ), @@ -5697,24 +5705,28 @@ void main() { hasSemantics( TestSemantics.root( children: [ - TestSemantics.rootChild( - id: 1, - textDirection: TextDirection.ltr, - value: 'some text', - actions: [SemanticsAction.tap, SemanticsAction.focus], - inputType: ui.SemanticsInputType.text, - currentValueLength: 9, - flags: [ - SemanticsFlag.isTextField, - SemanticsFlag.isFocusable, - SemanticsFlag.hasEnabledState, - SemanticsFlag.isEnabled, + TestSemantics( + children: [ + TestSemantics( + textDirection: TextDirection.ltr, + value: 'some text', + actions: [SemanticsAction.tap, SemanticsAction.focus], + inputType: ui.SemanticsInputType.text, + currentValueLength: 9, + flags: [ + SemanticsFlag.isTextField, + SemanticsFlag.isFocusable, + SemanticsFlag.hasEnabledState, + SemanticsFlag.isEnabled, + ], + ), + TestSemantics(textDirection: TextDirection.ltr, label: 'Prefix'), + TestSemantics(textDirection: TextDirection.ltr, label: 'Suffix'), ], ), - TestSemantics.rootChild(id: 2, textDirection: TextDirection.ltr, label: 'Prefix'), - TestSemantics.rootChild(id: 3, textDirection: TextDirection.ltr, label: 'Suffix'), ], ), + ignoreId: true, ignoreTransform: true, ignoreRect: true, ), @@ -8439,20 +8451,24 @@ void main() { TestSemantics.root( children: [ TestSemantics.rootChild( - id: 1, - textDirection: TextDirection.ltr, - inputType: ui.SemanticsInputType.text, - currentValueLength: 0, - actions: [SemanticsAction.tap, SemanticsAction.focus], - flags: [ - SemanticsFlag.isTextField, - SemanticsFlag.isFocusable, - SemanticsFlag.hasEnabledState, - SemanticsFlag.isEnabled, + children: [ + TestSemantics( + textDirection: TextDirection.ltr, + inputType: ui.SemanticsInputType.text, + currentValueLength: 0, + actions: [SemanticsAction.tap, SemanticsAction.focus], + flags: [ + SemanticsFlag.isTextField, + SemanticsFlag.isFocusable, + SemanticsFlag.hasEnabledState, + SemanticsFlag.isEnabled, + ], + ), ], ), ], ), + ignoreId: true, ignoreTransform: true, ignoreRect: true, ), @@ -8467,21 +8483,25 @@ void main() { TestSemantics.root( children: [ TestSemantics.rootChild( - id: 1, - textDirection: TextDirection.ltr, - value: 'Guten Tag', - inputType: ui.SemanticsInputType.text, - currentValueLength: 9, - actions: [SemanticsAction.tap, SemanticsAction.focus], - flags: [ - SemanticsFlag.isTextField, - SemanticsFlag.isFocusable, - SemanticsFlag.hasEnabledState, - SemanticsFlag.isEnabled, + children: [ + TestSemantics( + textDirection: TextDirection.ltr, + value: 'Guten Tag', + inputType: ui.SemanticsInputType.text, + currentValueLength: 9, + actions: [SemanticsAction.tap, SemanticsAction.focus], + flags: [ + SemanticsFlag.isTextField, + SemanticsFlag.isFocusable, + SemanticsFlag.hasEnabledState, + SemanticsFlag.isEnabled, + ], + ), ], ), ], ), + ignoreId: true, ignoreTransform: true, ignoreRect: true, ), @@ -8496,31 +8516,35 @@ void main() { TestSemantics.root( children: [ TestSemantics.rootChild( - id: 1, - textDirection: TextDirection.ltr, - value: 'Guten Tag', - inputType: ui.SemanticsInputType.text, - currentValueLength: 9, - textSelection: const TextSelection.collapsed(offset: 9), - actions: [ - SemanticsAction.tap, - SemanticsAction.focus, - SemanticsAction.moveCursorBackwardByCharacter, - SemanticsAction.moveCursorBackwardByWord, - SemanticsAction.setSelection, - SemanticsAction.setText, - SemanticsAction.paste, - ], - flags: [ - SemanticsFlag.isTextField, - SemanticsFlag.isFocusable, - SemanticsFlag.hasEnabledState, - SemanticsFlag.isEnabled, - SemanticsFlag.isFocused, + children: [ + TestSemantics( + textDirection: TextDirection.ltr, + value: 'Guten Tag', + inputType: ui.SemanticsInputType.text, + currentValueLength: 9, + textSelection: const TextSelection.collapsed(offset: 9), + actions: [ + SemanticsAction.tap, + SemanticsAction.focus, + SemanticsAction.moveCursorBackwardByCharacter, + SemanticsAction.moveCursorBackwardByWord, + SemanticsAction.setSelection, + SemanticsAction.setText, + SemanticsAction.paste, + ], + flags: [ + SemanticsFlag.isTextField, + SemanticsFlag.isFocusable, + SemanticsFlag.hasEnabledState, + SemanticsFlag.isEnabled, + SemanticsFlag.isFocused, + ], + ), ], ), ], ), + ignoreId: true, ignoreTransform: true, ignoreRect: true, ), @@ -8535,33 +8559,37 @@ void main() { TestSemantics.root( children: [ TestSemantics.rootChild( - id: 1, - textDirection: TextDirection.ltr, - textSelection: const TextSelection.collapsed(offset: 4), - value: 'Guten Tag', - inputType: ui.SemanticsInputType.text, - currentValueLength: 9, - actions: [ - SemanticsAction.tap, - SemanticsAction.focus, - SemanticsAction.moveCursorBackwardByCharacter, - SemanticsAction.moveCursorForwardByCharacter, - SemanticsAction.moveCursorBackwardByWord, - SemanticsAction.moveCursorForwardByWord, - SemanticsAction.setSelection, - SemanticsAction.setText, - SemanticsAction.paste, - ], - flags: [ - SemanticsFlag.isTextField, - SemanticsFlag.isFocusable, - SemanticsFlag.hasEnabledState, - SemanticsFlag.isEnabled, - SemanticsFlag.isFocused, + children: [ + TestSemantics( + textDirection: TextDirection.ltr, + textSelection: const TextSelection.collapsed(offset: 4), + value: 'Guten Tag', + inputType: ui.SemanticsInputType.text, + currentValueLength: 9, + actions: [ + SemanticsAction.tap, + SemanticsAction.focus, + SemanticsAction.moveCursorBackwardByCharacter, + SemanticsAction.moveCursorForwardByCharacter, + SemanticsAction.moveCursorBackwardByWord, + SemanticsAction.moveCursorForwardByWord, + SemanticsAction.setSelection, + SemanticsAction.setText, + SemanticsAction.paste, + ], + flags: [ + SemanticsFlag.isTextField, + SemanticsFlag.isFocusable, + SemanticsFlag.hasEnabledState, + SemanticsFlag.isEnabled, + SemanticsFlag.isFocused, + ], + ), ], ), ], ), + ignoreId: true, ignoreTransform: true, ignoreRect: true, ), @@ -8577,31 +8605,35 @@ void main() { TestSemantics.root( children: [ TestSemantics.rootChild( - id: 1, - textDirection: TextDirection.ltr, - textSelection: const TextSelection.collapsed(offset: 0), - value: 'Schönen Feierabend', - inputType: ui.SemanticsInputType.text, - currentValueLength: 18, - actions: [ - SemanticsAction.tap, - SemanticsAction.focus, - SemanticsAction.moveCursorForwardByCharacter, - SemanticsAction.moveCursorForwardByWord, - SemanticsAction.setSelection, - SemanticsAction.setText, - SemanticsAction.paste, - ], - flags: [ - SemanticsFlag.isTextField, - SemanticsFlag.isFocusable, - SemanticsFlag.hasEnabledState, - SemanticsFlag.isEnabled, - SemanticsFlag.isFocused, + children: [ + TestSemantics( + textDirection: TextDirection.ltr, + textSelection: const TextSelection.collapsed(offset: 0), + value: 'Schönen Feierabend', + inputType: ui.SemanticsInputType.text, + currentValueLength: 18, + actions: [ + SemanticsAction.tap, + SemanticsAction.focus, + SemanticsAction.moveCursorForwardByCharacter, + SemanticsAction.moveCursorForwardByWord, + SemanticsAction.setSelection, + SemanticsAction.setText, + SemanticsAction.paste, + ], + flags: [ + SemanticsFlag.isTextField, + SemanticsFlag.isFocusable, + SemanticsFlag.hasEnabledState, + SemanticsFlag.isEnabled, + SemanticsFlag.isFocused, + ], + ), ], ), ], ), + ignoreId: true, ignoreTransform: true, ignoreRect: true, ), @@ -8698,30 +8730,34 @@ void main() { TestSemantics.root( children: [ TestSemantics.rootChild( - id: 1, - textDirection: TextDirection.ltr, - inputType: ui.SemanticsInputType.text, - currentValueLength: 0, - actions: [ - SemanticsAction.tap, - SemanticsAction.focus, - SemanticsAction.setText, - // Absent the following because enableInteractiveSelection: false - // SemanticsAction.moveCursorBackwardByCharacter, - // SemanticsAction.moveCursorBackwardByWord, - // SemanticsAction.setSelection, - // SemanticsAction.paste, - ], - flags: [ - SemanticsFlag.isTextField, - SemanticsFlag.isFocusable, - SemanticsFlag.hasEnabledState, - SemanticsFlag.isEnabled, - SemanticsFlag.isFocused, + children: [ + TestSemantics.rootChild( + textDirection: TextDirection.ltr, + inputType: ui.SemanticsInputType.text, + currentValueLength: 0, + actions: [ + SemanticsAction.tap, + SemanticsAction.focus, + SemanticsAction.setText, + // Absent the following because enableInteractiveSelection: false + // SemanticsAction.moveCursorBackwardByCharacter, + // SemanticsAction.moveCursorBackwardByWord, + // SemanticsAction.setSelection, + // SemanticsAction.paste, + ], + flags: [ + SemanticsFlag.isTextField, + SemanticsFlag.isFocusable, + SemanticsFlag.hasEnabledState, + SemanticsFlag.isEnabled, + SemanticsFlag.isFocused, + ], + ), ], ), ], ), + ignoreId: true, ignoreTransform: true, ignoreRect: true, ), @@ -8747,21 +8783,25 @@ void main() { TestSemantics.root( children: [ TestSemantics.rootChild( - id: 1, - value: 'Hello', - inputType: ui.SemanticsInputType.text, - currentValueLength: 5, - textDirection: TextDirection.ltr, - actions: [SemanticsAction.tap, SemanticsAction.focus], - flags: [ - SemanticsFlag.isTextField, - SemanticsFlag.isFocusable, - SemanticsFlag.hasEnabledState, - SemanticsFlag.isEnabled, + children: [ + TestSemantics( + value: 'Hello', + inputType: ui.SemanticsInputType.text, + currentValueLength: 5, + textDirection: TextDirection.ltr, + actions: [SemanticsAction.tap, SemanticsAction.focus], + flags: [ + SemanticsFlag.isTextField, + SemanticsFlag.isFocusable, + SemanticsFlag.hasEnabledState, + SemanticsFlag.isEnabled, + ], + ), ], ), ], ), + ignoreId: true, ignoreTransform: true, ignoreRect: true, ), @@ -8777,31 +8817,35 @@ void main() { TestSemantics.root( children: [ TestSemantics.rootChild( - id: 1, - value: 'Hello', - inputType: ui.SemanticsInputType.text, - currentValueLength: 5, - textSelection: const TextSelection.collapsed(offset: 5), - textDirection: TextDirection.ltr, - actions: [ - SemanticsAction.tap, - SemanticsAction.focus, - SemanticsAction.moveCursorBackwardByCharacter, - SemanticsAction.moveCursorBackwardByWord, - SemanticsAction.setSelection, - SemanticsAction.setText, - SemanticsAction.paste, - ], - flags: [ - SemanticsFlag.isTextField, - SemanticsFlag.isFocusable, - SemanticsFlag.hasEnabledState, - SemanticsFlag.isEnabled, - SemanticsFlag.isFocused, + children: [ + TestSemantics( + value: 'Hello', + inputType: ui.SemanticsInputType.text, + currentValueLength: 5, + textSelection: const TextSelection.collapsed(offset: 5), + textDirection: TextDirection.ltr, + actions: [ + SemanticsAction.tap, + SemanticsAction.focus, + SemanticsAction.moveCursorBackwardByCharacter, + SemanticsAction.moveCursorBackwardByWord, + SemanticsAction.setSelection, + SemanticsAction.setText, + SemanticsAction.paste, + ], + flags: [ + SemanticsFlag.isTextField, + SemanticsFlag.isFocusable, + SemanticsFlag.hasEnabledState, + SemanticsFlag.isEnabled, + SemanticsFlag.isFocused, + ], + ), ], ), ], ), + ignoreId: true, ignoreTransform: true, ignoreRect: true, ), @@ -8816,35 +8860,39 @@ void main() { TestSemantics.root( children: [ TestSemantics.rootChild( - id: 1, - value: 'Hello', - inputType: ui.SemanticsInputType.text, - currentValueLength: 5, - textSelection: const TextSelection(baseOffset: 5, extentOffset: 3), - textDirection: TextDirection.ltr, - actions: [ - SemanticsAction.tap, - SemanticsAction.focus, - SemanticsAction.moveCursorBackwardByCharacter, - SemanticsAction.moveCursorForwardByCharacter, - SemanticsAction.moveCursorBackwardByWord, - SemanticsAction.moveCursorForwardByWord, - SemanticsAction.setSelection, - SemanticsAction.setText, - SemanticsAction.paste, - SemanticsAction.cut, - SemanticsAction.copy, - ], - flags: [ - SemanticsFlag.isTextField, - SemanticsFlag.isFocusable, - SemanticsFlag.hasEnabledState, - SemanticsFlag.isEnabled, - SemanticsFlag.isFocused, + children: [ + TestSemantics( + value: 'Hello', + inputType: ui.SemanticsInputType.text, + currentValueLength: 5, + textSelection: const TextSelection(baseOffset: 5, extentOffset: 3), + textDirection: TextDirection.ltr, + actions: [ + SemanticsAction.tap, + SemanticsAction.focus, + SemanticsAction.moveCursorBackwardByCharacter, + SemanticsAction.moveCursorForwardByCharacter, + SemanticsAction.moveCursorBackwardByWord, + SemanticsAction.moveCursorForwardByWord, + SemanticsAction.setSelection, + SemanticsAction.setText, + SemanticsAction.paste, + SemanticsAction.cut, + SemanticsAction.copy, + ], + flags: [ + SemanticsFlag.isTextField, + SemanticsFlag.isFocusable, + SemanticsFlag.hasEnabledState, + SemanticsFlag.isEnabled, + SemanticsFlag.isFocused, + ], + ), ], ), ], ), + ignoreId: true, ignoreTransform: true, ignoreRect: true, ), @@ -8869,7 +8917,7 @@ void main() { await tester.tap(find.byKey(key)); await tester.pump(); - const inputFieldId = 1; + const inputFieldId = 2; expect( controller.selection, @@ -8881,27 +8929,32 @@ void main() { TestSemantics.root( children: [ TestSemantics.rootChild( - id: inputFieldId, - value: 'Hello', - inputType: ui.SemanticsInputType.text, - currentValueLength: 5, - textSelection: const TextSelection.collapsed(offset: 5), - textDirection: TextDirection.ltr, - actions: [ - SemanticsAction.tap, - SemanticsAction.focus, - SemanticsAction.moveCursorBackwardByCharacter, - SemanticsAction.moveCursorBackwardByWord, - SemanticsAction.setSelection, - SemanticsAction.setText, - SemanticsAction.paste, - ], - flags: [ - SemanticsFlag.isTextField, - SemanticsFlag.isFocusable, - SemanticsFlag.hasEnabledState, - SemanticsFlag.isEnabled, - SemanticsFlag.isFocused, + id: 1, + children: [ + TestSemantics( + id: inputFieldId, + value: 'Hello', + inputType: ui.SemanticsInputType.text, + currentValueLength: 5, + textSelection: const TextSelection.collapsed(offset: 5), + textDirection: TextDirection.ltr, + actions: [ + SemanticsAction.tap, + SemanticsAction.focus, + SemanticsAction.moveCursorBackwardByCharacter, + SemanticsAction.moveCursorBackwardByWord, + SemanticsAction.setSelection, + SemanticsAction.setText, + SemanticsAction.paste, + ], + flags: [ + SemanticsFlag.isTextField, + SemanticsFlag.isFocusable, + SemanticsFlag.hasEnabledState, + SemanticsFlag.isEnabled, + SemanticsFlag.isFocused, + ], + ), ], ), ], @@ -8940,29 +8993,34 @@ void main() { TestSemantics.root( children: [ TestSemantics.rootChild( - id: inputFieldId, - value: 'Hello', - inputType: ui.SemanticsInputType.text, - currentValueLength: 5, - textSelection: const TextSelection(baseOffset: 0, extentOffset: 5), - textDirection: TextDirection.ltr, - actions: [ - SemanticsAction.tap, - SemanticsAction.focus, - SemanticsAction.moveCursorBackwardByCharacter, - SemanticsAction.moveCursorBackwardByWord, - SemanticsAction.setSelection, - SemanticsAction.setText, - SemanticsAction.paste, - SemanticsAction.cut, - SemanticsAction.copy, - ], - flags: [ - SemanticsFlag.isTextField, - SemanticsFlag.isFocusable, - SemanticsFlag.hasEnabledState, - SemanticsFlag.isEnabled, - SemanticsFlag.isFocused, + id: 1, + children: [ + TestSemantics( + id: inputFieldId, + value: 'Hello', + inputType: ui.SemanticsInputType.text, + currentValueLength: 5, + textSelection: const TextSelection(baseOffset: 0, extentOffset: 5), + textDirection: TextDirection.ltr, + actions: [ + SemanticsAction.tap, + SemanticsAction.focus, + SemanticsAction.moveCursorBackwardByCharacter, + SemanticsAction.moveCursorBackwardByWord, + SemanticsAction.setSelection, + SemanticsAction.setText, + SemanticsAction.paste, + SemanticsAction.cut, + SemanticsAction.copy, + ], + flags: [ + SemanticsFlag.isTextField, + SemanticsFlag.isFocusable, + SemanticsFlag.hasEnabledState, + SemanticsFlag.isEnabled, + SemanticsFlag.isFocused, + ], + ), ], ), ], @@ -8993,26 +9051,31 @@ void main() { ), ); - const inputFieldId = 1; + const inputFieldId = 2; expect( semantics, hasSemantics( TestSemantics.root( children: [ - TestSemantics( - id: inputFieldId, - flags: [ - SemanticsFlag.isTextField, - SemanticsFlag.isFocusable, - SemanticsFlag.hasEnabledState, - SemanticsFlag.isEnabled, + TestSemantics.rootChild( + id: 1, + children: [ + TestSemantics( + id: inputFieldId, + flags: [ + SemanticsFlag.isTextField, + SemanticsFlag.isFocusable, + SemanticsFlag.hasEnabledState, + SemanticsFlag.isEnabled, + ], + actions: [SemanticsAction.tap, SemanticsAction.focus], + value: textInTextField, + inputType: ui.SemanticsInputType.text, + currentValueLength: 5, + textDirection: TextDirection.ltr, + ), ], - actions: [SemanticsAction.tap, SemanticsAction.focus], - value: textInTextField, - inputType: ui.SemanticsInputType.text, - currentValueLength: 5, - textDirection: TextDirection.ltr, ), ], ), @@ -9029,32 +9092,37 @@ void main() { hasSemantics( TestSemantics.root( children: [ - TestSemantics( - id: inputFieldId, - flags: [ - SemanticsFlag.isTextField, - SemanticsFlag.isFocusable, - SemanticsFlag.hasEnabledState, - SemanticsFlag.isEnabled, - SemanticsFlag.isFocused, + TestSemantics.rootChild( + id: 1, + children: [ + TestSemantics( + id: inputFieldId, + flags: [ + SemanticsFlag.isTextField, + SemanticsFlag.isFocusable, + SemanticsFlag.hasEnabledState, + SemanticsFlag.isEnabled, + SemanticsFlag.isFocused, + ], + actions: [ + SemanticsAction.tap, + SemanticsAction.focus, + SemanticsAction.moveCursorBackwardByCharacter, + SemanticsAction.moveCursorBackwardByWord, + SemanticsAction.setSelection, + SemanticsAction.setText, + SemanticsAction.paste, + ], + value: textInTextField, + inputType: ui.SemanticsInputType.text, + currentValueLength: 5, + textDirection: TextDirection.ltr, + textSelection: const TextSelection( + baseOffset: textInTextField.length, + extentOffset: textInTextField.length, + ), + ), ], - actions: [ - SemanticsAction.tap, - SemanticsAction.focus, - SemanticsAction.moveCursorBackwardByCharacter, - SemanticsAction.moveCursorBackwardByWord, - SemanticsAction.setSelection, - SemanticsAction.setText, - SemanticsAction.paste, - ], - value: textInTextField, - inputType: ui.SemanticsInputType.text, - currentValueLength: 5, - textDirection: TextDirection.ltr, - textSelection: const TextSelection( - baseOffset: textInTextField.length, - extentOffset: textInTextField.length, - ), ), ], ), @@ -9083,26 +9151,31 @@ void main() { ), ); - const inputFieldId = 1; + const inputFieldId = 2; expect( semantics, hasSemantics( TestSemantics.root( children: [ - TestSemantics( - id: inputFieldId, - flags: [ - SemanticsFlag.isTextField, - SemanticsFlag.isFocusable, - SemanticsFlag.hasEnabledState, - SemanticsFlag.isEnabled, + TestSemantics.rootChild( + id: 1, + children: [ + TestSemantics( + id: inputFieldId, + flags: [ + SemanticsFlag.isTextField, + SemanticsFlag.isFocusable, + SemanticsFlag.hasEnabledState, + SemanticsFlag.isEnabled, + ], + actions: [SemanticsAction.tap, SemanticsAction.focus], + value: textInTextField, + inputType: ui.SemanticsInputType.text, + currentValueLength: 5, + textDirection: TextDirection.ltr, + ), ], - actions: [SemanticsAction.tap, SemanticsAction.focus], - value: textInTextField, - inputType: ui.SemanticsInputType.text, - currentValueLength: 5, - textDirection: TextDirection.ltr, ), ], ), @@ -9119,32 +9192,37 @@ void main() { hasSemantics( TestSemantics.root( children: [ - TestSemantics( - id: inputFieldId, - flags: [ - SemanticsFlag.isTextField, - SemanticsFlag.isFocusable, - SemanticsFlag.hasEnabledState, - SemanticsFlag.isEnabled, - SemanticsFlag.isFocused, + TestSemantics.rootChild( + id: 1, + children: [ + TestSemantics( + id: inputFieldId, + flags: [ + SemanticsFlag.isTextField, + SemanticsFlag.isFocusable, + SemanticsFlag.hasEnabledState, + SemanticsFlag.isEnabled, + SemanticsFlag.isFocused, + ], + actions: [ + SemanticsAction.tap, + SemanticsAction.focus, + SemanticsAction.moveCursorBackwardByCharacter, + SemanticsAction.moveCursorBackwardByWord, + SemanticsAction.setSelection, + SemanticsAction.setText, + // No paste option. + ], + value: textInTextField, + inputType: ui.SemanticsInputType.text, + currentValueLength: 5, + textDirection: TextDirection.ltr, + textSelection: const TextSelection( + baseOffset: textInTextField.length, + extentOffset: textInTextField.length, + ), + ), ], - actions: [ - SemanticsAction.tap, - SemanticsAction.focus, - SemanticsAction.moveCursorBackwardByCharacter, - SemanticsAction.moveCursorBackwardByWord, - SemanticsAction.setSelection, - SemanticsAction.setText, - // No paste option. - ], - value: textInTextField, - inputType: ui.SemanticsInputType.text, - currentValueLength: 5, - textDirection: TextDirection.ltr, - textSelection: const TextSelection( - baseOffset: textInTextField.length, - extentOffset: textInTextField.length, - ), ), ], ), @@ -9280,30 +9358,33 @@ void main() { TestSemantics.root( children: [ TestSemantics.rootChild( - label: 'label', - id: 1, - textDirection: TextDirection.ltr, - inputType: ui.SemanticsInputType.text, - maxValueLength: 10, - currentValueLength: 0, - actions: [SemanticsAction.tap, SemanticsAction.focus], - flags: [ - SemanticsFlag.isTextField, - SemanticsFlag.isFocusable, - SemanticsFlag.hasEnabledState, - SemanticsFlag.isEnabled, - ], children: [ - TestSemantics(id: 2, label: 'helper', textDirection: TextDirection.ltr), TestSemantics( - id: 3, - label: '10 characters remaining', + label: 'label', textDirection: TextDirection.ltr, + inputType: ui.SemanticsInputType.text, + maxValueLength: 10, + currentValueLength: 0, + actions: [SemanticsAction.tap, SemanticsAction.focus], + flags: [ + SemanticsFlag.isTextField, + SemanticsFlag.isFocusable, + SemanticsFlag.hasEnabledState, + SemanticsFlag.isEnabled, + ], + children: [ + TestSemantics(label: 'helper', textDirection: TextDirection.ltr), + TestSemantics( + label: '10 characters remaining', + textDirection: TextDirection.ltr, + ), + ], ), ], ), ], ), + ignoreId: true, ignoreTransform: true, ignoreRect: true, ), @@ -9318,39 +9399,42 @@ void main() { TestSemantics.root( children: [ TestSemantics.rootChild( - label: 'label', - id: 1, - textDirection: TextDirection.ltr, - textSelection: const TextSelection(baseOffset: 0, extentOffset: 0), - inputType: ui.SemanticsInputType.text, - currentValueLength: 0, - maxValueLength: 10, - actions: [ - SemanticsAction.tap, - SemanticsAction.focus, - SemanticsAction.setSelection, - SemanticsAction.setText, - SemanticsAction.paste, - ], - flags: [ - SemanticsFlag.isTextField, - SemanticsFlag.isFocusable, - SemanticsFlag.hasEnabledState, - SemanticsFlag.isEnabled, - SemanticsFlag.isFocused, - ], children: [ - TestSemantics(id: 2, label: 'helper', textDirection: TextDirection.ltr), - TestSemantics( - id: 3, - label: '10 characters remaining', - flags: [SemanticsFlag.isLiveRegion], + TestSemantics.rootChild( + label: 'label', textDirection: TextDirection.ltr, + textSelection: const TextSelection(baseOffset: 0, extentOffset: 0), + inputType: ui.SemanticsInputType.text, + currentValueLength: 0, + maxValueLength: 10, + actions: [ + SemanticsAction.tap, + SemanticsAction.focus, + SemanticsAction.setSelection, + SemanticsAction.setText, + SemanticsAction.paste, + ], + flags: [ + SemanticsFlag.isTextField, + SemanticsFlag.isFocusable, + SemanticsFlag.hasEnabledState, + SemanticsFlag.isEnabled, + SemanticsFlag.isFocused, + ], + children: [ + TestSemantics(id: 2, label: 'helper', textDirection: TextDirection.ltr), + TestSemantics( + label: '10 characters remaining', + flags: [SemanticsFlag.isLiveRegion], + textDirection: TextDirection.ltr, + ), + ], ), ], ), ], ), + ignoreId: true, ignoreTransform: true, ignoreRect: true, ), @@ -9390,20 +9474,24 @@ void main() { TestSemantics.root( children: [ TestSemantics.rootChild( - label: 'label', - textDirection: TextDirection.ltr, - inputType: ui.SemanticsInputType.text, - currentValueLength: 0, - actions: [SemanticsAction.tap, SemanticsAction.focus], - flags: [ - SemanticsFlag.isTextField, - SemanticsFlag.isFocusable, - SemanticsFlag.hasEnabledState, - SemanticsFlag.isEnabled, - ], children: [ - TestSemantics(label: 'helper', textDirection: TextDirection.ltr), - TestSemantics(label: '0 out of 10', textDirection: TextDirection.ltr), + TestSemantics( + label: 'label', + textDirection: TextDirection.ltr, + inputType: ui.SemanticsInputType.text, + currentValueLength: 0, + actions: [SemanticsAction.tap, SemanticsAction.focus], + flags: [ + SemanticsFlag.isTextField, + SemanticsFlag.isFocusable, + SemanticsFlag.hasEnabledState, + SemanticsFlag.isEnabled, + ], + children: [ + TestSemantics(label: 'helper', textDirection: TextDirection.ltr), + TestSemantics(label: '0 out of 10', textDirection: TextDirection.ltr), + ], + ), ], ), ], @@ -9448,22 +9536,26 @@ void main() { TestSemantics.root( children: [ TestSemantics.rootChild( - label: 'label', - textDirection: TextDirection.ltr, - actions: [SemanticsAction.tap, SemanticsAction.focus], - flags: [ - SemanticsFlag.isTextField, - SemanticsFlag.isFocusable, - SemanticsFlag.hasEnabledState, - SemanticsFlag.isEnabled, - ], - inputType: ui.SemanticsInputType.text, - currentValueLength: 0, children: [ - TestSemantics( - label: 'oh no!', + TestSemantics.rootChild( + label: 'label', textDirection: TextDirection.ltr, - flags: [if (!supportsAnnounce) SemanticsFlag.isLiveRegion], + actions: [SemanticsAction.tap, SemanticsAction.focus], + flags: [ + SemanticsFlag.isTextField, + SemanticsFlag.isFocusable, + SemanticsFlag.hasEnabledState, + SemanticsFlag.isEnabled, + ], + inputType: ui.SemanticsInputType.text, + currentValueLength: 0, + children: [ + TestSemantics( + label: 'oh no!', + textDirection: TextDirection.ltr, + flags: [if (!supportsAnnounce) SemanticsFlag.isLiveRegion], + ), + ], ), ], ), diff --git a/packages/flutter/test/widgets/selectable_text_test.dart b/packages/flutter/test/widgets/selectable_text_test.dart index 3b25b33692d..47c4eaa9699 100644 --- a/packages/flutter/test/widgets/selectable_text_test.dart +++ b/packages/flutter/test/widgets/selectable_text_test.dart @@ -1617,21 +1617,22 @@ void main() { TestSemantics.root( children: [ TestSemantics.rootChild( - id: 1, - actions: [SemanticsAction.longPress], textDirection: TextDirection.ltr, - inputType: ui.SemanticsInputType.text, children: [ TestSemantics( - id: 2, + actions: [SemanticsAction.longPress], + inputType: ui.SemanticsInputType.text, children: [ - TestSemantics(id: 3, label: 'text', textDirection: TextDirection.ltr), TestSemantics( - id: 4, - flags: [SemanticsFlag.isLink], - actions: [SemanticsAction.tap], - label: 'link', - textDirection: TextDirection.ltr, + children: [ + TestSemantics(label: 'text', textDirection: TextDirection.ltr), + TestSemantics( + flags: [SemanticsFlag.isLink], + actions: [SemanticsAction.tap], + label: 'link', + textDirection: TextDirection.ltr, + ), + ], ), ], ), @@ -1639,6 +1640,7 @@ void main() { ), ], ), + ignoreId: true, ignoreTransform: true, ignoreRect: true, ), @@ -2166,20 +2168,24 @@ void main() { TestSemantics.root( children: [ TestSemantics.rootChild( - id: 1, - textDirection: TextDirection.ltr, - value: 'Guten Tag', - actions: [SemanticsAction.longPress], - inputType: ui.SemanticsInputType.text, - flags: [ - SemanticsFlag.isTextField, - SemanticsFlag.isFocusable, - SemanticsFlag.isReadOnly, - SemanticsFlag.isMultiline, + children: [ + TestSemantics.rootChild( + textDirection: TextDirection.ltr, + value: 'Guten Tag', + actions: [SemanticsAction.longPress], + inputType: ui.SemanticsInputType.text, + flags: [ + SemanticsFlag.isTextField, + SemanticsFlag.isFocusable, + SemanticsFlag.isReadOnly, + SemanticsFlag.isMultiline, + ], + ), ], ), ], ), + ignoreId: true, ignoreTransform: true, ignoreRect: true, ), @@ -2197,27 +2203,31 @@ void main() { TestSemantics.root( children: [ TestSemantics.rootChild( - id: 1, - textDirection: TextDirection.ltr, - value: 'Guten Tag', - textSelection: const TextSelection.collapsed(offset: 9), - inputType: ui.SemanticsInputType.text, - actions: [ - SemanticsAction.longPress, - SemanticsAction.moveCursorBackwardByCharacter, - SemanticsAction.moveCursorBackwardByWord, - SemanticsAction.setSelection, - ], - flags: [ - SemanticsFlag.isReadOnly, - SemanticsFlag.isTextField, - SemanticsFlag.isFocusable, - SemanticsFlag.isMultiline, - SemanticsFlag.isFocused, + children: [ + TestSemantics( + textDirection: TextDirection.ltr, + value: 'Guten Tag', + textSelection: const TextSelection.collapsed(offset: 9), + inputType: ui.SemanticsInputType.text, + actions: [ + SemanticsAction.longPress, + SemanticsAction.moveCursorBackwardByCharacter, + SemanticsAction.moveCursorBackwardByWord, + SemanticsAction.setSelection, + ], + flags: [ + SemanticsFlag.isReadOnly, + SemanticsFlag.isTextField, + SemanticsFlag.isFocusable, + SemanticsFlag.isMultiline, + SemanticsFlag.isFocused, + ], + ), ], ), ], ), + ignoreId: true, ignoreTransform: true, ignoreRect: true, ), @@ -2232,29 +2242,33 @@ void main() { TestSemantics.root( children: [ TestSemantics.rootChild( - id: 1, - textDirection: TextDirection.ltr, - textSelection: const TextSelection.collapsed(offset: 4), - value: 'Guten Tag', - inputType: ui.SemanticsInputType.text, - actions: [ - SemanticsAction.longPress, - SemanticsAction.moveCursorBackwardByCharacter, - SemanticsAction.moveCursorForwardByCharacter, - SemanticsAction.moveCursorBackwardByWord, - SemanticsAction.moveCursorForwardByWord, - SemanticsAction.setSelection, - ], - flags: [ - SemanticsFlag.isReadOnly, - SemanticsFlag.isTextField, - SemanticsFlag.isFocusable, - SemanticsFlag.isMultiline, - SemanticsFlag.isFocused, + children: [ + TestSemantics( + textDirection: TextDirection.ltr, + textSelection: const TextSelection.collapsed(offset: 4), + value: 'Guten Tag', + inputType: ui.SemanticsInputType.text, + actions: [ + SemanticsAction.longPress, + SemanticsAction.moveCursorBackwardByCharacter, + SemanticsAction.moveCursorForwardByCharacter, + SemanticsAction.moveCursorBackwardByWord, + SemanticsAction.moveCursorForwardByWord, + SemanticsAction.setSelection, + ], + flags: [ + SemanticsFlag.isReadOnly, + SemanticsFlag.isTextField, + SemanticsFlag.isFocusable, + SemanticsFlag.isMultiline, + SemanticsFlag.isFocused, + ], + ), ], ), ], ), + ignoreId: true, ignoreTransform: true, ignoreRect: true, ), @@ -2269,27 +2283,31 @@ void main() { TestSemantics.root( children: [ TestSemantics.rootChild( - id: 1, - textDirection: TextDirection.ltr, - textSelection: const TextSelection.collapsed(offset: 0), - value: 'Guten Tag', - inputType: ui.SemanticsInputType.text, - actions: [ - SemanticsAction.longPress, - SemanticsAction.moveCursorForwardByCharacter, - SemanticsAction.moveCursorForwardByWord, - SemanticsAction.setSelection, - ], - flags: [ - SemanticsFlag.isReadOnly, - SemanticsFlag.isTextField, - SemanticsFlag.isFocusable, - SemanticsFlag.isMultiline, - SemanticsFlag.isFocused, + children: [ + TestSemantics( + textDirection: TextDirection.ltr, + textSelection: const TextSelection.collapsed(offset: 0), + value: 'Guten Tag', + inputType: ui.SemanticsInputType.text, + actions: [ + SemanticsAction.longPress, + SemanticsAction.moveCursorForwardByCharacter, + SemanticsAction.moveCursorForwardByWord, + SemanticsAction.setSelection, + ], + flags: [ + SemanticsFlag.isReadOnly, + SemanticsFlag.isTextField, + SemanticsFlag.isFocusable, + SemanticsFlag.isMultiline, + SemanticsFlag.isFocused, + ], + ), ], ), ], ), + ignoreId: true, ignoreTransform: true, ignoreRect: true, ), @@ -2317,14 +2335,18 @@ void main() { hasSemantics( TestSemantics.root( children: [ - TestSemantics( - id: 1, - actions: [SemanticsAction.longPress], - label: 'German greeting for good day', - textDirection: TextDirection.ltr, + TestSemantics.rootChild( + children: [ + TestSemantics( + actions: [SemanticsAction.longPress], + label: 'German greeting for good day', + textDirection: TextDirection.ltr, + ), + ], ), ], ), + ignoreId: true, ignoreTransform: true, ignoreRect: true, ), @@ -2351,30 +2373,34 @@ void main() { TestSemantics.root( children: [ TestSemantics.rootChild( - id: 1, - value: 'Guten Tag', - textDirection: TextDirection.ltr, - inputType: ui.SemanticsInputType.text, - actions: [ - SemanticsAction.longPress, - // Absent the following because enableInteractiveSelection: false - // SemanticsAction.moveCursorBackwardByCharacter, - // SemanticsAction.moveCursorBackwardByWord, - // SemanticsAction.setSelection, - // SemanticsAction.paste, - ], - flags: [ - SemanticsFlag.isReadOnly, - SemanticsFlag.isTextField, - SemanticsFlag.isFocusable, - SemanticsFlag.isMultiline, - // SelectableText act like a text widget when enableInteractiveSelection - // is false. It will not respond to any pointer event. - // SemanticsFlag.isFocused, + children: [ + TestSemantics( + value: 'Guten Tag', + textDirection: TextDirection.ltr, + inputType: ui.SemanticsInputType.text, + actions: [ + SemanticsAction.longPress, + // Absent the following because enableInteractiveSelection: false + // SemanticsAction.moveCursorBackwardByCharacter, + // SemanticsAction.moveCursorBackwardByWord, + // SemanticsAction.setSelection, + // SemanticsAction.paste, + ], + flags: [ + SemanticsFlag.isReadOnly, + SemanticsFlag.isTextField, + SemanticsFlag.isFocusable, + SemanticsFlag.isMultiline, + // SelectableText act like a text widget when enableInteractiveSelection + // is false. It will not respond to any pointer event. + // SemanticsFlag.isFocused, + ], + ), ], ), ], ), + ignoreId: true, ignoreTransform: true, ignoreRect: true, ), @@ -2398,20 +2424,24 @@ void main() { TestSemantics.root( children: [ TestSemantics.rootChild( - id: 1, - value: 'Hello', - textDirection: TextDirection.ltr, - inputType: ui.SemanticsInputType.text, - actions: [SemanticsAction.longPress], - flags: [ - SemanticsFlag.isReadOnly, - SemanticsFlag.isTextField, - SemanticsFlag.isFocusable, - SemanticsFlag.isMultiline, + children: [ + TestSemantics( + value: 'Hello', + textDirection: TextDirection.ltr, + inputType: ui.SemanticsInputType.text, + actions: [SemanticsAction.longPress], + flags: [ + SemanticsFlag.isReadOnly, + SemanticsFlag.isTextField, + SemanticsFlag.isFocusable, + SemanticsFlag.isMultiline, + ], + ), ], ), ], ), + ignoreId: true, ignoreTransform: true, ignoreRect: true, ), @@ -2430,27 +2460,31 @@ void main() { TestSemantics.root( children: [ TestSemantics.rootChild( - id: 1, - value: 'Hello', - textSelection: const TextSelection.collapsed(offset: 5), - textDirection: TextDirection.ltr, - inputType: ui.SemanticsInputType.text, - actions: [ - SemanticsAction.longPress, - SemanticsAction.moveCursorBackwardByCharacter, - SemanticsAction.moveCursorBackwardByWord, - SemanticsAction.setSelection, - ], - flags: [ - SemanticsFlag.isReadOnly, - SemanticsFlag.isTextField, - SemanticsFlag.isFocusable, - SemanticsFlag.isMultiline, - SemanticsFlag.isFocused, + children: [ + TestSemantics( + value: 'Hello', + textSelection: const TextSelection.collapsed(offset: 5), + textDirection: TextDirection.ltr, + inputType: ui.SemanticsInputType.text, + actions: [ + SemanticsAction.longPress, + SemanticsAction.moveCursorBackwardByCharacter, + SemanticsAction.moveCursorBackwardByWord, + SemanticsAction.setSelection, + ], + flags: [ + SemanticsFlag.isReadOnly, + SemanticsFlag.isTextField, + SemanticsFlag.isFocusable, + SemanticsFlag.isMultiline, + SemanticsFlag.isFocused, + ], + ), ], ), ], ), + ignoreId: true, ignoreTransform: true, ignoreRect: true, ), @@ -2465,30 +2499,34 @@ void main() { TestSemantics.root( children: [ TestSemantics.rootChild( - id: 1, - value: 'Hello', - textSelection: const TextSelection(baseOffset: 5, extentOffset: 3), - textDirection: TextDirection.ltr, - inputType: ui.SemanticsInputType.text, - actions: [ - SemanticsAction.longPress, - SemanticsAction.moveCursorBackwardByCharacter, - SemanticsAction.moveCursorForwardByCharacter, - SemanticsAction.moveCursorBackwardByWord, - SemanticsAction.moveCursorForwardByWord, - SemanticsAction.setSelection, - SemanticsAction.copy, - ], - flags: [ - SemanticsFlag.isReadOnly, - SemanticsFlag.isTextField, - SemanticsFlag.isFocusable, - SemanticsFlag.isMultiline, - SemanticsFlag.isFocused, + children: [ + TestSemantics( + value: 'Hello', + textSelection: const TextSelection(baseOffset: 5, extentOffset: 3), + textDirection: TextDirection.ltr, + inputType: ui.SemanticsInputType.text, + actions: [ + SemanticsAction.longPress, + SemanticsAction.moveCursorBackwardByCharacter, + SemanticsAction.moveCursorForwardByCharacter, + SemanticsAction.moveCursorBackwardByWord, + SemanticsAction.moveCursorForwardByWord, + SemanticsAction.setSelection, + SemanticsAction.copy, + ], + flags: [ + SemanticsFlag.isReadOnly, + SemanticsFlag.isTextField, + SemanticsFlag.isFocusable, + SemanticsFlag.isMultiline, + SemanticsFlag.isFocused, + ], + ), ], ), ], ), + ignoreId: true, ignoreTransform: true, ignoreRect: true, ), @@ -2609,7 +2647,7 @@ void main() { controller.selection = const TextSelection(baseOffset: 5, extentOffset: 5); await tester.pump(); - const inputFieldId = 1; + const inputFieldId = 2; expect( semantics, @@ -2617,23 +2655,28 @@ void main() { TestSemantics.root( children: [ TestSemantics.rootChild( - id: inputFieldId, - value: 'Hello', - textSelection: const TextSelection.collapsed(offset: 5), - textDirection: TextDirection.ltr, - inputType: ui.SemanticsInputType.text, - actions: [ - SemanticsAction.longPress, - SemanticsAction.moveCursorBackwardByCharacter, - SemanticsAction.moveCursorBackwardByWord, - SemanticsAction.setSelection, - ], - flags: [ - SemanticsFlag.isReadOnly, - SemanticsFlag.isTextField, - SemanticsFlag.isFocusable, - SemanticsFlag.isMultiline, - SemanticsFlag.isFocused, + id: 1, + children: [ + TestSemantics( + id: inputFieldId, + value: 'Hello', + textSelection: const TextSelection.collapsed(offset: 5), + textDirection: TextDirection.ltr, + inputType: ui.SemanticsInputType.text, + actions: [ + SemanticsAction.longPress, + SemanticsAction.moveCursorBackwardByCharacter, + SemanticsAction.moveCursorBackwardByWord, + SemanticsAction.setSelection, + ], + flags: [ + SemanticsFlag.isReadOnly, + SemanticsFlag.isTextField, + SemanticsFlag.isFocusable, + SemanticsFlag.isMultiline, + SemanticsFlag.isFocused, + ], + ), ], ), ], @@ -2672,24 +2715,29 @@ void main() { TestSemantics.root( children: [ TestSemantics.rootChild( - id: inputFieldId, - value: 'Hello', - textSelection: const TextSelection(baseOffset: 0, extentOffset: 5), - textDirection: TextDirection.ltr, - inputType: ui.SemanticsInputType.text, - actions: [ - SemanticsAction.longPress, - SemanticsAction.moveCursorBackwardByCharacter, - SemanticsAction.moveCursorBackwardByWord, - SemanticsAction.setSelection, - SemanticsAction.copy, - ], - flags: [ - SemanticsFlag.isReadOnly, - SemanticsFlag.isTextField, - SemanticsFlag.isFocusable, - SemanticsFlag.isMultiline, - SemanticsFlag.isFocused, + id: 1, + children: [ + TestSemantics( + id: inputFieldId, + value: 'Hello', + textSelection: const TextSelection(baseOffset: 0, extentOffset: 5), + textDirection: TextDirection.ltr, + inputType: ui.SemanticsInputType.text, + actions: [ + SemanticsAction.longPress, + SemanticsAction.moveCursorBackwardByCharacter, + SemanticsAction.moveCursorBackwardByWord, + SemanticsAction.setSelection, + SemanticsAction.copy, + ], + flags: [ + SemanticsFlag.isReadOnly, + SemanticsFlag.isTextField, + SemanticsFlag.isFocusable, + SemanticsFlag.isMultiline, + SemanticsFlag.isFocused, + ], + ), ], ), ], @@ -2715,25 +2763,30 @@ void main() { await tester.pumpWidget(overlay(child: SelectableText(testValue, key: key))); - const inputFieldId = 1; + const inputFieldId = 2; expect( semantics, hasSemantics( TestSemantics.root( children: [ - TestSemantics( - id: inputFieldId, - inputType: ui.SemanticsInputType.text, - flags: [ - SemanticsFlag.isReadOnly, - SemanticsFlag.isTextField, - SemanticsFlag.isFocusable, - SemanticsFlag.isMultiline, + TestSemantics.rootChild( + id: 1, + children: [ + TestSemantics( + id: inputFieldId, + inputType: ui.SemanticsInputType.text, + flags: [ + SemanticsFlag.isReadOnly, + SemanticsFlag.isTextField, + SemanticsFlag.isFocusable, + SemanticsFlag.isMultiline, + ], + actions: [SemanticsAction.longPress], + value: testValue, + textDirection: TextDirection.ltr, + ), ], - actions: [SemanticsAction.longPress], - value: testValue, - textDirection: TextDirection.ltr, ), ], ), @@ -2750,28 +2803,33 @@ void main() { hasSemantics( TestSemantics.root( children: [ - TestSemantics( - id: inputFieldId, - inputType: ui.SemanticsInputType.text, - flags: [ - SemanticsFlag.isReadOnly, - SemanticsFlag.isTextField, - SemanticsFlag.isFocusable, - SemanticsFlag.isMultiline, - SemanticsFlag.isFocused, + TestSemantics.rootChild( + id: 1, + children: [ + TestSemantics( + id: inputFieldId, + inputType: ui.SemanticsInputType.text, + flags: [ + SemanticsFlag.isReadOnly, + SemanticsFlag.isTextField, + SemanticsFlag.isFocusable, + SemanticsFlag.isMultiline, + SemanticsFlag.isFocused, + ], + actions: [ + SemanticsAction.longPress, + SemanticsAction.moveCursorBackwardByCharacter, + SemanticsAction.moveCursorBackwardByWord, + SemanticsAction.setSelection, + ], + value: testValue, + textDirection: TextDirection.ltr, + textSelection: const TextSelection( + baseOffset: testValue.length, + extentOffset: testValue.length, + ), + ), ], - actions: [ - SemanticsAction.longPress, - SemanticsAction.moveCursorBackwardByCharacter, - SemanticsAction.moveCursorBackwardByWord, - SemanticsAction.setSelection, - ], - value: testValue, - textDirection: TextDirection.ltr, - textSelection: const TextSelection( - baseOffset: testValue.length, - extentOffset: testValue.length, - ), ), ], ), diff --git a/packages/flutter/test/widgets/semantics_test.dart b/packages/flutter/test/widgets/semantics_test.dart index 4e23edf2835..f2bd18ab097 100644 --- a/packages/flutter/test/widgets/semantics_test.dart +++ b/packages/flutter/test/widgets/semantics_test.dart @@ -184,6 +184,43 @@ void main() { semantics.dispose(); }); + testWidgets('different locale will not merge', (WidgetTester tester) async { + final semantics = SemanticsTester(tester); + final GlobalKey key = GlobalKey(); + + await tester.pumpWidget( + Directionality( + textDirection: TextDirection.ltr, + child: Semantics( + localeForSubtree: const Locale('AB', 'CD'), + child: Semantics( + key: key, + localeForSubtree: const Locale('DE', 'FG'), + child: const SizedBox(width: 10, height: 10), + ), + ), + ), + ); + + expect( + semantics, + hasSemantics( + TestSemantics.root( + children: [ + TestSemantics.rootChild( + locale: const Locale('AB', 'CD'), + children: [TestSemantics(locale: const Locale('DE', 'FG'))], + ), + ], + ), + ignoreId: true, + ignoreRect: true, + ignoreTransform: true, + ), + ); + semantics.dispose(); + }); + testWidgets('Semantics and Directionality - RTL', (WidgetTester tester) async { final semantics = SemanticsTester(tester); diff --git a/packages/flutter/test/widgets/semantics_tester.dart b/packages/flutter/test/widgets/semantics_tester.dart index 9502fa02321..f03a4ec9ad0 100644 --- a/packages/flutter/test/widgets/semantics_tester.dart +++ b/packages/flutter/test/widgets/semantics_tester.dart @@ -63,6 +63,7 @@ class TestSemantics { this.identifier = '', this.traversalParentIdentifier, this.traversalChildIdentifier, + this.locale, this.hintOverrides, }) : assert(flags is int || flags is List || flags is SemanticsFlags), assert(actions is int || actions is List), @@ -97,6 +98,7 @@ class TestSemantics { this.identifier = '', this.traversalParentIdentifier, this.traversalChildIdentifier, + this.locale, this.hintOverrides, }) : id = 0, assert(flags is int || flags is List || flags is SemanticsFlags), @@ -143,6 +145,7 @@ class TestSemantics { this.identifier = '', this.traversalParentIdentifier, this.traversalChildIdentifier, + this.locale, this.hintOverrides, }) : assert(flags is int || flags is List || flags is SemanticsFlags), assert(actions is int || actions is List), @@ -301,6 +304,11 @@ class TestSemantics { /// Defaults to null if not set. final Object? traversalChildIdentifier; + /// The expected locale for the node. + /// + /// Defaults to null if not set. + final Locale? locale; + /// The expected hint overrides for the node. /// /// Defaults to null if not set. @@ -515,6 +523,11 @@ class TestSemantics { 'expected node id $id to have hint overrides $hintOverrides but found hint overrides ${node.hintOverrides}', ); } + if (locale != null && locale != node.getSemanticsData().locale) { + return fail( + 'expected node id $id to have locale $locale but found locale ${node.getSemanticsData().locale}', + ); + } if (children.isEmpty) { return true;