Unverified Commit 948523b8 authored by Bartek Pacia's avatar Bartek Pacia Committed by GitHub

Add accessibility identifier to `SemanticsProperties` (#138331)

This PR adds `String? identifier` to `Semantics` and `SemanticsProperties`. The `identifier` will be exposed on Android as `resource-id` and on iOS as `accessibilityIdentifier`.

Mainly targeted at #17988

Initial Engine PR with Android support: https://github.com/flutter/engine/pull/47961
iOS Engine PR: https://github.com/flutter/engine/pull/48858

### Migration

This change breaks the SemanticsUpdateBuilder API which is on the Framework<-->Engine border. For more details see [engine PR](https://github.com/flutter/engine/pull/47961).

Steps:
part 1: [engine] add `SemanticsUpdateBuilderNew` https://github.com/flutter/engine/pull/47961
**part 2: [flutter] use `SemanticsUpdateBuilderNew`**  <-- we are here
part 3: [engine] update `SemanticsUpdateBuilder` to be the same as `SemanticsUpdateBuilderNew`*
part 4: [flutter] use (now updated) `SemanticsUpdateBuilder` again.
part 5: [engine] remove `SemanticsBuilderNew`
parent 4252aa0f
...@@ -4356,6 +4356,9 @@ class RenderSemanticsAnnotations extends RenderProxyBox { ...@@ -4356,6 +4356,9 @@ class RenderSemanticsAnnotations extends RenderProxyBox {
if (_properties.image != null) { if (_properties.image != null) {
config.isImage = _properties.image!; config.isImage = _properties.image!;
} }
if (_properties.identifier != null) {
config.identifier = _properties.identifier!;
}
if (_attributedLabel != null) { if (_attributedLabel != null) {
config.attributedLabel = _attributedLabel!; config.attributedLabel = _attributedLabel!;
} }
......
...@@ -2,14 +2,16 @@ ...@@ -2,14 +2,16 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
import 'dart:ui' as ui show AccessibilityFeatures, SemanticsActionEvent, SemanticsUpdateBuilder; // ignore: deprecated_member_use
import 'dart:ui' as ui show AccessibilityFeatures, SemanticsActionEvent, SemanticsUpdateBuilderNew;
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import 'debug.dart'; import 'debug.dart';
export 'dart:ui' show AccessibilityFeatures, SemanticsActionEvent, SemanticsUpdateBuilder; // ignore: deprecated_member_use
export 'dart:ui' show AccessibilityFeatures, SemanticsActionEvent, SemanticsUpdateBuilderNew;
/// The glue between the semantics layer and the Flutter engine. /// The glue between the semantics layer and the Flutter engine.
mixin SemanticsBinding on BindingBase { mixin SemanticsBinding on BindingBase {
...@@ -160,8 +162,10 @@ mixin SemanticsBinding on BindingBase { ...@@ -160,8 +162,10 @@ mixin SemanticsBinding on BindingBase {
/// ///
/// This method is used by the [SemanticsOwner] to create builder for all its /// This method is used by the [SemanticsOwner] to create builder for all its
/// semantics updates. /// semantics updates.
ui.SemanticsUpdateBuilder createSemanticsUpdateBuilder() { // ignore: deprecated_member_use
return ui.SemanticsUpdateBuilder(); ui.SemanticsUpdateBuilderNew createSemanticsUpdateBuilder() {
// ignore: deprecated_member_use
return ui.SemanticsUpdateBuilderNew();
} }
/// The platform is requesting that animations be disabled or simplified. /// The platform is requesting that animations be disabled or simplified.
......
...@@ -3,7 +3,8 @@ ...@@ -3,7 +3,8 @@
// found in the LICENSE file. // found in the LICENSE file.
import 'dart:math' as math; import 'dart:math' as math;
import 'dart:ui' show Offset, Rect, SemanticsAction, SemanticsFlag, SemanticsUpdate, SemanticsUpdateBuilder, StringAttribute, TextDirection; // ignore: deprecated_member_use
import 'dart:ui' show Offset, Rect, SemanticsAction, SemanticsFlag, SemanticsUpdate, SemanticsUpdateBuilderNew, StringAttribute, TextDirection;
import 'package:collection/collection.dart'; import 'package:collection/collection.dart';
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
...@@ -426,6 +427,7 @@ class SemanticsData with Diagnosticable { ...@@ -426,6 +427,7 @@ class SemanticsData with Diagnosticable {
SemanticsData({ SemanticsData({
required this.flags, required this.flags,
required this.actions, required this.actions,
required this.identifier,
required this.attributedLabel, required this.attributedLabel,
required this.attributedValue, required this.attributedValue,
required this.attributedIncreasedValue, required this.attributedIncreasedValue,
...@@ -461,6 +463,9 @@ class SemanticsData with Diagnosticable { ...@@ -461,6 +463,9 @@ class SemanticsData with Diagnosticable {
/// A bit field of [SemanticsAction]s that apply to this node. /// A bit field of [SemanticsAction]s that apply to this node.
final int actions; final int actions;
/// {@macro flutter.semantics.SemanticsProperties.identifier}
final String identifier;
/// A textual description for the current label of the node. /// A textual description for the current label of the node.
/// ///
/// The reading direction is given by [textDirection]. /// The reading direction is given by [textDirection].
...@@ -696,6 +701,7 @@ class SemanticsData with Diagnosticable { ...@@ -696,6 +701,7 @@ class SemanticsData with Diagnosticable {
flag.name, flag.name,
]; ];
properties.add(IterableProperty<String>('flags', flagSummary, ifEmpty: null)); properties.add(IterableProperty<String>('flags', flagSummary, ifEmpty: null));
properties.add(StringProperty('identifier', identifier, defaultValue: ''));
properties.add(AttributedStringProperty('label', attributedLabel)); properties.add(AttributedStringProperty('label', attributedLabel));
properties.add(AttributedStringProperty('value', attributedValue)); properties.add(AttributedStringProperty('value', attributedValue));
properties.add(AttributedStringProperty('increasedValue', attributedIncreasedValue)); properties.add(AttributedStringProperty('increasedValue', attributedIncreasedValue));
...@@ -721,6 +727,7 @@ class SemanticsData with Diagnosticable { ...@@ -721,6 +727,7 @@ class SemanticsData with Diagnosticable {
return other is SemanticsData return other is SemanticsData
&& other.flags == flags && other.flags == flags
&& other.actions == actions && other.actions == actions
&& other.identifier == identifier
&& other.attributedLabel == attributedLabel && other.attributedLabel == attributedLabel
&& other.attributedValue == attributedValue && other.attributedValue == attributedValue
&& other.attributedIncreasedValue == attributedIncreasedValue && other.attributedIncreasedValue == attributedIncreasedValue
...@@ -749,6 +756,7 @@ class SemanticsData with Diagnosticable { ...@@ -749,6 +756,7 @@ class SemanticsData with Diagnosticable {
int get hashCode => Object.hash( int get hashCode => Object.hash(
flags, flags,
actions, actions,
identifier,
attributedLabel, attributedLabel,
attributedValue, attributedValue,
attributedIncreasedValue, attributedIncreasedValue,
...@@ -765,8 +773,8 @@ class SemanticsData with Diagnosticable { ...@@ -765,8 +773,8 @@ class SemanticsData with Diagnosticable {
scrollExtentMax, scrollExtentMax,
scrollExtentMin, scrollExtentMin,
platformViewId, platformViewId,
maxValueLength,
Object.hash( Object.hash(
maxValueLength,
currentValueLength, currentValueLength,
transform, transform,
elevation, elevation,
...@@ -901,6 +909,7 @@ class SemanticsProperties extends DiagnosticableTree { ...@@ -901,6 +909,7 @@ class SemanticsProperties extends DiagnosticableTree {
this.liveRegion, this.liveRegion,
this.maxValueLength, this.maxValueLength,
this.currentValueLength, this.currentValueLength,
this.identifier,
this.label, this.label,
this.attributedLabel, this.attributedLabel,
this.value, this.value,
...@@ -1165,6 +1174,21 @@ class SemanticsProperties extends DiagnosticableTree { ...@@ -1165,6 +1174,21 @@ class SemanticsProperties extends DiagnosticableTree {
/// [maxValueLength] is set. /// [maxValueLength] is set.
final int? currentValueLength; final int? currentValueLength;
/// {@template flutter.semantics.SemanticsProperties.identifier}
/// Provides an identifier for the semantics node in native accessibility hierarchy.
///
/// This value is not exposed to the users of the app.
///
/// It's usually used for UI testing with tools that work by querying the
/// native accessibility, like UIAutomator, XCUITest, or Appium.
///
/// On Android, this is used for `AccessibilityNodeInfo.setViewIdResourceName`.
/// It'll be appear in accessibility hierarchy as `resource-id`.
///
/// On iOS, this will set `UIAccessibilityElement.accessibilityIdentifier`.
/// {@endtemplate}
final String? identifier;
/// Provides a textual description of the widget. /// Provides a textual description of the widget.
/// ///
/// If a label is provided, there must either by an ambient [Directionality] /// If a label is provided, there must either by an ambient [Directionality]
...@@ -1632,6 +1656,7 @@ class SemanticsProperties extends DiagnosticableTree { ...@@ -1632,6 +1656,7 @@ class SemanticsProperties extends DiagnosticableTree {
properties.add(DiagnosticsProperty<bool>('mixed', mixed, defaultValue: null)); properties.add(DiagnosticsProperty<bool>('mixed', mixed, defaultValue: null));
properties.add(DiagnosticsProperty<bool>('expanded', expanded, defaultValue: null)); properties.add(DiagnosticsProperty<bool>('expanded', expanded, defaultValue: null));
properties.add(DiagnosticsProperty<bool>('selected', selected, defaultValue: null)); properties.add(DiagnosticsProperty<bool>('selected', selected, defaultValue: null));
properties.add(StringProperty('identifier', identifier));
properties.add(StringProperty('label', label, defaultValue: null)); properties.add(StringProperty('label', label, defaultValue: null));
properties.add(AttributedStringProperty('attributedLabel', attributedLabel, defaultValue: null)); properties.add(AttributedStringProperty('attributedLabel', attributedLabel, defaultValue: null));
properties.add(StringProperty('value', value, defaultValue: null)); properties.add(StringProperty('value', value, defaultValue: null));
...@@ -2210,6 +2235,10 @@ class SemanticsNode with DiagnosticableTreeMixin { ...@@ -2210,6 +2235,10 @@ class SemanticsNode with DiagnosticableTreeMixin {
/// Whether this node currently has a given [SemanticsFlag]. /// Whether this node currently has a given [SemanticsFlag].
bool hasFlag(SemanticsFlag flag) => _flags & flag.index != 0; bool hasFlag(SemanticsFlag flag) => _flags & flag.index != 0;
/// {@macro flutter.semantics.SemanticsProperties.identifier}
String get identifier => _identifier;
String _identifier = _kEmptyConfig.identifier;
/// A textual description of this node. /// A textual description of this node.
/// ///
/// The reading direction is given by [textDirection]. /// The reading direction is given by [textDirection].
...@@ -2514,6 +2543,7 @@ class SemanticsNode with DiagnosticableTreeMixin { ...@@ -2514,6 +2543,7 @@ class SemanticsNode with DiagnosticableTreeMixin {
final bool mergeAllDescendantsIntoThisNodeValueChanged = _mergeAllDescendantsIntoThisNode != config.isMergingSemanticsOfDescendants; final bool mergeAllDescendantsIntoThisNodeValueChanged = _mergeAllDescendantsIntoThisNode != config.isMergingSemanticsOfDescendants;
_identifier = config.identifier;
_attributedLabel = config.attributedLabel; _attributedLabel = config.attributedLabel;
_attributedValue = config.attributedValue; _attributedValue = config.attributedValue;
_attributedIncreasedValue = config.attributedIncreasedValue; _attributedIncreasedValue = config.attributedIncreasedValue;
...@@ -2569,6 +2599,7 @@ class SemanticsNode with DiagnosticableTreeMixin { ...@@ -2569,6 +2599,7 @@ class SemanticsNode with DiagnosticableTreeMixin {
// Can't use _effectiveActionsAsBits here. The filtering of action bits // Can't use _effectiveActionsAsBits here. The filtering of action bits
// must be done after the merging the its descendants. // must be done after the merging the its descendants.
int actions = _actionsAsBits; int actions = _actionsAsBits;
String identifier = _identifier;
AttributedString attributedLabel = _attributedLabel; AttributedString attributedLabel = _attributedLabel;
AttributedString attributedValue = _attributedValue; AttributedString attributedValue = _attributedValue;
AttributedString attributedIncreasedValue = _attributedIncreasedValue; AttributedString attributedIncreasedValue = _attributedIncreasedValue;
...@@ -2625,6 +2656,9 @@ class SemanticsNode with DiagnosticableTreeMixin { ...@@ -2625,6 +2656,9 @@ class SemanticsNode with DiagnosticableTreeMixin {
platformViewId ??= node._platformViewId; platformViewId ??= node._platformViewId;
maxValueLength ??= node._maxValueLength; maxValueLength ??= node._maxValueLength;
currentValueLength ??= node._currentValueLength; currentValueLength ??= node._currentValueLength;
if (identifier == '') {
identifier = node._identifier;
}
if (attributedValue.string == '') { if (attributedValue.string == '') {
attributedValue = node._attributedValue; attributedValue = node._attributedValue;
} }
...@@ -2682,6 +2716,7 @@ class SemanticsNode with DiagnosticableTreeMixin { ...@@ -2682,6 +2716,7 @@ class SemanticsNode with DiagnosticableTreeMixin {
return SemanticsData( return SemanticsData(
flags: flags, flags: flags,
actions: _areUserActionsBlocked ? actions & _kUnblockedUserActions : actions, actions: _areUserActionsBlocked ? actions & _kUnblockedUserActions : actions,
identifier: identifier,
attributedLabel: attributedLabel, attributedLabel: attributedLabel,
attributedValue: attributedValue, attributedValue: attributedValue,
attributedIncreasedValue: attributedIncreasedValue, attributedIncreasedValue: attributedIncreasedValue,
...@@ -2715,7 +2750,8 @@ class SemanticsNode with DiagnosticableTreeMixin { ...@@ -2715,7 +2750,8 @@ class SemanticsNode with DiagnosticableTreeMixin {
static final Int32List _kEmptyCustomSemanticsActionsList = Int32List(0); static final Int32List _kEmptyCustomSemanticsActionsList = Int32List(0);
static final Float64List _kIdentityTransform = _initIdentityTransform(); static final Float64List _kIdentityTransform = _initIdentityTransform();
void _addToUpdate(SemanticsUpdateBuilder builder, Set<int> customSemanticsActionIdsUpdate) { // ignore: deprecated_member_use
void _addToUpdate(SemanticsUpdateBuilderNew builder, Set<int> customSemanticsActionIdsUpdate) {
assert(_dirty); assert(_dirty);
final SemanticsData data = getSemanticsData(); final SemanticsData data = getSemanticsData();
final Int32List childrenInTraversalOrder; final Int32List childrenInTraversalOrder;
...@@ -2750,6 +2786,7 @@ class SemanticsNode with DiagnosticableTreeMixin { ...@@ -2750,6 +2786,7 @@ class SemanticsNode with DiagnosticableTreeMixin {
flags: data.flags, flags: data.flags,
actions: data.actions, actions: data.actions,
rect: data.rect, rect: data.rect,
identifier: data.identifier,
label: data.attributedLabel.string, label: data.attributedLabel.string,
labelAttributes: data.attributedLabel.attributes, labelAttributes: data.attributedLabel.attributes,
value: data.attributedValue.string, value: data.attributedValue.string,
...@@ -2904,6 +2941,7 @@ class SemanticsNode with DiagnosticableTreeMixin { ...@@ -2904,6 +2941,7 @@ class SemanticsNode with DiagnosticableTreeMixin {
properties.add(IterableProperty<String>('flags', flags, ifEmpty: null)); properties.add(IterableProperty<String>('flags', flags, ifEmpty: null));
properties.add(FlagProperty('isInvisible', value: isInvisible, ifTrue: 'invisible')); properties.add(FlagProperty('isInvisible', value: isInvisible, ifTrue: 'invisible'));
properties.add(FlagProperty('isHidden', value: hasFlag(SemanticsFlag.isHidden), ifTrue: 'HIDDEN')); properties.add(FlagProperty('isHidden', value: hasFlag(SemanticsFlag.isHidden), ifTrue: 'HIDDEN'));
properties.add(StringProperty('identifier', _identifier, defaultValue: ''));
properties.add(AttributedStringProperty('label', _attributedLabel)); properties.add(AttributedStringProperty('label', _attributedLabel));
properties.add(AttributedStringProperty('value', _attributedValue)); properties.add(AttributedStringProperty('value', _attributedValue));
properties.add(AttributedStringProperty('increasedValue', _attributedIncreasedValue)); properties.add(AttributedStringProperty('increasedValue', _attributedIncreasedValue));
...@@ -3406,7 +3444,8 @@ class SemanticsOwner extends ChangeNotifier { ...@@ -3406,7 +3444,8 @@ class SemanticsOwner extends ChangeNotifier {
} }
} }
visitedNodes.sort((SemanticsNode a, SemanticsNode b) => a.depth - b.depth); visitedNodes.sort((SemanticsNode a, SemanticsNode b) => a.depth - b.depth);
final SemanticsUpdateBuilder builder = SemanticsBinding.instance.createSemanticsUpdateBuilder(); // ignore: deprecated_member_use
final SemanticsUpdateBuilderNew builder = SemanticsBinding.instance.createSemanticsUpdateBuilder();
for (final SemanticsNode node in visitedNodes) { for (final SemanticsNode node in visitedNodes) {
assert(node.parent?._dirty != true); // could be null (no parent) or false (not dirty) assert(node.parent?._dirty != true); // could be null (no parent) or false (not dirty)
// The _serialize() method marks the node as not dirty, and // The _serialize() method marks the node as not dirty, and
...@@ -4201,6 +4240,14 @@ class SemanticsConfiguration { ...@@ -4201,6 +4240,14 @@ class SemanticsConfiguration {
} }
} }
/// {@macro flutter.semantics.SemanticsProperties.identifier}
String get identifier => _identifier;
String _identifier = '';
set identifier(String identifier) {
_identifier = identifier;
_hasBeenAnnotated = true;
}
/// A textual description of the owning [RenderObject]. /// A textual description of the owning [RenderObject].
/// ///
/// Setting this attribute will override the [attributedLabel]. /// Setting this attribute will override the [attributedLabel].
...@@ -4898,6 +4945,9 @@ class SemanticsConfiguration { ...@@ -4898,6 +4945,9 @@ class SemanticsConfiguration {
textDirection ??= child.textDirection; textDirection ??= child.textDirection;
_sortKey ??= child._sortKey; _sortKey ??= child._sortKey;
if (_identifier == '') {
_identifier = child._identifier;
}
_attributedLabel = _concatAttributedString( _attributedLabel = _concatAttributedString(
thisAttributedString: _attributedLabel, thisAttributedString: _attributedLabel,
thisTextDirection: textDirection, thisTextDirection: textDirection,
...@@ -4938,6 +4988,7 @@ class SemanticsConfiguration { ...@@ -4938,6 +4988,7 @@ class SemanticsConfiguration {
.._isMergingSemanticsOfDescendants = _isMergingSemanticsOfDescendants .._isMergingSemanticsOfDescendants = _isMergingSemanticsOfDescendants
.._textDirection = _textDirection .._textDirection = _textDirection
.._sortKey = _sortKey .._sortKey = _sortKey
.._identifier = _identifier
.._attributedLabel = _attributedLabel .._attributedLabel = _attributedLabel
.._attributedIncreasedValue = _attributedIncreasedValue .._attributedIncreasedValue = _attributedIncreasedValue
.._attributedValue = _attributedValue .._attributedValue = _attributedValue
......
...@@ -7123,6 +7123,7 @@ class Semantics extends SingleChildRenderObjectWidget { ...@@ -7123,6 +7123,7 @@ class Semantics extends SingleChildRenderObjectWidget {
bool? expanded, bool? expanded,
int? maxValueLength, int? maxValueLength,
int? currentValueLength, int? currentValueLength,
String? identifier,
String? label, String? label,
AttributedString? attributedLabel, AttributedString? attributedLabel,
String? value, String? value,
...@@ -7191,6 +7192,7 @@ class Semantics extends SingleChildRenderObjectWidget { ...@@ -7191,6 +7192,7 @@ class Semantics extends SingleChildRenderObjectWidget {
liveRegion: liveRegion, liveRegion: liveRegion,
maxValueLength: maxValueLength, maxValueLength: maxValueLength,
currentValueLength: currentValueLength, currentValueLength: currentValueLength,
identifier: identifier,
label: label, label: label,
attributedLabel: attributedLabel, attributedLabel: attributedLabel,
value: value, value: value,
......
...@@ -682,6 +682,7 @@ void main() { ...@@ -682,6 +682,7 @@ void main() {
' flags: []\n' ' flags: []\n'
' invisible\n' ' invisible\n'
' isHidden: false\n' ' isHidden: false\n'
' identifier: ""\n'
' label: ""\n' ' label: ""\n'
' value: ""\n' ' value: ""\n'
' increasedValue: ""\n' ' increasedValue: ""\n'
...@@ -805,6 +806,7 @@ void main() { ...@@ -805,6 +806,7 @@ void main() {
' flags: []\n' ' flags: []\n'
' invisible\n' ' invisible\n'
' isHidden: false\n' ' isHidden: false\n'
' identifier: ""\n'
' label: ""\n' ' label: ""\n'
' value: ""\n' ' value: ""\n'
' increasedValue: ""\n' ' increasedValue: ""\n'
......
...@@ -157,6 +157,7 @@ void main() { ...@@ -157,6 +157,7 @@ void main() {
'Semantics(' 'Semantics('
'container: false, ' 'container: false, '
'properties: SemanticsProperties, ' 'properties: SemanticsProperties, '
'identifier: null, '// ignore: missing_whitespace_between_adjacent_strings
'attributedLabel: "label" [SpellOutStringAttribute(TextRange(start: 0, end: 5))], ' 'attributedLabel: "label" [SpellOutStringAttribute(TextRange(start: 0, end: 5))], '
'attributedValue: "value" [LocaleStringAttribute(TextRange(start: 0, end: 5), en-MX)], ' 'attributedValue: "value" [LocaleStringAttribute(TextRange(start: 0, end: 5), en-MX)], '
'attributedHint: "hint" [SpellOutStringAttribute(TextRange(start: 1, end: 2))], ' 'attributedHint: "hint" [SpellOutStringAttribute(TextRange(start: 1, end: 2))], '
...@@ -171,13 +172,16 @@ void main() { ...@@ -171,13 +172,16 @@ void main() {
class SemanticsUpdateTestBinding extends AutomatedTestWidgetsFlutterBinding { class SemanticsUpdateTestBinding extends AutomatedTestWidgetsFlutterBinding {
@override @override
ui.SemanticsUpdateBuilder createSemanticsUpdateBuilder() { // ignore: deprecated_member_use
ui.SemanticsUpdateBuilderNew createSemanticsUpdateBuilder() {
return SemanticsUpdateBuilderSpy(); return SemanticsUpdateBuilderSpy();
} }
} }
class SemanticsUpdateBuilderSpy extends Fake implements ui.SemanticsUpdateBuilder { // ignore: deprecated_member_use
final SemanticsUpdateBuilder _builder = ui.SemanticsUpdateBuilder(); class SemanticsUpdateBuilderSpy extends Fake implements ui.SemanticsUpdateBuilderNew {
// ignore: deprecated_member_use
final SemanticsUpdateBuilderNew _builder = ui.SemanticsUpdateBuilderNew();
static Map<int, SemanticsNodeUpdateObservation> observations = <int, SemanticsNodeUpdateObservation>{}; static Map<int, SemanticsNodeUpdateObservation> observations = <int, SemanticsNodeUpdateObservation>{};
...@@ -199,6 +203,7 @@ class SemanticsUpdateBuilderSpy extends Fake implements ui.SemanticsUpdateBuilde ...@@ -199,6 +203,7 @@ class SemanticsUpdateBuilderSpy extends Fake implements ui.SemanticsUpdateBuilde
required double elevation, required double elevation,
required double thickness, required double thickness,
required Rect rect, required Rect rect,
required String identifier,
required String label, required String label,
List<StringAttribute>? labelAttributes, List<StringAttribute>? labelAttributes,
required String value, required String value,
......
...@@ -624,6 +624,7 @@ AsyncMatcher matchesReferenceImage(ui.Image image) { ...@@ -624,6 +624,7 @@ AsyncMatcher matchesReferenceImage(ui.Image image) {
/// * [SemanticsController.find] under [WidgetTester.semantics], the tester method which retrieves semantics. /// * [SemanticsController.find] under [WidgetTester.semantics], the tester method which retrieves semantics.
/// * [containsSemantics], a similar matcher without default values for flags or actions. /// * [containsSemantics], a similar matcher without default values for flags or actions.
Matcher matchesSemantics({ Matcher matchesSemantics({
String? identifier,
String? label, String? label,
AttributedString? attributedLabel, AttributedString? attributedLabel,
String? hint, String? hint,
...@@ -701,6 +702,7 @@ Matcher matchesSemantics({ ...@@ -701,6 +702,7 @@ Matcher matchesSemantics({
List<Matcher>? children, List<Matcher>? children,
}) { }) {
return _MatchesSemanticsData( return _MatchesSemanticsData(
identifier: identifier,
label: label, label: label,
attributedLabel: attributedLabel, attributedLabel: attributedLabel,
hint: hint, hint: hint,
...@@ -808,6 +810,7 @@ Matcher matchesSemantics({ ...@@ -808,6 +810,7 @@ Matcher matchesSemantics({
/// * [SemanticsController.find] under [WidgetTester.semantics], the tester method which retrieves semantics. /// * [SemanticsController.find] under [WidgetTester.semantics], the tester method which retrieves semantics.
/// * [matchesSemantics], a similar matcher with default values for flags and actions. /// * [matchesSemantics], a similar matcher with default values for flags and actions.
Matcher containsSemantics({ Matcher containsSemantics({
String? identifier,
String? label, String? label,
AttributedString? attributedLabel, AttributedString? attributedLabel,
String? hint, String? hint,
...@@ -885,6 +888,7 @@ Matcher containsSemantics({ ...@@ -885,6 +888,7 @@ Matcher containsSemantics({
List<Matcher>? children, List<Matcher>? children,
}) { }) {
return _MatchesSemanticsData( return _MatchesSemanticsData(
identifier: identifier,
label: label, label: label,
attributedLabel: attributedLabel, attributedLabel: attributedLabel,
hint: hint, hint: hint,
...@@ -2207,6 +2211,7 @@ class _MatchesReferenceImage extends AsyncMatcher { ...@@ -2207,6 +2211,7 @@ class _MatchesReferenceImage extends AsyncMatcher {
class _MatchesSemanticsData extends Matcher { class _MatchesSemanticsData extends Matcher {
_MatchesSemanticsData({ _MatchesSemanticsData({
required this.identifier,
required this.label, required this.label,
required this.attributedLabel, required this.attributedLabel,
required this.hint, required this.hint,
...@@ -2344,6 +2349,7 @@ class _MatchesSemanticsData extends Matcher { ...@@ -2344,6 +2349,7 @@ class _MatchesSemanticsData extends Matcher {
onLongPressHint: onLongPressHint, onLongPressHint: onLongPressHint,
); );
final String? identifier;
final String? label; final String? label;
final AttributedString? attributedLabel; final AttributedString? attributedLabel;
final String? hint; final String? hint;
......
...@@ -663,6 +663,7 @@ void main() { ...@@ -663,6 +663,7 @@ void main() {
final SemanticsData data = SemanticsData( final SemanticsData data = SemanticsData(
flags: flags, flags: flags,
actions: actions, actions: actions,
identifier: 'i',
attributedLabel: AttributedString('a'), attributedLabel: AttributedString('a'),
attributedIncreasedValue: AttributedString('b'), attributedIncreasedValue: AttributedString('b'),
attributedValue: AttributedString('c'), attributedValue: AttributedString('c'),
...@@ -790,6 +791,7 @@ void main() { ...@@ -790,6 +791,7 @@ void main() {
link: true, link: true,
onTap: () { }, onTap: () { },
onLongPress: () { }, onLongPress: () { },
identifier: 'ident',
label: 'foo', label: 'foo',
hint: 'bar', hint: 'bar',
value: 'baz', value: 'baz',
...@@ -947,6 +949,7 @@ void main() { ...@@ -947,6 +949,7 @@ void main() {
final SemanticsData data = SemanticsData( final SemanticsData data = SemanticsData(
flags: flags, flags: flags,
actions: actions, actions: actions,
identifier: 'i',
attributedLabel: AttributedString('a'), attributedLabel: AttributedString('a'),
attributedIncreasedValue: AttributedString('b'), attributedIncreasedValue: AttributedString('b'),
attributedValue: AttributedString('c'), attributedValue: AttributedString('c'),
...@@ -1039,6 +1042,7 @@ void main() { ...@@ -1039,6 +1042,7 @@ void main() {
final SemanticsData data = SemanticsData( final SemanticsData data = SemanticsData(
flags: 0, flags: 0,
actions: 0, actions: 0,
identifier: 'i',
attributedLabel: AttributedString('a'), attributedLabel: AttributedString('a'),
attributedIncreasedValue: AttributedString('b'), attributedIncreasedValue: AttributedString('b'),
attributedValue: AttributedString('c'), attributedValue: AttributedString('c'),
...@@ -1137,6 +1141,7 @@ void main() { ...@@ -1137,6 +1141,7 @@ void main() {
final SemanticsData emptyData = SemanticsData( final SemanticsData emptyData = SemanticsData(
flags: 0, flags: 0,
actions: 0, actions: 0,
identifier: 'i',
attributedLabel: AttributedString('a'), attributedLabel: AttributedString('a'),
attributedIncreasedValue: AttributedString('b'), attributedIncreasedValue: AttributedString('b'),
attributedValue: AttributedString('c'), attributedValue: AttributedString('c'),
...@@ -1163,6 +1168,7 @@ void main() { ...@@ -1163,6 +1168,7 @@ void main() {
final SemanticsData fullData = SemanticsData( final SemanticsData fullData = SemanticsData(
flags: allFlags, flags: allFlags,
actions: allActions, actions: allActions,
identifier: 'i',
attributedLabel: AttributedString('a'), attributedLabel: AttributedString('a'),
attributedIncreasedValue: AttributedString('b'), attributedIncreasedValue: AttributedString('b'),
attributedValue: AttributedString('c'), attributedValue: AttributedString('c'),
...@@ -1252,6 +1258,7 @@ void main() { ...@@ -1252,6 +1258,7 @@ void main() {
final SemanticsData data = SemanticsData( final SemanticsData data = SemanticsData(
flags: 0, flags: 0,
actions: SemanticsAction.customAction.index, actions: SemanticsAction.customAction.index,
identifier: 'i',
attributedLabel: AttributedString('a'), attributedLabel: AttributedString('a'),
attributedIncreasedValue: AttributedString('b'), attributedIncreasedValue: AttributedString('b'),
attributedValue: AttributedString('c'), attributedValue: AttributedString('c'),
......
...@@ -313,7 +313,8 @@ void main() { ...@@ -313,7 +313,8 @@ void main() {
}); });
testWidgets('updateSemantics is passed through to backing FlutterView', (WidgetTester tester) async { testWidgets('updateSemantics is passed through to backing FlutterView', (WidgetTester tester) async {
final SemanticsUpdate expectedUpdate = SemanticsUpdateBuilder().build(); // ignore: deprecated_member_use
final SemanticsUpdate expectedUpdate = SemanticsUpdateBuilderNew().build();
final _FakeFlutterView backingView = _FakeFlutterView(); final _FakeFlutterView backingView = _FakeFlutterView();
final TestFlutterView view = TestFlutterView( final TestFlutterView view = TestFlutterView(
view: backingView, view: backingView,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment