Unverified Commit d00fe8fa authored by auto-submit[bot]'s avatar auto-submit[bot] Committed by GitHub

Reverts "Fix and test SemanticsController.simulatedAccessibilityTraversal (#143386)" (#143523)

Reverts flutter/flutter#143386

Initiated by: Piinks

Reason for reverting: This broke a customer test.

Original PR Author: Piinks

Reviewed By: {goderbauer}

This change reverts the following previous change:
Original Description:
Fixes https://github.com/flutter/flutter/issues/143173

The `start` and `end` parameters of `SemanticsController.simulatedAccessibilityTraversal` were deprecated in https://github.com/flutter/flutter/issues/112413, but no tests were added that verified the new API. 😳

This change
- fixes a typo in an error message
- fixes the new `startNode` and `endNode` not being accounted for in setting the traversal range
- adds dart fixes for the deprecations
- adds tests for the new API that is meant to replace the deprecated one.
  - Filed https://github.com/flutter/flutter/issues/143405 to follow up on the new API not working in multiple views.
parent c0778318
# Copyright 2014 The Flutter Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
# For details regarding the *Flutter Fix* feature, see
# https://flutter.dev/docs/development/tools/flutter-fix
# Please add new fixes to the top of the file, separated by one blank line
# from other fixes. In a comment, include a link to the PR where the change
# requiring the fix was made.
# Every fix must be tested. See the
# flutter/packages/flutter_test/test_fixes/README.md file for instructions
# on testing these data driven fixes.
# For documentation about this file format, see
# https://dart.dev/go/data-driven-fixes.
# * Fixes in this file are for the flutter_test/controller.dart file. *
version: 1
transforms:
# Changes made in TBD
- title: "Migrate to startNode and endNode."
date: 2024-02-13
element:
uris: [ 'flutter_test.dart' ]
method: simulatedAccessibilityTraversal
inClass: SemanticsController
oneOf:
- if: "start != '' && end != ''"
changes:
- kind: 'addParameter'
index: 2
name: 'startNode'
style: optional_named
argumentValue:
expression: '{% start %}'
requiredIf: "start != '' && end != ''"
- kind: 'addParameter'
index: 3
name: 'endNode'
style: optional_named
argumentValue:
expression: '{% end %}'
requiredIf: "start != '' && end != ''"
- kind: 'removeParameter'
name: 'start'
- kind: 'removeParameter'
name: 'end'
- if: "start != '' && end == ''"
changes:
- kind: 'addParameter'
index: 2
name: 'startNode'
style: optional_named
argumentValue:
expression: '{% start %}'
requiredIf: "start != '' && end == ''"
- kind: 'removeParameter'
name: 'start'
- if: "start == '' && end != ''"
changes:
- kind: 'addParameter'
index: 2
name: 'endNode'
style: optional_named
argumentValue:
expression: '{% end %}'
requiredIf: "start == '' && end != ''"
- kind: 'removeParameter'
name: 'end'
variables:
start:
kind: 'fragment'
value: 'arguments[start]'
end:
kind: 'fragment'
value: 'arguments[end]'
...@@ -183,14 +183,8 @@ class SemanticsController { ...@@ -183,14 +183,8 @@ class SemanticsController {
FlutterView? view, FlutterView? view,
}) { }) {
TestAsyncUtils.guardSync(); TestAsyncUtils.guardSync();
assert( assert(start == null || startNode == null, 'Cannot provide both start and startNode. Prefer startNode as start is deprecated.');
start == null || startNode == null, assert(end == null || endNode == null, 'Cannot provide both end and endNode. Prefer endNode as end is deprecated.');
'Cannot provide both start and startNode. Prefer startNode as start is deprecated.',
);
assert(
end == null || endNode == null,
'Cannot provide both end and endNode. Prefer endNode as end is deprecated.',
);
FlutterView? startView; FlutterView? startView;
if (start != null) { if (start != null) {
...@@ -203,7 +197,8 @@ class SemanticsController { ...@@ -203,7 +197,8 @@ class SemanticsController {
'Specified view: $view' 'Specified view: $view'
); );
} }
} else if (startNode != null) { }
if (startNode != null) {
final SemanticsOwner owner = startNode.evaluate().single.owner!; final SemanticsOwner owner = startNode.evaluate().single.owner!;
final RenderView renderView = _controller.binding.renderViews.firstWhere( final RenderView renderView = _controller.binding.renderViews.firstWhere(
(RenderView render) => render.owner!.semanticsOwner == owner, (RenderView render) => render.owner!.semanticsOwner == owner,
...@@ -211,9 +206,9 @@ class SemanticsController { ...@@ -211,9 +206,9 @@ class SemanticsController {
startView = renderView.flutterView; startView = renderView.flutterView;
if (view != null && startView != view) { if (view != null && startView != view) {
throw StateError( throw StateError(
'The start node is not part of the provided view.\n' 'The end node is not part of the provided view.\n'
'Finder: ${startNode.toString(describeSelf: true)}\n' 'Finder: ${startNode.toString(describeSelf: true)}\n'
'View of start node: $startView\n' 'View of end node: $startView\n'
'Specified view: $view' 'Specified view: $view'
); );
} }
...@@ -230,7 +225,8 @@ class SemanticsController { ...@@ -230,7 +225,8 @@ class SemanticsController {
'Specified view: $view' 'Specified view: $view'
); );
} }
} else if (endNode != null) { }
if (endNode != null) {
final SemanticsOwner owner = endNode.evaluate().single.owner!; final SemanticsOwner owner = endNode.evaluate().single.owner!;
final RenderView renderView = _controller.binding.renderViews.firstWhere( final RenderView renderView = _controller.binding.renderViews.firstWhere(
(RenderView render) => render.owner!.semanticsOwner == owner, (RenderView render) => render.owner!.semanticsOwner == owner,
...@@ -265,49 +261,32 @@ class SemanticsController { ...@@ -265,49 +261,32 @@ class SemanticsController {
traversal, traversal,
); );
// Setting the range int startIndex = 0;
SemanticsNode? node; int endIndex = traversal.length - 1;
String? errorString;
int startIndex;
if (start != null) { if (start != null) {
node = find(start); final SemanticsNode startNode = find(start);
startIndex = traversal.indexOf(node); startIndex = traversal.indexOf(startNode);
errorString = start.toString(describeSelf: true);
} else if (startNode != null) {
node = startNode.evaluate().single;
startIndex = traversal.indexOf(node);
errorString = startNode.toString(describeSelf: true);
} else {
startIndex = 0;
}
if (startIndex == -1) { if (startIndex == -1) {
throw StateError( throw StateError(
'The expected starting node was not found.\n' 'The expected starting node was not found.\n'
'Finder: $errorString\n\n' 'Finder: ${start.toString(describeSelf: true)}\n\n'
'Expected Start Node: $node\n\n' 'Expected Start Node: $startNode\n\n'
'Traversal: [\n ${traversal.join('\n ')}\n]'); 'Traversal: [\n ${traversal.join('\n ')}\n]');
} }
}
int endIndex;
if (end != null) { if (end != null) {
node = find(end); final SemanticsNode endNode = find(end);
endIndex = traversal.indexOf(node); endIndex = traversal.indexOf(endNode);
errorString = end.toString(describeSelf: true);
} else if (endNode != null) {
node = endNode.evaluate().single;
endIndex = traversal.indexOf(node);
errorString = endNode.toString(describeSelf: true);
} else {
endIndex = traversal.length - 1;
}
if (endIndex == -1) { if (endIndex == -1) {
throw StateError( throw StateError(
'The expected ending node was not found.\n' 'The expected ending node was not found.\n'
'Finder: $errorString\n\n' 'Finder: ${end.toString(describeSelf: true)}\n\n'
'Expected End Node: $node\n\n' 'Expected End Node: $endNode\n\n'
'Traversal: [\n ${traversal.join('\n ')}\n]'); 'Traversal: [\n ${traversal.join('\n ')}\n]');
} }
}
return traversal.getRange(startIndex, endIndex + 1); return traversal.getRange(startIndex, endIndex + 1);
} }
......
...@@ -920,30 +920,6 @@ void main() { ...@@ -920,30 +920,6 @@ void main() {
orderedEquals(expectedMatchers)); orderedEquals(expectedMatchers));
}); });
testWidgets('starts traversal at semantics node for `startNode`', (WidgetTester tester) async {
await tester.pumpWidget(MaterialApp(
home: Center(
child: Column(
children: <Widget>[
for (int c = 0; c < 5; c++)
Semantics(container: true, child: Text('Child$c')),
]
),
),
));
expect(
tester.semantics.simulatedAccessibilityTraversal(
startNode: find.semantics.byLabel('Child1'),
).map((SemanticsNode node) => node.label),
<String>[
'Child1',
'Child2',
'Child3',
'Child4',
],
);
});
testWidgets('throws StateError if `start` not found in traversal', (WidgetTester tester) async { testWidgets('throws StateError if `start` not found in traversal', (WidgetTester tester) async {
await tester.pumpWidget(const MaterialApp(home: _SemanticsTestWidget())); await tester.pumpWidget(const MaterialApp(home: _SemanticsTestWidget()));
...@@ -955,23 +931,6 @@ void main() { ...@@ -955,23 +931,6 @@ void main() {
); );
}); });
testWidgets('throws StateError if `startNode` not found in traversal', (WidgetTester tester) async {
await tester.pumpWidget(MaterialApp(
home: Center(
child: Column(
children: <Widget>[
for (int c = 0; c < 5; c++)
Semantics(container: true, child: Text('Child$c')),
]
),
),
));
expect(
() => tester.semantics.simulatedAccessibilityTraversal(startNode: find.semantics.byLabel('Child20')),
throwsA(isA<StateError>()),
);
});
testWidgets('ends traversal at semantics node for `end`', (WidgetTester tester) async { testWidgets('ends traversal at semantics node for `end`', (WidgetTester tester) async {
await tester.pumpWidget(const MaterialApp(home: _SemanticsTestWidget())); await tester.pumpWidget(const MaterialApp(home: _SemanticsTestWidget()));
...@@ -983,28 +942,6 @@ void main() { ...@@ -983,28 +942,6 @@ void main() {
orderedEquals(expectedMatchers)); orderedEquals(expectedMatchers));
}); });
testWidgets('ends traversal at semantics node for `endNode`', (WidgetTester tester) async {
await tester.pumpWidget(MaterialApp(
home: Center(
child: Column(
children: <Widget>[
for (int c = 0; c < 5; c++)
Semantics(container: true, child: Text('Child$c')),
]
),
),
));
expect(
tester.semantics.simulatedAccessibilityTraversal(
endNode: find.semantics.byLabel('Child1'),
).map((SemanticsNode node) => node.label),
<String>[
'Child0',
'Child1',
],
);
});
testWidgets('throws StateError if `end` not found in traversal', (WidgetTester tester) async { testWidgets('throws StateError if `end` not found in traversal', (WidgetTester tester) async {
await tester.pumpWidget(const MaterialApp(home: _SemanticsTestWidget())); await tester.pumpWidget(const MaterialApp(home: _SemanticsTestWidget()));
...@@ -1016,23 +953,6 @@ void main() { ...@@ -1016,23 +953,6 @@ void main() {
); );
}); });
testWidgets('throws StateError if `endNode` not found in traversal', (WidgetTester tester) async {
await tester.pumpWidget(MaterialApp(
home: Center(
child: Column(
children: <Widget>[
for (int c = 0; c < 5; c++)
Semantics(container: true, child: Text('Child$c')),
]
),
),
));
expect(
() => tester.semantics.simulatedAccessibilityTraversal(endNode: find.semantics.byLabel('Child20')),
throwsA(isA<StateError>()),
);
});
testWidgets('returns traversal between `start` and `end` if both are provided', (WidgetTester tester) async { testWidgets('returns traversal between `start` and `end` if both are provided', (WidgetTester tester) async {
await tester.pumpWidget(const MaterialApp(home: _SemanticsTestWidget())); await tester.pumpWidget(const MaterialApp(home: _SemanticsTestWidget()));
...@@ -1047,30 +967,6 @@ void main() { ...@@ -1047,30 +967,6 @@ void main() {
orderedEquals(expectedMatchers)); orderedEquals(expectedMatchers));
}); });
testWidgets('returns traversal between `startNode` and `endNode` if both are provided', (WidgetTester tester) async {
await tester.pumpWidget(MaterialApp(
home: Center(
child: Column(
children: <Widget>[
for (int c = 0; c < 5; c++)
Semantics(container: true, child: Text('Child$c')),
]
),
),
));
expect(
tester.semantics.simulatedAccessibilityTraversal(
startNode: find.semantics.byLabel('Child1'),
endNode: find.semantics.byLabel('Child3'),
).map((SemanticsNode node) => node.label),
<String>[
'Child1',
'Child2',
'Child3',
],
);
});
testWidgets('can do fuzzy traversal match with `containsAllInOrder`', (WidgetTester tester) async { testWidgets('can do fuzzy traversal match with `containsAllInOrder`', (WidgetTester tester) async {
await tester.pumpWidget(const MaterialApp(home: _SemanticsTestWidget())); await tester.pumpWidget(const MaterialApp(home: _SemanticsTestWidget()));
......
// Copyright 2014 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'package:flutter_test/flutter_test.dart';
void main() {
// Generic reference variables.
finders.FinderBase<Element> theStart;
finders.FinderBase<Element> theEnd;
testWidgets('simulatedAccessibilityTraversal', (WidgetTester tester) async {
// Changes made in https://github.com/flutter/flutter/pull/143386
tester.semantics.simulatedAccessibilityTraversal();
tester.semantics.simulatedAccessibilityTraversal(start: theStart);
tester.semantics.simulatedAccessibilityTraversal(end: theEnd);
tester.semantics.simulatedAccessibilityTraversal(start: theStart, end: theEnd);
});
}
// Copyright 2014 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'package:flutter_test/flutter_test.dart';
void main() {
// Generic reference variables.
finders.FinderBase<Element> theStart;
finders.FinderBase<Element> theEnd;
testWidgets('simulatedAccessibilityTraversal', (WidgetTester tester) async {
// Changes made in https://github.com/flutter/flutter/pull/143386
tester.semantics.simulatedAccessibilityTraversal();
tester.semantics.simulatedAccessibilityTraversal(startNode: theStart);
tester.semantics.simulatedAccessibilityTraversal(endNode: theEnd);
tester.semantics.simulatedAccessibilityTraversal(startNode: theStart, endNode: theEnd);
});
}
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