flutterdriver

Flutter Driver - How to know which "waitFor" command has failed?


I am using Flutter Driver to write some integration tests for our app and I am trying to use the waitFor command to wait until an element has appeared.

The command works well and waits for my element, or fails when it hasn't found it. My problem is that when it fails, the logs in the console don't tell me which of the waitFor calls has failed.

I run, for example, the following code to wait for myButton1 and myButton2:

Duration timeout = new Duration(seconds: 2);
await _driver.waitFor(myButton1, timeout: timeout);
await _driver.waitFor(myButton2, timeout: timeout);

However, when I run the tests, they fail with the following error message:

00:04 +0 -1: Buttons shown when app is started [E]                                                                               
  DriverError: Error in Flutter application: Timeout while executing waitFor: TimeoutException after 0:00:02.000000: Future not completed
  
  
  package:flutter_driver/src/driver/vmservice_driver.dart 343:7  VMServiceFlutterDriver.sendCommand
  
00:04 +0 -1: Buttons (tearDownAll)                                                                                               [  +77 ms] test 0: process with pid 87459 no longer needed by test harness
[        ] test 0: cleaning up...
[        ] test 0: ensuring end-of-process for shell
[  +10 ms] test 0: deleting temporary directory
[   +4 ms] test 0: shutting down test harness socket server
[   +2 ms] test 0: finished
00:04 +0 -1: Some tests failed.                                                                                                            
[  +13 ms] Deleting /var/folders/xt/0fckrj2558746_v71h2vwqh00000gn/T/flutter_tools.WEuo76/flutter_test_compiler.u7VNn4...
[   +9 ms] killing pid 87444
[  +37 ms] Deleting /var/folders/xt/0fckrj2558746_v71h2vwqh00000gn/T/flutter_tools.WEuo76/flutter_test_fonts.FDpcXF...
[   +6 ms] test package returned with exit code 1
[  +13 ms] "flutter test" took 4,890ms.
[   +6 ms] 
           #0      throwToolExit (package:flutter_tools/src/base/common.dart:14:3)
           #1      TestCommand.runCommand (package:flutter_tools/src/commands/test.dart:292:7)
           <asynchronous suspension>
           #2      FlutterCommand.verifyThenRunCommand (package:flutter_tools/src/runner/flutter_command.dart:860:18)
           #3      _rootRunUnary (dart:async/zone.dart:1198:47)
           #4      _CustomZone.runUnary (dart:async/zone.dart:1100:19)
           #5      _FutureListener.handleValue (dart:async/future_impl.dart:143:18)
           #6      Future._propagateToListeners.handleValueCallback (dart:async/future_impl.dart:696:45)
           #7      Future._propagateToListeners (dart:async/future_impl.dart:725:32)
           #8      Future._completeWithValue (dart:async/future_impl.dart:529:5)
           #9      Future._asyncCompleteWithValue.<anonymous closure> (dart:async/future_impl.dart:567:7)
           #10     _rootRun (dart:async/zone.dart:1190:13)
           #11     _CustomZone.run (dart:async/zone.dart:1093:19)
           #12     _CustomZone.runGuarded (dart:async/zone.dart:997:7)
           #13     _CustomZone.bindCallbackGuarded.<anonymous closure> (dart:async/zone.dart:1037:23)
           #14     _microtaskLoop (dart:async/schedule_microtask.dart:41:21)
           #15     _startMicrotaskLoop (dart:async/schedule_microtask.dart:50:5)
           #16     _runPendingImmediateCallback (dart:isolate-patch/isolate_patch.dart:118:13)
           #17     _RawReceivePortImpl._handleMessage (dart:isolate-patch/isolate_patch.dart:169:5)
           
           
[ +254 ms] ensureAnalyticsSent: 251ms
[   +1 ms] Running shutdown hooks
[        ] Shutdown hook priority 4
[        ] Shutdown hooks complete
[        ] exiting with code 1

This info doesn't tell me if it was myButton1 or myButton2 that has failed. It also doesn't give me any code line from my tests to indicate which of the lines actually had the error.

Any ideas on this?


Solution

  • I haven't yet figured out if there is a built-in way to do that, but I wrote a helper method to get the info I need:

      Future waitForObject(SerializableFinder object, Duration timeout, {String errorMessage = "waitForObject timed out"}) async {
        var message = "ERROR ==> $errorMessage";
        return await _driver.waitFor(object, timeout: timeout).catchError((e) { throw(message);});
      }
    

    This will still throw an error after timing out if the object is not found, but it will also point me to the exact line in the code that caused the timeout.