add ability to match child semantics data (#22001)
diff --git a/examples/flutter_gallery/test/demo/material/chip_demo_test.dart b/examples/flutter_gallery/test/demo/material/chip_demo_test.dart
index ef0b6d1..cfc9c65 100644
--- a/examples/flutter_gallery/test/demo/material/chip_demo_test.dart
+++ b/examples/flutter_gallery/test/demo/material/chip_demo_test.dart
@@ -14,7 +14,7 @@
home: ChipDemo(),
));
- expect(tester.getSemanticsData(find.byIcon(Icons.vignette)), matchesSemanticsData(
+ expect(tester.getSemantics(find.byIcon(Icons.vignette)), matchesSemantics(
isButton: true,
hasEnabledState: true,
isEnabled: true,
@@ -22,7 +22,7 @@
label: 'Update border shape',
));
- expect(tester.getSemanticsData(find.byIcon(Icons.refresh)), matchesSemanticsData(
+ expect(tester.getSemantics(find.byIcon(Icons.refresh)), matchesSemantics(
isButton: true,
hasEnabledState: true,
isEnabled: true,
diff --git a/packages/flutter/test/cupertino/slider_test.dart b/packages/flutter/test/cupertino/slider_test.dart
index 5c8e1ca..eae21e7 100644
--- a/packages/flutter/test/cupertino/slider_test.dart
+++ b/packages/flutter/test/cupertino/slider_test.dart
@@ -330,7 +330,7 @@
),
));
- expect(tester.getSemanticsData(find.byType(CupertinoSlider)), matchesSemanticsData(
+ expect(tester.getSemantics(find.byType(CupertinoSlider)), matchesSemantics(
hasIncreaseAction: true,
hasDecreaseAction: true,
value: '50%',
@@ -348,7 +348,7 @@
),
));
- expect(tester.getSemanticsData(find.byType(CupertinoSlider)), matchesSemanticsData(
+ expect(tester.getSemantics(find.byType(CupertinoSlider)), matchesSemantics(
hasIncreaseAction: true,
hasDecreaseAction: true,
value: '60%',
diff --git a/packages/flutter/test/material/back_button_test.dart b/packages/flutter/test/material/back_button_test.dart
index 3f50b76..dab5b65 100644
--- a/packages/flutter/test/material/back_button_test.dart
+++ b/packages/flutter/test/material/back_button_test.dart
@@ -82,7 +82,7 @@
await tester.pumpAndSettle();
- expect(tester.getSemanticsData(find.byType(BackButton)), matchesSemanticsData(
+ expect(tester.getSemantics(find.byType(BackButton)), matchesSemantics(
label: 'Back',
isButton: true,
hasEnabledState: true,
diff --git a/packages/flutter/test/material/checkbox_test.dart b/packages/flutter/test/material/checkbox_test.dart
index 3d3a64e..eba2aee 100644
--- a/packages/flutter/test/material/checkbox_test.dart
+++ b/packages/flutter/test/material/checkbox_test.dart
@@ -66,7 +66,7 @@
),
));
- expect(tester.getSemanticsData(find.byType(Checkbox)), matchesSemanticsData(
+ expect(tester.getSemantics(find.byType(Checkbox)), matchesSemantics(
hasCheckedState: true,
hasEnabledState: true,
isEnabled: true,
@@ -80,7 +80,7 @@
),
));
- expect(tester.getSemanticsData(find.byType(Checkbox)), matchesSemanticsData(
+ expect(tester.getSemantics(find.byType(Checkbox)), matchesSemantics(
hasCheckedState: true,
hasEnabledState: true,
isChecked: true,
@@ -95,7 +95,7 @@
),
));
- expect(tester.getSemanticsData(find.byType(Checkbox)), matchesSemanticsData(
+ expect(tester.getSemantics(find.byType(Checkbox)), matchesSemantics(
hasCheckedState: true,
hasEnabledState: true,
));
@@ -107,7 +107,7 @@
),
));
- expect(tester.getSemanticsData(find.byType(Checkbox)), matchesSemanticsData(
+ expect(tester.getSemantics(find.byType(Checkbox)), matchesSemantics(
hasCheckedState: true,
hasEnabledState: true,
isChecked: true,
@@ -129,7 +129,7 @@
),
));
- expect(tester.getSemanticsData(find.byType(Checkbox)), matchesSemanticsData(
+ expect(tester.getSemantics(find.byType(Checkbox)), matchesSemantics(
label: 'foo',
textDirection: TextDirection.ltr,
hasCheckedState: true,
diff --git a/packages/flutter/test/material/dropdown_test.dart b/packages/flutter/test/material/dropdown_test.dart
index 950629d..c061135 100644
--- a/packages/flutter/test/material/dropdown_test.dart
+++ b/packages/flutter/test/material/dropdown_test.dart
@@ -692,7 +692,7 @@
));
// By default the hint contributes the label.
- expect(tester.getSemanticsData(find.byKey(key)), matchesSemanticsData(
+ expect(tester.getSemantics(find.byKey(key)), matchesSemantics(
isButton: true,
label: 'test',
hasTapAction: true,
@@ -707,7 +707,7 @@
));
// Displays label of select item and is no longer tappable.
- expect(tester.getSemanticsData(find.byKey(key)), matchesSemanticsData(
+ expect(tester.getSemantics(find.byKey(key)), matchesSemantics(
isButton: true,
label: 'three',
hasTapAction: true,
diff --git a/packages/flutter/test/material/expand_icon_test.dart b/packages/flutter/test/material/expand_icon_test.dart
index 2b537eb..57e0a2a 100644
--- a/packages/flutter/test/material/expand_icon_test.dart
+++ b/packages/flutter/test/material/expand_icon_test.dart
@@ -95,7 +95,7 @@
)
));
- expect(tester.getSemanticsData(find.byType(ExpandIcon)), matchesSemanticsData(
+ expect(tester.getSemantics(find.byType(ExpandIcon)), matchesSemantics(
hasTapAction: true,
hasEnabledState: true,
isEnabled: true,
@@ -110,7 +110,7 @@
)
));
- expect(tester.getSemanticsData(find.byType(ExpandIcon)), matchesSemanticsData(
+ expect(tester.getSemantics(find.byType(ExpandIcon)), matchesSemantics(
hasTapAction: true,
hasEnabledState: true,
isEnabled: true,
diff --git a/packages/flutter/test/material/expansion_panel_test.dart b/packages/flutter/test/material/expansion_panel_test.dart
index eb8725d..bf915a7 100644
--- a/packages/flutter/test/material/expansion_panel_test.dart
+++ b/packages/flutter/test/material/expansion_panel_test.dart
@@ -382,7 +382,7 @@
),
);
- expect(tester.getSemanticsData(find.byKey(expandedKey)), matchesSemanticsData(
+ expect(tester.getSemantics(find.byKey(expandedKey)), matchesSemantics(
label: 'Expanded',
isButton: true,
hasEnabledState: true,
@@ -391,7 +391,7 @@
onTapHint: localizations.expandedIconTapHint,
));
- expect(tester.getSemanticsData(find.byKey(collapsedKey)), matchesSemanticsData(
+ expect(tester.getSemantics(find.byKey(collapsedKey)), matchesSemantics(
label: 'Collapsed',
isButton: true,
hasEnabledState: true,
diff --git a/packages/flutter/test/material/reorderable_list_test.dart b/packages/flutter/test/material/reorderable_list_test.dart
index bab13e2..7acdedc 100644
--- a/packages/flutter/test/material/reorderable_list_test.dart
+++ b/packages/flutter/test/material/reorderable_list_test.dart
@@ -462,10 +462,10 @@
));
// Get the switch tile's semantics:
- final SemanticsData semanticsData = tester.getSemanticsData(find.byKey(const Key('Switch tile')));
+ final SemanticsNode semanticsNode = tester.getSemantics(find.byKey(const Key('Switch tile')));
// Check for properties of both SwitchTile semantics and the ReorderableListView custom semantics actions.
- expect(semanticsData, matchesSemanticsData(
+ expect(semanticsNode, matchesSemantics(
hasToggledState: true,
isToggled: true,
isEnabled: true,
diff --git a/packages/flutter/test/material/snack_bar_test.dart b/packages/flutter/test/material/snack_bar_test.dart
index 992c132..1404263 100644
--- a/packages/flutter/test/material/snack_bar_test.dart
+++ b/packages/flutter/test/material/snack_bar_test.dart
@@ -555,7 +555,7 @@
await tester.tap(find.text('X'));
await tester.pumpAndSettle();
- expect(tester.getSemanticsData(find.text('snack')), matchesSemanticsData(
+ expect(tester.getSemantics(find.text('snack')), matchesSemantics(
isLiveRegion: true,
hasDismissAction: true,
hasScrollDownAction: true,
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 25ea2bd..31fb510 100644
--- a/packages/flutter/test/material/user_accounts_drawer_header_test.dart
+++ b/packages/flutter/test/material/user_accounts_drawer_header_test.dart
@@ -378,17 +378,17 @@
final SemanticsHandle handle = tester.ensureSemantics();
await pumpTestWidget(tester);
- expect(tester.getSemanticsData(find.text('B')), matchesSemanticsData(
+ expect(tester.getSemantics(find.text('B')), matchesSemantics(
label: 'B',
size: const Size(48.0, 48.0),
));
- expect(tester.getSemanticsData(find.text('C')), matchesSemanticsData(
+ expect(tester.getSemantics(find.text('C')), matchesSemantics(
label: 'C',
size: const Size(48.0, 48.0),
));
- expect(tester.getSemanticsData(find.text('D')), matchesSemanticsData(
+ expect(tester.getSemantics(find.text('D')), matchesSemantics(
label: 'D',
size: const Size(48.0, 48.0),
));
diff --git a/packages/flutter/test/widgets/image_icon_test.dart b/packages/flutter/test/widgets/image_icon_test.dart
index cf70e78..676c530 100644
--- a/packages/flutter/test/widgets/image_icon_test.dart
+++ b/packages/flutter/test/widgets/image_icon_test.dart
@@ -111,7 +111,7 @@
),
);
- expect(tester.getSemanticsData(find.byType(ImageIcon)), matchesSemanticsData(
+ expect(tester.getSemantics(find.byType(ImageIcon)), matchesSemantics(
label: 'test',
textDirection: TextDirection.ltr,
));
diff --git a/packages/flutter/test/widgets/semantics_test.dart b/packages/flutter/test/widgets/semantics_test.dart
index c2214c7..6f27b26 100644
--- a/packages/flutter/test/widgets/semantics_test.dart
+++ b/packages/flutter/test/widgets/semantics_test.dart
@@ -643,7 +643,7 @@
onTapHint: 'test',
));
- expect(tester.getSemanticsData(find.byType(Semantics)), matchesSemanticsData(
+ expect(tester.getSemantics(find.byType(Semantics)), matchesSemantics(
hasTapAction: true,
onTapHint: 'test'
));
@@ -654,7 +654,7 @@
onLongPressHint: 'foo',
));
- expect(tester.getSemanticsData(find.byType(Semantics)), matchesSemanticsData(
+ expect(tester.getSemantics(find.byType(Semantics)), matchesSemantics(
hasLongPressAction: true,
onLongPressHint: 'foo'
));
@@ -671,7 +671,7 @@
},
));
- expect(tester.getSemanticsData(find.byType(Semantics)), matchesSemanticsData(
+ expect(tester.getSemantics(find.byType(Semantics)), matchesSemantics(
customActions: <CustomSemanticsAction>[
const CustomSemanticsAction(label: 'bar'),
const CustomSemanticsAction(label: 'foo'),
diff --git a/packages/flutter_test/lib/src/matchers.dart b/packages/flutter_test/lib/src/matchers.dart
index c30759a..dda8377 100644
--- a/packages/flutter_test/lib/src/matchers.dart
+++ b/packages/flutter_test/lib/src/matchers.dart
@@ -325,13 +325,13 @@
return _MatchesReferenceImage(image);
}
-/// Asserts that a [SemanticsData] contains the specified information.
+/// Asserts that a [SemanticsNode] contains the specified information.
///
/// If either the label, hint, value, textDirection, or rect fields are not
/// provided, then they are not part of the comparison. All of the boolean
/// flag and action fields must match, and default to false.
///
-/// To retrieve the semantics data of a widget, use [tester.getSemanticsData]
+/// To retrieve the semantics data of a widget, use [tester.getSemantics]
/// with a [Finder] that returns a single widget. Semantics must be enabled
/// in order to use this method.
///
@@ -339,14 +339,178 @@
///
/// ```dart
/// final SemanticsHandle handle = tester.ensureSemantics();
-/// final SemanticsData data = tester.getSemanticsData(find.text('hello'));
-/// expect(data, matchesSemanticsData(label: 'hello'));
+/// expect(tester.getSemantics(find.text('hello')), matchesSemanticsNode(label: 'hello'));
/// handle.dispose();
/// ```
///
/// See also:
///
-/// * [WidgetTester.getSemanticsData], the tester method which retrieves data.
+/// * [WidgetTester.getSemantics], the tester method which retrieves semantics.
+Matcher matchesSemantics({
+ String label,
+ String hint,
+ String value,
+ String increasedValue,
+ String decreasedValue,
+ TextDirection textDirection,
+ Rect rect,
+ Size size,
+ // Flags //
+ bool hasCheckedState = false,
+ bool isChecked = false,
+ bool isSelected = false,
+ bool isButton = false,
+ bool isFocused = false,
+ bool isTextField = false,
+ bool hasEnabledState = false,
+ bool isEnabled = false,
+ bool isInMutuallyExclusiveGroup = false,
+ bool isHeader = false,
+ bool isObscured = false,
+ bool namesRoute = false,
+ bool scopesRoute = false,
+ bool isHidden = false,
+ bool isImage = false,
+ bool isLiveRegion = false,
+ bool hasToggledState = false,
+ bool isToggled = false,
+ bool hasImplicitScrolling = false,
+ // Actions //
+ bool hasTapAction = false,
+ bool hasLongPressAction = false,
+ bool hasScrollLeftAction = false,
+ bool hasScrollRightAction = false,
+ bool hasScrollUpAction = false,
+ bool hasScrollDownAction = false,
+ bool hasIncreaseAction = false,
+ bool hasDecreaseAction = false,
+ bool hasShowOnScreenAction = false,
+ bool hasMoveCursorForwardByCharacterAction = false,
+ bool hasMoveCursorBackwardByCharacterAction = false,
+ bool hasMoveCursorForwardByWordAction = false,
+ bool hasMoveCursorBackwardByWordAction = false,
+ bool hasSetSelectionAction = false,
+ bool hasCopyAction = false,
+ bool hasCutAction = false,
+ bool hasPasteAction = false,
+ bool hasDidGainAccessibilityFocusAction = false,
+ bool hasDidLoseAccessibilityFocusAction = false,
+ bool hasDismissAction = false,
+ // Custom actions and overrides
+ String onTapHint,
+ String onLongPressHint,
+ List<CustomSemanticsAction> customActions,
+ List<Matcher> children,
+}) {
+ final List<SemanticsFlag> flags = <SemanticsFlag>[];
+ if (hasCheckedState)
+ flags.add(SemanticsFlag.hasCheckedState);
+ if (isChecked)
+ flags.add(SemanticsFlag.isChecked);
+ if (isSelected)
+ flags.add(SemanticsFlag.isSelected);
+ if (isButton)
+ flags.add(SemanticsFlag.isButton);
+ if (isTextField)
+ flags.add(SemanticsFlag.isTextField);
+ if (isFocused)
+ flags.add(SemanticsFlag.isFocused);
+ if (hasEnabledState)
+ flags.add(SemanticsFlag.hasEnabledState);
+ if (isEnabled)
+ flags.add(SemanticsFlag.isEnabled);
+ if (isInMutuallyExclusiveGroup)
+ flags.add(SemanticsFlag.isInMutuallyExclusiveGroup);
+ if (isHeader)
+ flags.add(SemanticsFlag.isHeader);
+ if (isObscured)
+ flags.add(SemanticsFlag.isObscured);
+ if (namesRoute)
+ flags.add(SemanticsFlag.namesRoute);
+ if (scopesRoute)
+ flags.add(SemanticsFlag.scopesRoute);
+ if (isHidden)
+ flags.add(SemanticsFlag.isHidden);
+ if (isImage)
+ flags.add(SemanticsFlag.isImage);
+ if (isLiveRegion)
+ flags.add(SemanticsFlag.isLiveRegion);
+ if (hasToggledState)
+ flags.add(SemanticsFlag.hasToggledState);
+ if (isToggled)
+ flags.add(SemanticsFlag.isToggled);
+ if (hasImplicitScrolling)
+ flags.add(SemanticsFlag.hasImplicitScrolling);
+
+ final List<SemanticsAction> actions = <SemanticsAction>[];
+ if (hasTapAction)
+ actions.add(SemanticsAction.tap);
+ if (hasLongPressAction)
+ actions.add(SemanticsAction.longPress);
+ if (hasScrollLeftAction)
+ actions.add(SemanticsAction.scrollLeft);
+ if (hasScrollRightAction)
+ actions.add(SemanticsAction.scrollRight);
+ if (hasScrollUpAction)
+ actions.add(SemanticsAction.scrollUp);
+ if (hasScrollDownAction)
+ actions.add(SemanticsAction.scrollDown);
+ if (hasIncreaseAction)
+ actions.add(SemanticsAction.increase);
+ if (hasDecreaseAction)
+ actions.add(SemanticsAction.decrease);
+ if (hasShowOnScreenAction)
+ actions.add(SemanticsAction.showOnScreen);
+ if (hasMoveCursorForwardByCharacterAction)
+ actions.add(SemanticsAction.moveCursorForwardByCharacter);
+ if (hasMoveCursorBackwardByCharacterAction)
+ actions.add(SemanticsAction.moveCursorBackwardByCharacter);
+ if (hasSetSelectionAction)
+ actions.add(SemanticsAction.setSelection);
+ if (hasCopyAction)
+ actions.add(SemanticsAction.copy);
+ if (hasCutAction)
+ actions.add(SemanticsAction.cut);
+ if (hasPasteAction)
+ actions.add(SemanticsAction.paste);
+ if (hasDidGainAccessibilityFocusAction)
+ actions.add(SemanticsAction.didGainAccessibilityFocus);
+ if (hasDidLoseAccessibilityFocusAction)
+ actions.add(SemanticsAction.didLoseAccessibilityFocus);
+ if (customActions != null && customActions.isNotEmpty)
+ actions.add(SemanticsAction.customAction);
+ if (hasDismissAction)
+ actions.add(SemanticsAction.dismiss);
+ if (hasMoveCursorForwardByWordAction)
+ actions.add(SemanticsAction.moveCursorForwardByWord);
+ if (hasMoveCursorBackwardByWordAction)
+ actions.add(SemanticsAction.moveCursorBackwardByWord);
+ SemanticsHintOverrides hintOverrides;
+ if (onTapHint != null || onLongPressHint != null)
+ hintOverrides = SemanticsHintOverrides(
+ onTapHint: onTapHint,
+ onLongPressHint: onLongPressHint,
+ );
+
+ return _MatchesSemanticsData(
+ label: label,
+ hint: hint,
+ value: value,
+ increasedValue: increasedValue,
+ decreasedValue: decreasedValue,
+ actions: actions,
+ flags: flags,
+ textDirection: textDirection,
+ rect: rect,
+ size: size,
+ customActions: customActions,
+ hintOverrides: hintOverrides,
+ children: children,
+ );
+}
+
+/// DEPRECATED: use [matchesSemantics] instead.
+@Deprecated('use matchesSemantics instead')
Matcher matchesSemanticsData({
String label,
String hint,
@@ -402,7 +566,7 @@
String onLongPressHint,
List<CustomSemanticsAction> customActions,
}) {
- final List<SemanticsFlag> flags = <SemanticsFlag>[];
+ final List<SemanticsFlag> flags = <SemanticsFlag>[];
if (hasCheckedState)
flags.add(SemanticsFlag.hasCheckedState);
if (isChecked)
@@ -1686,6 +1850,7 @@
this.size,
this.customActions,
this.hintOverrides,
+ this.children,
});
final String label;
@@ -1700,43 +1865,51 @@
final TextDirection textDirection;
final Rect rect;
final Size size;
+ final List<Matcher> children;
@override
Description describe(Description description) {
description.add('has semantics');
if (label != null)
- description.add('with label: $label ');
+ description.add(' with label: $label');
if (value != null)
- description.add('with value: $value ');
+ description.add(' with value: $value');
if (hint != null)
- description.add('with hint: $hint ');
+ description.add(' with hint: $hint');
if (increasedValue != null)
- description.add('with increasedValue: $increasedValue');
+ description.add(' with increasedValue: $increasedValue ');
if (decreasedValue != null)
- description.add('with decreasedValue: $decreasedValue');
+ description.add(' with decreasedValue: $decreasedValue ');
if (actions != null)
- description.add('with actions:').addDescriptionOf(actions);
+ description.add(' with actions: ').addDescriptionOf(actions);
if (flags != null)
- description.add('with flags:').addDescriptionOf(flags);
+ description.add(' with flags: ').addDescriptionOf(flags);
if (textDirection != null)
- description.add('with textDirection: $textDirection ');
+ description.add(' with textDirection: $textDirection ');
if (rect != null)
- description.add('with rect: $rect');
+ description.add(' with rect: $rect');
if (size != null)
- description.add('with size: $size');
+ description.add(' with size: $size');
if (customActions != null)
- description.add('with custom actions: $customActions');
+ description.add(' with custom actions: $customActions');
if (hintOverrides != null)
- description.add('with custom hints: $hintOverrides');
+ description.add(' with custom hints: $hintOverrides');
+ if (children != null) {
+ description.add(' with children:\n');
+ for (_MatchesSemanticsData child in children)
+ child.describe(description);
+ }
return description;
}
@override
- bool matches(covariant SemanticsData data, Map<dynamic, dynamic> matchState) {
- if (data == null)
+ bool matches(dynamic node, Map<dynamic, dynamic> matchState) {
+ // TODO(jonahwilliams): remove dynamic once we have removed getSemanticsData.
+ if (node == null)
return failWithDescription(matchState, 'No SemanticsData provided. '
- 'Maybe you forgot to enabled semantics?');
+ 'Maybe you forgot to enable semantics?');
+ final SemanticsData data = node is SemanticsNode ? node.getSemanticsData() : node;
if (label != null && label != data.label)
return failWithDescription(matchState, 'label was: ${data.label}');
if (hint != null && hint != data.hint)
@@ -1800,7 +1973,16 @@
return failWithDescription(matchState, 'flags were: $flagSummary');
}
}
- return true;
+ bool allMatched = true;
+ if (children != null) {
+ int i = 0;
+ node.visitChildren((SemanticsNode child) {
+ allMatched = children[i].matches(child, matchState) && allMatched;
+ i += 1;
+ return allMatched;
+ });
+ }
+ return allMatched;
}
bool failWithDescription(Map<dynamic, dynamic> matchState, String description) {
diff --git a/packages/flutter_test/lib/src/widget_tester.dart b/packages/flutter_test/lib/src/widget_tester.dart
index bcdee59..bac856f 100644
--- a/packages/flutter_test/lib/src/widget_tester.dart
+++ b/packages/flutter_test/lib/src/widget_tester.dart
@@ -617,15 +617,39 @@
});
}
- /// Attempts to find the [SemanticsData] of first result from `finder`.
+ /// Attempts to find the [SemanticsNode] of first result from `finder`.
///
/// If the object identified by the finder doesn't own it's semantic node,
- /// this will return the semantics data of the first ancestor with semantics
- /// data. The ancestor's semantic data will include the child's as well as
+ /// this will return the semantics data of the first ancestor with semantics.
+ /// The ancestor's semantic data will include the child's as well as
/// other nodes that have been merged together.
///
/// Will throw a [StateError] if the finder returns more than one element or
/// if no semantics are found or are not enabled.
+ SemanticsNode getSemantics(Finder finder) {
+ if (binding.pipelineOwner.semanticsOwner == null)
+ throw StateError('Semantics are not enabled.');
+ final Iterable<Element> candidates = finder.evaluate();
+ if (candidates.isEmpty) {
+ throw StateError('Finder returned no matching elements.');
+ }
+ if (candidates.length > 1) {
+ throw StateError('Finder returned more than one element.');
+ }
+ final Element element = candidates.single;
+ RenderObject renderObject = element.findRenderObject();
+ SemanticsNode result = renderObject.debugSemantics;
+ while (renderObject != null && result == null) {
+ renderObject = renderObject?.parent;
+ result = renderObject?.debugSemantics;
+ }
+ if (result == null)
+ throw StateError('No Semantics data found.');
+ return result;
+ }
+
+ /// DEPRECATED: use [getSemantics] instead.
+ @Deprecated('use getSemantics instead')
SemanticsData getSemanticsData(Finder finder) {
if (binding.pipelineOwner.semanticsOwner == null)
throw StateError('Semantics are not enabled.');
diff --git a/packages/flutter_test/test/matchers_test.dart b/packages/flutter_test/test/matchers_test.dart
index 166ef1c..334247f 100644
--- a/packages/flutter_test/test/matchers_test.dart
+++ b/packages/flutter_test/test/matchers_test.dart
@@ -409,8 +409,8 @@
},
));
- expect(tester.getSemanticsData(find.byKey(key)),
- matchesSemanticsData(
+ expect(tester.getSemantics(find.byKey(key)),
+ matchesSemantics(
label: 'foo',
hint: 'bar',
value: 'baz',
@@ -432,8 +432,8 @@
);
// Doesn't match custom actions
- expect(tester.getSemanticsData(find.byKey(key)),
- isNot(matchesSemanticsData(
+ expect(tester.getSemantics(find.byKey(key)),
+ isNot(matchesSemantics(
label: 'foo',
hint: 'bar',
value: 'baz',
@@ -453,8 +453,8 @@
);
// Doesn't match wrong hints
- expect(tester.getSemanticsData(find.byKey(key)),
- isNot(matchesSemanticsData(
+ expect(tester.getSemantics(find.byKey(key)),
+ isNot(matchesSemantics(
label: 'foo',
hint: 'bar',
value: 'baz',
@@ -500,8 +500,10 @@
scrollExtentMin: null,
customSemanticsActionIds: <int>[CustomSemanticsAction.getIdentifier(action)],
);
+ final _FakeSemanticsNode node = _FakeSemanticsNode();
+ node.data = data;
- expect(data, matchesSemanticsData(
+ expect(node, matchesSemantics(
rect: Rect.fromLTRB(0.0, 0.0, 10.0, 10.0),
size: const Size(10.0, 10.0),
/* Flags */
@@ -548,6 +550,35 @@
customActions: <CustomSemanticsAction>[action],
));
});
+
+ testWidgets('Can match child semantics', (WidgetTester tester) async {
+ final SemanticsHandle handle = tester.ensureSemantics();
+ const Key key = Key('a');
+ await tester.pumpWidget(Semantics(
+ key: key,
+ label: 'Foo',
+ container: true,
+ explicitChildNodes: true,
+ textDirection: TextDirection.ltr,
+ child: Semantics(
+ label: 'Bar',
+ textDirection: TextDirection.ltr,
+ ),
+ ));
+ final SemanticsNode node = tester.getSemantics(find.byKey(key));
+
+ expect(node, matchesSemantics(
+ label: 'Foo',
+ textDirection: TextDirection.ltr,
+ children: <Matcher>[
+ matchesSemantics(
+ label: 'Bar',
+ textDirection: TextDirection.ltr,
+ ),
+ ],
+ ));
+ handle.dispose();
+ });
});
}
@@ -592,3 +623,9 @@
return Future<void>.value();
}
}
+
+class _FakeSemanticsNode extends SemanticsNode {
+ SemanticsData data;
+ @override
+ SemanticsData getSemanticsData() => data;
+}
\ No newline at end of file
diff --git a/packages/flutter_test/test/widget_tester_test.dart b/packages/flutter_test/test/widget_tester_test.dart
index 9249398..e37ef47 100644
--- a/packages/flutter_test/test/widget_tester_test.dart
+++ b/packages/flutter_test/test/widget_tester_test.dart
@@ -540,7 +540,7 @@
),
);
- expect(() => tester.getSemanticsData(find.text('hello')),
+ expect(() => tester.getSemantics(find.text('hello')),
throwsA(isInstanceOf<StateError>()));
});
@@ -560,7 +560,7 @@
),
);
- expect(() => tester.getSemanticsData(find.text('hello')),
+ expect(() => tester.getSemantics(find.text('hello')),
throwsA(isInstanceOf<StateError>()));
semanticsHandle.dispose();
});
@@ -581,7 +581,8 @@
),
);
- final SemanticsData semantics = tester.getSemanticsData(find.text('hello'));
+ final SemanticsNode node = tester.getSemantics(find.text('hello'));
+ final SemanticsData semantics = node.getSemanticsData();
expect(semantics.label, 'hello');
expect(semantics.hasAction(SemanticsAction.tap), true);
expect(semantics.hasFlag(SemanticsFlag.isButton), true);
@@ -609,7 +610,8 @@
),
);
- final SemanticsData semantics = tester.getSemanticsData(find.byKey(key));
+ final SemanticsNode node = tester.getSemantics(find.byKey(key));
+ final SemanticsData semantics = node.getSemanticsData();
expect(semantics.label, 'A\nB\nC');
semanticsHandle.dispose();
});