Skip to content

Commit c71f1dd

Browse files
authored
Treat hidden IndexedStack children as offstage for test finder (#123129)
Treat hidden `IndexedStack` children as offstage for test finder
1 parent 42f61b3 commit c71f1dd

File tree

6 files changed

+164
-96
lines changed

6 files changed

+164
-96
lines changed

examples/api/test/material/dropdown/dropdown_button.style.0_test.dart

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,15 @@ void main() {
1616
),
1717
);
1818

19-
expect(find.text('One'), findsNWidgets(4));
19+
expect(find.text('One'), findsOneWidget);
20+
expect(find.text('One', skipOffstage: false), findsNWidgets(4));
2021

2122
await tester.tap(find.text('One').first);
2223
await tester.pumpAndSettle();
2324
expect(find.text('Two'), findsOneWidget);
2425
await tester.tap(find.text('Two'));
2526
await tester.pumpAndSettle();
26-
expect(find.text('Two'), findsNWidgets(4));
27+
expect(find.text('Two'), findsOneWidget);
28+
expect(find.text('Two', skipOffstage: false), findsNWidgets(4));
2729
});
2830
}

examples/api/test/widgets/basic/indexed_stack.0_test.dart

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,11 @@ void main() {
1111
await tester.pumpWidget(const example.IndexedStackApp());
1212

1313
final Finder gesture2 = find.byKey(const Key('gesture2'));
14-
final Element containerFinder = find.byKey(const Key('Dash')).evaluate().first;
14+
final Element containerFinder = find.byKey(const Key('Dash'), skipOffstage: false).evaluate().first;
1515
expect(containerFinder.renderObject!.debugNeedsPaint, false);
16-
final Element containerFinder1 = find.byKey(const Key('John')).evaluate().first;
16+
final Element containerFinder1 = find.byKey(const Key('John'), skipOffstage: false).evaluate().first;
1717
expect(containerFinder1.renderObject!.debugNeedsPaint, true);
18-
final Element containerFinder2 = find.byKey(const Key('Mary')).evaluate().first;
18+
final Element containerFinder2 = find.byKey(const Key('Mary'), skipOffstage: false).evaluate().first;
1919
expect(containerFinder2.renderObject!.debugNeedsPaint, true);
2020

2121
await tester.tap(gesture2);
@@ -34,9 +34,9 @@ void main() {
3434
await tester.pumpWidget(const example.IndexedStackApp());
3535

3636
final Finder gesture1 = find.byKey(const Key('gesture1'));
37-
final Element containerFinder = find.byKey(const Key('Dash')).evaluate().first;
38-
final Element containerFinder1 = find.byKey(const Key('John')).evaluate().first;
39-
final Element containerFinder2 = find.byKey(const Key('Mary')).evaluate().first;
37+
final Element containerFinder = find.byKey(const Key('Dash'), skipOffstage: false).evaluate().first;
38+
final Element containerFinder1 = find.byKey(const Key('John'), skipOffstage: false).evaluate().first;
39+
final Element containerFinder2 = find.byKey(const Key('Mary'), skipOffstage: false).evaluate().first;
4040

4141
await tester.tap(gesture1);
4242
await tester.pump();
@@ -53,17 +53,18 @@ void main() {
5353
testWidgets('has correct element addition handling', (WidgetTester tester) async {
5454
await tester.pumpWidget(const example.IndexedStackApp());
5555

56-
expect(find.byType(example.PersonTracker), findsNWidgets(3));
56+
expect(find.byType(example.PersonTracker), findsOneWidget);
57+
expect(find.byType(example.PersonTracker, skipOffstage: false), findsNWidgets(3));
5758
final Finder textField = find.byType(TextField);
5859
await tester.enterText(textField, 'hello');
5960
await tester.testTextInput.receiveAction(TextInputAction.done);
6061
await tester.pump();
61-
expect(find.byType(example.PersonTracker), findsNWidgets(4));
62+
expect(find.byType(example.PersonTracker, skipOffstage: false), findsNWidgets(4));
6263

6364
await tester.enterText(textField, 'hello1');
6465
await tester.testTextInput.receiveAction(TextInputAction.done);
6566
await tester.pump();
66-
expect(find.byType(example.PersonTracker), findsNWidgets(5));
67+
expect(find.byType(example.PersonTracker, skipOffstage: false), findsNWidgets(5));
6768
});
6869
testWidgets('has state preservation', (WidgetTester tester) async {
6970
await tester.pumpWidget(const example.IndexedStackApp());

packages/flutter/lib/src/widgets/basic.dart

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4075,6 +4075,28 @@ class _RawIndexedStack extends Stack {
40754075
..alignment = alignment
40764076
..textDirection = textDirection ?? Directionality.maybeOf(context);
40774077
}
4078+
4079+
@override
4080+
MultiChildRenderObjectElement createElement() {
4081+
return _IndexedStackElement(this);
4082+
}
4083+
}
4084+
4085+
class _IndexedStackElement extends MultiChildRenderObjectElement {
4086+
_IndexedStackElement(_RawIndexedStack super.widget);
4087+
4088+
@override
4089+
_RawIndexedStack get widget => super.widget as _RawIndexedStack;
4090+
4091+
@override
4092+
void debugVisitOnstageChildren(ElementVisitor visitor) {
4093+
final int? index = widget.index;
4094+
// If the index is null, no child is onstage. Otherwise, only the child at
4095+
// the selected index is.
4096+
if (index != null && children.isNotEmpty) {
4097+
visitor(children.elementAt(index));
4098+
}
4099+
}
40784100
}
40794101

40804102
/// A widget that controls where a child of a [Stack] is positioned.

0 commit comments

Comments
 (0)