Flutter driver - enter text into field that is off screen

3,095

I tried to re-create your case and was able to run a driver test successfully that entered text in non-visible textfield on screen using ScrollIntoView() method. Here's what I did for demo:

  • In main.dart, had series of textformfields having unique key for each, wrapped inside Column which was wrapped in SingleChildScrollView:

enter image description here

When we scroll down, you'll see the last textfield with hintText Last TextField which is not visible when screen launches.

enter image description here

For this setup, wrote two driver tests to tap and enter text as below:

test('Enter text into first text field', () async {
      await driver.tap(myTextField);
      await driver.enterText('Hello world');
      await driver.waitFor(find.text('Hello world'));
    });

    test('Enter text into last text field', () async {
      await driver.scrollIntoView(myTextField21);
      await driver.tap(myTextField21);
      await driver.enterText('Hello');
      await driver.waitFor(find.text('Hello'));

    });

Which successfully entered text in last textfield after scrolling into it first.

enter image description here

Hope this helps.

Share:
3,095
user2181948
Author by

user2181948

Updated on December 01, 2022

Comments

  • user2181948
    user2181948 over 1 year

    I am trying to write an integration test for a screen with multiple TextFormFields. For each test, I am simply:

    1. Tapping the text field
    2. Entering some text
    3. Checking if the text exists in the text field.

    Using Flutter driver, the following works well for each TextFormField:

    final myTextField = find.byValueKey('TextField');
    
    test('Enter text into text field', () async {
       await driver.tap(myTextField);
       await driver.enterText('Hello world');
       await driver.waitFor(find.text('Hello world'));
     });
    

    However for any TextFormFields that are off-screen (ie. not visible / outside of the viewport), the test fails with a timeout error.

    I tried adding scrollIntoView() to the tests to tell Flutter Driver to scroll until the field is in the viewport. Below is an example:

    final myTextField = find.byValueKey('TextField');
    
    test('Enter text into text field', () async {
       await driver.scrollIntoView(myTextField); // Added
       await driver.tap(myTextField);
       await driver.enterText('Hello world');
       await driver.waitFor(find.text('Hello world'));
     });
    

    However the tests continue to fail with a timeout error:

    FlutterDriver: tap message is taking a long time to complete...
    00:39 +0 -1: My screen: Enter text into text field [E]
    
      TimeoutException after 0:00:30.000000: Test timed out after 30 seconds.
    

    How do I test TextFormFields that are outside of the viewport?


    Update: I've found that using scrollUntilVisible() is preferred to scrollIntoView(), as the element may not yet have been rendered yet and therefore cannot be found (see https://flutter.dev/docs/cookbook/testing/integration/scrolling).

    scrollUntilVisible() successfully auto-scrolls the screen and finds the element that was off screen. However, once found, the screen automatically jumps back up to the top for some reason, making the element off-screen again. What's going on?

    final myTextField = find.byValueKey('TextField');
    final myListView = find.byValueKey('ListView');
    
    test('Enter text into text field', () async {
         await scrollUntilVisible(
         myListView,
         finder,
         // To scroll down the list, provide a negative value to dyScroll.
         // Ensure that this value is a small enough increment to
         // scroll the item into view without potentially scrolling past it.
         //
         // To scroll through horizontal lists, provide a dxScroll
         // property instead.
         dyScroll: -100
       );
    
       await driver.tap(myTextField);
       await driver.enterText('Hello world');
       await driver.waitFor(find.text('Hello world'));
     });
    
    • Admin
      Admin about 4 years
      Can you please explain your question more thoroughly ?
    • user2181948
      user2181948 about 4 years
      @ChinkySight Ok, I have added some extra details now.