How to open a drawer in flutter test
Asked Answered
B

4

13

I am trying to test a custom drawer but find it hard opening it in the test, tried the following to begin with and even this test doesn't pass. The error is: Bad state: no element.

void main() {
  testWidgets('my drawer test', (WidgetTester tester) async {
    final displayName = "displayName";
    var drawKey = UniqueKey();
    await tester.pumpWidget(MaterialApp(
        home: Scaffold(
      drawer: Drawer(key: drawKey, child: Text(displayName),),
    )));
    await tester.tap(find.byKey(drawKey));
    expect(find.text(displayName), findsOneWidget);
  });
}
Baring answered 14/11, 2018 at 11:23 Comment(0)
J
19

You're calling tap() on the Drawer, but it isn't in view as it's hidden on the left. Because of this, the Finder doesn't find any elements and the tap() is unsuccessful. And even if the Finder found the Drawer, tapping on the Drawer itself doesn't open it anyway.

One way, and in my opinion, the simplest way of doing it is to provide a GlobalKey for the Scaffold and call openDrawer() on the current State of it. You could also tap on the hamburger icon or swipe from the left - but calling openDrawer() is more deterministic:

void main() {
  testWidgets('my drawer test', (WidgetTester tester) async {
    final scaffoldKey = GlobalKey<ScaffoldState>();
    const displayName = "displayName";

    await tester.pumpWidget(
      MaterialApp(
        home: Scaffold(
          key: scaffoldKey,
          drawer: const Text(displayName),
        ),
      ),
    );

    scaffoldKey.currentState.openDrawer();
    await tester.pump();

    expect(find.text(displayName), findsOneWidget);
  });
}
Jiles answered 14/11, 2018 at 11:43 Comment(0)
R
7

You can grab the top left of the parent widget and use dragFrom in order to simulate opening the drawer. In comparison to the current accepted answer, this does not require you to pass the scaffold key.

An example with a slight modification of the original code:

testWidgets('my drawer test', (WidgetTester tester) async {
  final displayName = "displayName";
  var drawKey = UniqueKey();
  await tester.pumpWidget(MaterialApp(
    home: Scaffold(
      drawer: Drawer(key: drawKey, child: Text(displayName),),
    )));

  await tester.dragFrom(tester.getTopLeft(find.byType(MaterialApp)), Offset(300, 0));
  await tester.pumpAndSettle();

  expect(find.text(displayName), findsOneWidget);
});

Notice tester.pumpAndSettle() was added to ensure enough time has passed.

Rog answered 16/2, 2020 at 20:55 Comment(0)
G
4

another solution:

  final ScaffoldState state = tester.firstState(find.byType(Scaffold));
  state.openDrawer();
  await tester.pump();
  await tester.tap(find.byTooltip('your tooltip text'));
  await tester.pump();
Gateway answered 20/5, 2022 at 8:35 Comment(0)
K
0

I am using:

Finder finder = find.byType(EndDrawerButton);
expect(finder, findsOneWidget);
await tester.tap(finder);
Kerby answered 27/6 at 15:10 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.