Warm tip: This article is reproduced from serverfault.com, please click

DriverError: Failed to fulfill Tap due to remote error flutter

发布于 2019-07-12 19:36:35

I have some customized TextFiels and they are for entering a pin and I called them PinInputField. When I'm running integration test using flutter drive, all of the input fields will receive given text, except last one and stops running test. Here is the code: P.s: the I'm using HookWidget

    final focusNodes = List.generate(6, (_) => new FocusNode());
    final values = List.generate(6, (_) => useState<String>(''));

Row(
                  mainAxisAlignment: MainAxisAlignment.center,
                  crossAxisAlignment: CrossAxisAlignment.center,
                  children: <Widget>[
                    for (int i = 0; i < values.length; i++)
                      PinInputField(
                        key: ValueKey('$i'),
                        width: MediaQuery.of(context).size.width / 11.71,
                        height: 80,
                        fontSize: 50,
                        marginRight: 16,
                        input: values[i],
                        focusNode: focusNodes[i],
                        nextFocusNode: i == 5 ? null : focusNodes[i + 1],
                      )
                  ],
                )

and here is the tests:

    test('test main card settings items', () async {
      final cardSettingsItem = find.byValueKey('settings.cardSettings');
       final mainSettingsList = find.byValueKey('mainSettingsList');
      final profileButton = find.byValueKey('Profile');
      final changePinButton = find.byValueKey('Cambiar pin');
      final changePinInputField0 = find.byValueKey('0');
      final changePinInputField1 = find.byValueKey('1');
      final changePinInputField2 = find.byValueKey('2');
      final changePinInputField3 = find.byValueKey('3');
      final changePinInputField4 = find.byValueKey('4');
      final changePinInputField5 = find.byValueKey('5');
      final changePinScreenButton = find.byValueKey('changePinScreenButton');
      sleep(Duration(seconds: 3));
      await driver.tap(profileButton);
      sleep(Duration(seconds: 2));
      await driver.scrollIntoView(mainSettingsList);
      sleep(Duration(seconds: 3));
      await driver.tap(cardSettingsItem);
      sleep(Duration(seconds: 3));
      await driver.tap(changePinButton);
      sleep(Duration(seconds: 4));
      await driver.tap(changePinInputField0);
      sleep(Duration(seconds: 2));
      await driver.enterText("0");
      sleep(Duration(seconds: 1));
      await driver.tap(changePinInputField1);
      sleep(Duration(seconds: 2));
      await driver.enterText("1");
      sleep(Duration(seconds: 1));
      await driver.tap(changePinInputField2);
      sleep(Duration(seconds: 2));
      await driver.enterText("2");
      sleep(Duration(seconds: 1));
      await driver.tap(changePinInputField3);
      sleep(Duration(seconds: 2));
      await driver.enterText("3");
      sleep(Duration(seconds: 1));
      await driver.tap(changePinInputField4);
      sleep(Duration(seconds: 2));
      await driver.enterText("4");
      sleep(Duration(seconds: 4));
      await driver.tap(changePinInputField5);
      sleep(Duration(seconds: 1));
      await driver.enterText("5");
      sleep(Duration(seconds: 5));
      await driver.tap(changePinScreenButton);
      sleep(Duration(seconds: 4));
    });

and here is the log:

 DriverError: Failed to fulfill Tap due to remote error
  Original error: Bad state: The client closed with pending request "ext.flutter.driver".
  Original stack trace:
  #0      new Client.withoutJson.<anonymous closure> (package:json_rpc_2/src/client.dart:70:24)
  #1      StackZoneSpecification._run (package:stack_trace/src/stack_zone_specification.dart:209:15)
  #2      StackZoneSpecification._registerCallback.<anonymous closure> (package:stack_trace/src/stack_zone_specification.dart:119:48)
  #3      _rootRun (dart:async/zone.dart:1120:38)
  #4      _CustomZone.run (dart:async/zone.dart:1021:19)
  #5      _FutureListener.handleWhenComplete (dart:async/future_impl.dart:150:18)
  #6      Future._propagateToListeners.handleWhenCompleteCallback (dart:async/future_impl.dart:609:39)
  #7      Future._propagateToListeners (dart:async/future_impl.dart:665:37)
  #8      Future._propagateToListeners (dart:async/future_impl.dart:566:9)
  #9      Future._completeWithValue (dart:async/future_impl.dart:483:5)
  #10     Future._asyncComplete.<anonymous closure> (dart:async/future_impl.dart:513:7)
  #11     StackZoneSpecification._run (package:stack_trace/src/stack_zone_specification.dart:209:15)
  #12     StackZoneSpecification._registerCallback.<anonymous closure> (package:stack_trace/src/stack_zone_specification.dart:119:48)
  #13     _rootRun (dart:async/zone.dart:1124:13)
  #14     _CustomZone.run (dart:async/zone.dart:1021:19)
  #15     _CustomZone.runGuarded (dart:async/zone.dart:923:7)
  #16     _CustomZone.bindCallbackGuarded.<anonymous closure> (dart:async/zone.dart:963:23)
  #17     _microtaskLoop (dart:async/schedule_microtask.dart:41:21)
  #18     _startMicrotaskLoop (dart:async/schedule_microtask.dart:50:5)
  #19     _Timer._runTimers (dart:isolate-patch/timer_impl.dart:391:30)
  #20     _Timer._handleMessage (dart:isolate-patch/timer_impl.dart:416:5)
  #21     _RawReceivePortImpl._handleMessage (dart:isolate-patch/isolate_patch.dart:172:12)

Questioner
Mohammad Meshkani
Viewed
1
Hemanth Raj 2019-07-15 23:31:01

This issue mostly occurs when the test times out before it is actually completed. The default timeout used for a test to run is 30 seconds, here your sleep durations add up to more than 30 seconds, hence the connection closed with pending requests.

I don't understand why to sleep for a certain duration after each action, may be you can reduce/remove sleep. If sleeps are mandatory for your case try to pass the appropriate timeout to the test.

Example:

test(
  'test main card settings items',
  () async {
    final cardSettingsItem = find.byValueKey('settings.cardSettings');
    final mainSettingsList = find.byValueKey('mainSettingsList');
    final profileButton = find.byValueKey('Profile');
    final changePinButton = find.byValueKey('Cambiar pin');
    final changePinInputField0 = find.byValueKey('0');
    final changePinInputField1 = find.byValueKey('1');
    final changePinInputField2 = find.byValueKey('2');
    final changePinInputField3 = find.byValueKey('3');
    final changePinInputField4 = find.byValueKey('4');
    final changePinInputField5 = find.byValueKey('5');
    final changePinScreenButton = find.byValueKey('changePinScreenButton');
    sleep(Duration(seconds: 3));
    await driver.tap(profileButton);
    sleep(Duration(seconds: 2));
    await driver.scrollIntoView(mainSettingsList);
    sleep(Duration(seconds: 3));
    await driver.tap(cardSettingsItem);
    sleep(Duration(seconds: 3));
    await driver.tap(changePinButton);
    sleep(Duration(seconds: 4));
    await driver.tap(changePinInputField0);
    sleep(Duration(seconds: 2));
    await driver.enterText("0");
    sleep(Duration(seconds: 1));
    await driver.tap(changePinInputField1);
    sleep(Duration(seconds: 2));
    await driver.enterText("1");
    sleep(Duration(seconds: 1));
    await driver.tap(changePinInputField2);
    sleep(Duration(seconds: 2));
    await driver.enterText("2");
    sleep(Duration(seconds: 1));
    await driver.tap(changePinInputField3);
    sleep(Duration(seconds: 2));
    await driver.enterText("3");
    sleep(Duration(seconds: 1));
    await driver.tap(changePinInputField4);
    sleep(Duration(seconds: 2));
    await driver.enterText("4");
    sleep(Duration(seconds: 4));
    await driver.tap(changePinInputField5);
    sleep(Duration(seconds: 1));
    await driver.enterText("5");
    sleep(Duration(seconds: 5));
    await driver.tap(changePinScreenButton);
    sleep(Duration(seconds: 4));
  },
  timeout: Timeout(
    Duration(minutes: 2),
  ),
);

Hope that helps!