Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

FlutterDriver problem, not able to find Widget by Key

I am having a problem in terms of finding the widget by key in SerializableFinder, what can I do to solve this?

I have tried on making the key with constants and I made sure to check that the key is the same as the one in finder by providing constants. Besides, I was referring to this link : Flutter Driver: Test BottomNavigationBarItem

Here is the code: Integration test file (example part, not a full code):

// todo: bottom navigation pressed
    test('bottom navigation bar test item', () async{

      // todo: intended = pressed favorite dessert, but we want to test
      await flutterDriver.waitFor(bottomNavigationBar);

      // todo: bottom navigation bar item text research
      await flutterDriver.tap(dessert); // intended : tap at bottom navigation view item

      print('This is Dessert section');

      // todo: expect title is keyword

      await flutterDriver.tap(seafood);

      print('This is Seafood section');

      await flutterDriver.tap(favoriteDessert);

      print('This is Favorite Dessert section');

      await flutterDriver.tap(favoriteSeafood);

      print('This is Favorite Seafood section');


    });

Finder file (for bottom navigation bar thing):

SerializableFinder bottomNavigationBar = find.byValueKey(BOTTOM_NAVIGATION_BAR);

SerializableFinder dessert = find.byValueKey(DESSERT);
SerializableFinder seafood = find.byValueKey(SEAFOOD);
SerializableFinder favoriteDessert = find.byValueKey(FAVORITE_DESSERT);
SerializableFinder favoriteSeafood = find.byValueKey(FAVORITE_SEAFOOD);

Widget file (2 parts): Part 1: bottom navigation bar items

List<BottomNavigationBarItem> bottomNavigationBarItems = [
    BottomNavigationBarItem(
        icon: Icon(Icons.cake, key: Key(DESSERT)), title: Text("Dessert")),
    BottomNavigationBarItem(
        icon: Icon(Icons.restaurant, key : Key(SEAFOOD)), title: Text("Seafood")),
    BottomNavigationBarItem(
        icon: Icon(Icons.cake, key: Key(FAVORITE_DESSERT)), title: Text("Favorite Dessert")),
    BottomNavigationBarItem(
        icon: Icon(Icons.restaurant, key: Key(FAVORITE_SEAFOOD)), title: Text("Favorite Seafood"))
  ];

Part 2: bottom navigation bar

 bottomNavigationBar: BottomNavigationBar(
        key: Key(BOTTOM_NAVIGATION_BAR),
        items: bottomNavigationBarItems,
        currentIndex: currentIndex,
        onTap: (index) {
          changeSelectedBottomNavigationBarItem(index);
        },
        selectedItemColor: appConfig.appColor,
        unselectedItemColor: Colors.grey,
      ),

If you want to provide full code just request it, I will be more than happy to provide them.

Expected results : When doing integration testing, the app will automatically navigate selected item

Actual result :

Sneak peek:

00:02 +0: Meals Catalogue App bottom navigation bar test item
[warning] FlutterDriver: waitFor message is taking a long time to complete...
00:32 +0 -1: Meals Catalogue App bottom navigation bar test item [E]
  TimeoutException after 0:00:30.000000: Test timed out after 30 seconds.
00:32 +0 -1: Meals Catalogue App (tearDownAll)
00:32 +0 -1: Meals Catalogue App bottom navigation bar test item [E]
  DriverError: Failed to fulfill WaitFor due to remote error
  Original error: Bad state: The client closed with pending request "ext.flutter.driver".

Since the stack trace is a bit too long in the link, I will provide my pastebin into here: https://pastebin.com/p4ktKXLA

like image 927
Hansel T Avatar asked Jun 07 '19 10:06

Hansel T


1 Answers

I had the same problem and the solution that finally helped me is from Pyozer:

The flutter driver is by default frame synchronized, it will wait until there is no pending frame(s), but if there is infinite animation, the test will go to the timeout and fail.

To fix this, you need to wrap your tests with the driver.runUnsynchronized() method. Like this:

test('Test SplashScreen', () async {
  await driver.runUnsynchronized(() async {
    await driver.waitFor(find.text("DESSERT"));
  });
});

(Only if you have an infinite animation or you want to continue before end of an animation)

like image 135
Till Friebe Avatar answered Oct 13 '22 01:10

Till Friebe