Unverified Commit c71f1dd7 authored by Simon Binder's avatar Simon Binder Committed by GitHub

Treat hidden `IndexedStack` children as offstage for test finder (#123129)

Treat hidden `IndexedStack` children as offstage for test finder
parent 42f61b32
......@@ -16,13 +16,15 @@ void main() {
),
);
expect(find.text('One'), findsNWidgets(4));
expect(find.text('One'), findsOneWidget);
expect(find.text('One', skipOffstage: false), findsNWidgets(4));
await tester.tap(find.text('One').first);
await tester.pumpAndSettle();
expect(find.text('Two'), findsOneWidget);
await tester.tap(find.text('Two'));
await tester.pumpAndSettle();
expect(find.text('Two'), findsNWidgets(4));
expect(find.text('Two'), findsOneWidget);
expect(find.text('Two', skipOffstage: false), findsNWidgets(4));
});
}
......@@ -11,11 +11,11 @@ void main() {
await tester.pumpWidget(const example.IndexedStackApp());
final Finder gesture2 = find.byKey(const Key('gesture2'));
final Element containerFinder = find.byKey(const Key('Dash')).evaluate().first;
final Element containerFinder = find.byKey(const Key('Dash'), skipOffstage: false).evaluate().first;
expect(containerFinder.renderObject!.debugNeedsPaint, false);
final Element containerFinder1 = find.byKey(const Key('John')).evaluate().first;
final Element containerFinder1 = find.byKey(const Key('John'), skipOffstage: false).evaluate().first;
expect(containerFinder1.renderObject!.debugNeedsPaint, true);
final Element containerFinder2 = find.byKey(const Key('Mary')).evaluate().first;
final Element containerFinder2 = find.byKey(const Key('Mary'), skipOffstage: false).evaluate().first;
expect(containerFinder2.renderObject!.debugNeedsPaint, true);
await tester.tap(gesture2);
......@@ -34,9 +34,9 @@ void main() {
await tester.pumpWidget(const example.IndexedStackApp());
final Finder gesture1 = find.byKey(const Key('gesture1'));
final Element containerFinder = find.byKey(const Key('Dash')).evaluate().first;
final Element containerFinder1 = find.byKey(const Key('John')).evaluate().first;
final Element containerFinder2 = find.byKey(const Key('Mary')).evaluate().first;
final Element containerFinder = find.byKey(const Key('Dash'), skipOffstage: false).evaluate().first;
final Element containerFinder1 = find.byKey(const Key('John'), skipOffstage: false).evaluate().first;
final Element containerFinder2 = find.byKey(const Key('Mary'), skipOffstage: false).evaluate().first;
await tester.tap(gesture1);
await tester.pump();
......@@ -53,17 +53,18 @@ void main() {
testWidgets('has correct element addition handling', (WidgetTester tester) async {
await tester.pumpWidget(const example.IndexedStackApp());
expect(find.byType(example.PersonTracker), findsNWidgets(3));
expect(find.byType(example.PersonTracker), findsOneWidget);
expect(find.byType(example.PersonTracker, skipOffstage: false), findsNWidgets(3));
final Finder textField = find.byType(TextField);
await tester.enterText(textField, 'hello');
await tester.testTextInput.receiveAction(TextInputAction.done);
await tester.pump();
expect(find.byType(example.PersonTracker), findsNWidgets(4));
expect(find.byType(example.PersonTracker, skipOffstage: false), findsNWidgets(4));
await tester.enterText(textField, 'hello1');
await tester.testTextInput.receiveAction(TextInputAction.done);
await tester.pump();
expect(find.byType(example.PersonTracker), findsNWidgets(5));
expect(find.byType(example.PersonTracker, skipOffstage: false), findsNWidgets(5));
});
testWidgets('has state preservation', (WidgetTester tester) async {
await tester.pumpWidget(const example.IndexedStackApp());
......
......@@ -4075,6 +4075,28 @@ class _RawIndexedStack extends Stack {
..alignment = alignment
..textDirection = textDirection ?? Directionality.maybeOf(context);
}
@override
MultiChildRenderObjectElement createElement() {
return _IndexedStackElement(this);
}
}
class _IndexedStackElement extends MultiChildRenderObjectElement {
_IndexedStackElement(_RawIndexedStack super.widget);
@override
_RawIndexedStack get widget => super.widget as _RawIndexedStack;
@override
void debugVisitOnstageChildren(ElementVisitor visitor) {
final int? index = widget.index;
// If the index is null, no child is onstage. Otherwise, only the child at
// the selected index is.
if (index != null && children.isNotEmpty) {
visitor(children.elementAt(index));
}
}
}
/// A widget that controls where a child of a [Stack] is positioned.
......
......@@ -264,16 +264,28 @@ void main() {
);
}
void expectFindsChild(int n) {
for (int i = 0; i < 3; i++) {
expect(find.text('$i', skipOffstage: false), findsOneWidget);
if (i == n) {
expect(find.text('$i'), findsOneWidget);
} else {
expect(find.text('$i'), findsNothing);
}
}
}
await tester.pumpWidget(buildFrame(0));
expect(find.text('0'), findsOneWidget);
expect(find.text('1'), findsOneWidget);
expect(find.text('2'), findsOneWidget);
expectFindsChild(0);
expect(itemsPainted, equals(<int>[0]));
await tester.pumpWidget(buildFrame(1));
expectFindsChild(1);
expect(itemsPainted, equals(<int>[1]));
await tester.pumpWidget(buildFrame(2));
expectFindsChild(2);
expect(itemsPainted, equals(<int>[2]));
});
......@@ -473,6 +485,40 @@ void main() {
expect(tapped, isNull);
});
testWidgets('IndexedStack reports hidden children as offstage', (WidgetTester tester) async {
final List<Widget> children = <Widget>[
for (int i = 0; i < 5; i++) Text('child $i'),
];
Future<void> pumpIndexedStack(int? activeIndex) async{
await tester.pumpWidget(
Directionality(
textDirection: TextDirection.ltr,
child: IndexedStack(
index: activeIndex,
children: children,
),
)
);
}
final Finder finder = find.byType(Text);
final Finder finderIncludingOffstage = find.byType(Text, skipOffstage: false);
await pumpIndexedStack(null);
expect(finder, findsNothing); // IndexedStack with null index shows nothing
expect(finderIncludingOffstage, findsNWidgets(5));
for (int i = 0; i < 5; i++) {
await pumpIndexedStack(i);
expect(finder, findsOneWidget);
expect(finderIncludingOffstage, findsNWidgets(5));
expect(find.text('child $i'), findsOneWidget);
}
});
testWidgets('Stack clip test', (WidgetTester tester) async {
await tester.pumpWidget(
const Directionality(
......
......@@ -318,8 +318,9 @@ void main() {
],
)),
);
expect(find.byType(GestureDetector), findsNWidgets(2));
final Finder hitTestable = find.byType(GestureDetector).hitTestable();
expect(find.byType(GestureDetector), findsOneWidget);
expect(find.byType(GestureDetector, skipOffstage: false), findsNWidgets(2));
final Finder hitTestable = find.byType(GestureDetector, skipOffstage: false).hitTestable();
expect(hitTestable, findsOneWidget);
expect(tester.widget(hitTestable).key, const ValueKey<int>(0));
});
......
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