How to locate multiple widget of same type in widget hierarchy?

Viewed 788

I am developing some intregration tests for one of my flutter-web application. I wanted to specifically locate the container(width: 50, height: 50) in the following below widget hierarchy tree considering top to bottom approach. ParentWidget --> Row --> Text, SizedBox, Row --> Container(), Container(width: 50, height: 50), Container(). Note: Without key approach

I tried to locate using descendant of ParentWidget --> Row --> Row --> with index tried to select the 2nd container, but this isn't working, it fails with error "Bad state: No element".

import 'package:flutter/material.dart';

class ParentWidget extends StatelessWidget {
  const ParentWidget({Key? key});

  @override
  Widget build(BuildContext context) {
    return Row(
      crossAxisAlignment: CrossAxisAlignment.center,
      children: [
        Text("Hello World..!!"),
        SizedBox(
          width: 20,
        ),
        Row(
          crossAxisAlignment: CrossAxisAlignment.end,
          children: [
            Container(
              width: 20,
              height: 20,
              color: Colors.red,
            ),
            Container(
              width: 50,
              height: 50,
              color: Colors.red,
            ),
            Container(
              width: 20,
              height: 20,
              color: Colors.red,
            ),
          ],
        ),
      ],
    );
  }
}
final container = tester.widget<Container>(find.descendant(
    of: find.descendant(
        of: find.byType(ParentWidget), matching: find.byType(Row)),
    matching: find.descendant(
        of: find.byType(Row), matching: find.byType(Container).at(1))));
2 Answers

To find multiple widgets in a test you can do this:

testWidgets('Test containers', (tester) async {
    
    await tester.pumpWidget(ParentWidget());

    expect(find.byType(Container), findsNWidgets(3));
  });

For more info check https://docs.flutter.dev/cookbook/testing/widget/introduction

Edit: To test the second Container's width you could do something like this:

//get the second element's widget, index 1, cast it as a container and check it's width
expect((find.byType(Container).evaluate().elementAt(1).widget as Container).constraints?.maxWidth, 50.0);

If your widget tree is deep nested and you want to locate specific widget down the tree we can make use of something: If sub-widget tree contains multiple widget of same type...try locating it via index...how the look up will going to work is, it iwll try to locate the 2nd Container down under the ParentWidget sub tree.

final container = (find
          .descendant(
              of: find.byType(ParentWidget),
              matching: find.byType(Container),
              matchRoot: true)
          .evaluate()
          .elementAt(1)
          .widget as Container);
Related