Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Flutter Driver crashing when main has async operations #41029

Closed
jamesdixon opened this issue Sep 21, 2019 · 20 comments
Closed

Flutter Driver crashing when main has async operations #41029

jamesdixon opened this issue Sep 21, 2019 · 20 comments
Assignees
Labels
t: flutter driver "flutter driver", flutter_drive, or a driver test tool Affects the "flutter" command-line tool. See also t: labels.

Comments

@jamesdixon
Copy link

jamesdixon commented Sep 21, 2019

Internal: b/147455985

My app has a few async operations that are initialized in main(). This works fine in my actual application. However, when attempting to run integration tests using Flutter Driver, the tests fail with the following error:

Result (on Emulators):
DriverError: Error in Flutter application: Uncaught extension error while executing tap: 'package:flutter_driver/src/extension/extension.dart': Failed assertion: line 193 pos 14: 'WidgetsBinding.instance.isRootWidgetAttached || !command.requiresRootWidgetAttached': No root widget is attached; have you remembered to call runApp()?

From what I can tell, Flutter Driver doesn't let the app fully initialize before running the tests. If I remove the async operation, things run as expected.

Steps to Reproduce

I've created a minimal reproduction in this repo: https://github.com/jamesdixon/hive_flutter_driver_issue

  1. Clone the repo
  2. Run flutter drive --target=test_driver/run_app.dart

Logs

The log output was quite long so I pasted it into a gist here: https://gist.github.com/jamesdixon/0b4d0895f6707bdaba439b158eb1110c

No issues found! (ran in 2.3s)
[✓] Flutter (Channel stable, v1.9.1+hotfix.2, on Mac OS X 10.14.5 18F132, locale en-US)
    • Flutter version 1.9.1+hotfix.2 at /Users/jamesdixon/flutter
    • Framework revision 2d2a1ffec9 (2 weeks ago), 2019-09-06 18:39:49 -0700
    • Engine revision b863200c37
    • Dart version 2.5.0

 
[✓] Android toolchain - develop for Android devices (Android SDK version 28.0.3)
    • Android SDK at /Users/jamesdixon/Library/Android/sdk
    • Android NDK location not configured (optional; useful for native profiling support)
    • Platform android-28, build-tools 28.0.3
    • ANDROID_HOME = /Users/jamesdixon/Library/Android/sdk
    • Java binary at: /Applications/Android Studio.app/Contents/jre/jdk/Contents/Home/bin/java
    • Java version OpenJDK Runtime Environment (build 1.8.0_202-release-1483-b49-5587405)
    • All Android licenses accepted.

[✓] Xcode - develop for iOS and macOS (Xcode 10.3)
    • Xcode at /Applications/Xcode.app/Contents/Developer
    • Xcode 10.3, Build version 10G8
    • CocoaPods version 1.7.4

[✓] Android Studio (version 3.5)
    • Android Studio at /Applications/Android Studio.app/Contents
    • Flutter plugin version 38.2.3
    • Dart plugin version 191.8423
    • Java version OpenJDK Runtime Environment (build 1.8.0_202-release-1483-b49-5587405)

[✓] VS Code (version 1.38.1)
    • VS Code at /Applications/Visual Studio Code.app/Contents
    • Flutter extension version 3.4.1

[✓] Connected device (1 available)
    • iPhone 7 Plus • 790FC845-4FE6-49C0-8B15-09E3BE74FA3F • ios • com.apple.CoreSimulator.SimRuntime.iOS-12-4 (simulator)
@BondarenkoStas BondarenkoStas added c: crash Stack traces logged to the console t: flutter driver "flutter driver", flutter_drive, or a driver test tool Affects the "flutter" command-line tool. See also t: labels. labels Sep 21, 2019
@anjrew
Copy link

anjrew commented Oct 19, 2019

Also getting this issue

@bgetsug
Copy link

bgetsug commented Oct 21, 2019

Same issue here...my current workaround is to add some sleep():

//...
setUpAll(() async {
    driver = await FlutterDriver.connect();

    await sleep(Duration(seconds: 10));

   // more setup...
}   

@zeucxb
Copy link

zeucxb commented Nov 11, 2019

Same here!

@russell-sf
Copy link

Since the call to await in main defers the creation of the app, the flutter driver starts up immediately and starts running tests. Problem is the app may not be fully initialized since the awaited call could still be in flight. That's why adding the delay before running your tests fixes the problem.

Flutter should not start the tests until runApp is actually called.

@jonahwilliams
Copy link
Member

To fix this, the driver bindings could be updated to send a handshake single to the command line test. Then FlutterDriver.connect could be updated to wait for this signal before beginning

DriverBinding: https://github.com/flutter/flutter/blob/master/packages/flutter_driver/lib/src/extension/extension.dart#L45

@jonahwilliams jonahwilliams removed the c: crash Stack traces logged to the console label Feb 4, 2020
@msmaromi
Copy link

Sometimes I got this also

@matejhocevar
Copy link

@jonahwilliams can you give more instructions on how to update FlutterDriver.connect in order for Flutter driver to work with async main?

@jonahwilliams
Copy link
Member

connect would need to wait for a firstFrame event or similar event from when the Widget tree is attached. I'm not quite sure what the exact approach would be

@bionara
Copy link

bionara commented Mar 29, 2020

I can't seem to get mine working - even putting the sleep i get the same error:

[trace] FlutterDriver: Isolate found with number: 420724065357151
[trace] FlutterDriver: Isolate is paused at start.
[trace] FlutterDriver: Attempting to resume isolate
[trace] FlutterDriver: Waiting for service extension
[warning] FlutterDriver: Flutter Driver extension is taking a long time to become available. Ensure your test app (often "lib/main.dart") imports "package:flutter_driver/driver_extension.dart" and calls enableFlutterDriverExtension() as the first call in main().

I tried the enableFlutterDriverExtension in main, but that didn't do anything; furthermore, this actually stopped it working on my teammate's machine!

@Boehrsi
Copy link
Contributor

Boehrsi commented Apr 9, 2020

I also encountered this and tried to avoid hardcoded waiting times. I create a Gist (https://gist.github.com/Boehrsi/93c26371431367a639476a3a860ead60) which works well for me. Feel free to give it a try, hopefully it helps you too.

@jiahaog
Copy link
Member

jiahaog commented Apr 28, 2020

I'm currently looking into this as well because it affects internal clients. (b/147455985)

@jiahaog
Copy link
Member

jiahaog commented Jun 30, 2020

This has been fixed with the above two PRs, you should be able to call await driver.waitUntilFirstFrameRasterized() after FlutterDriver.connect() directly without the looping workaround mentioned in #41029 (comment) if you're expecting to do heavy work before runApp in your application main.

@jiahaog jiahaog closed this as completed Jun 30, 2020
@amreniouinnovent
Copy link

@jiahaog Flutter 1.17.5 not working is your fix on the stable branch?

@jiahaog
Copy link
Member

jiahaog commented Jul 17, 2020

I don't think so, you'll have to wait a bit for it to hit stable 🙂

@urmilshroff
Copy link

I'm facing this issue with the newly released integration_test package as well.

Adding await sleep(Duration(seconds: 10)); in my setUpAll() or testWidgets() methods doesn't work, and since I'm not using the old FlutterDriver method, I'm a bit stuck.

@fernandocerkal
Copy link

I'm facing this issue with the newly released integration_test package as well.

Adding await sleep(Duration(seconds: 10)); in my setUpAll() or testWidgets() methods doesn't work, and since I'm not using the old FlutterDriver method, I'm a bit stuck.

Me too.
I have been faced the same issue using integration_test.
I tried put "sleep" in all methods without success.

integration_test.dart:
`import 'package:integration_test/integration_test_driver.dart';

Future main() => integrationDriver();`

app.dart:
`import 'package:com.unclewash.partnerapp/common/core/locator.dart';
import 'package:com.unclewash.partnerapp/main.dart';
import 'package:flutter/material.dart';
import 'package:flutter_driver/driver_extension.dart';

Future main() async {
// This line enables the extension.
enableFlutterDriverExtension();
WidgetsFlutterBinding.ensureInitialized();

setupLocator();

runApp(MyApp());
}`

app_test.dart:
`// Imports the Flutter Driver API.
import 'dart:io';
import 'package:com.unclewash.partnerapp/common/core/locator.dart';
import 'package:flutter_driver/flutter_driver.dart';
import 'package:flutter/material.dart';
import 'package:get_it/get_it.dart';
import 'package:test/test.dart';

//import 'package:flutter_test/flutter_test.dart';

import 'workaround.dart';

void main() {

print('group');
group("All test", (){
print("All test");
final loginPage = find.byValueKey('LoginPage');
final login = find.byValueKey('_loginFieldKey');
final password = find.byValueKey(Key('_passwordFieldKey'));
final join = find.text('Entrar');

FlutterDriver driver;
IsolatesWorkaround workaround;

Future<bool> isPresent(SerializableFinder byValueKey, {Duration timeout = const Duration(seconds: 1)}) async {
  try {
    await driver.waitFor(byValueKey, timeout: timeout);
    return true;
  } catch (exception) {
    return false;
  }
}

// Connect to the Flutter driver before running any tests.
setUpAll(() async {      
  driver = await FlutterDriver.connect();       
  workaround = IsolatesWorkaround(driver);
  await workaround.resumeIsolates();
  await driver.waitUntilFirstFrameRasterized();
  
  
  if (!await Directory('screenshots').exists()) {
    await Directory('screenshots').create();
  }
});

// Close the connection to the driver after the tests have completed.
tearDownAll(() async {
  if (driver != null) {
    await driver?.close();
    await workaround.tearDown();
  }
});

test('check flutter driver health', () async {
  Health health = await driver.checkHealth();
  print(health.status);
});

test("Login", () async {
  print('login..');
  await sleep(Duration(seconds: 5));
  await driver.waitFor(loginPage);
  
  setupLocator();
  await driver.waitFor(login);
  await driver.tap(login);
  await driver.enterText("luiz@unclewash.com");
  await driver.tap(password);
  await driver.enterText("Brasil123");
  
  
  await driver.tap(join);   

  await driver.waitFor(find.text("Serviços"));     
  
}); 

 //test("Add Services", () async {});

});
}

Widget buildTestableWidget(Widget widget) {
return MediaQuery(data: MediaQueryData(), child: MaterialApp(home: widget));
}`

pubspec.yaml:
dev_dependencies: flutter_test: sdk: flutter flutter_driver: sdk: flutter test: integration_test:

flutter doctor -v:
`[✓] Flutter (Channel stable, 1.22.5, on Linux, locale en_US.UTF-8)
• Flutter version 1.22.5 at /home/luiz/Development/flutter
• Framework revision 7891006 (4 weeks ago), 2020-12-10 11:54:40 -0800
• Engine revision ae90085a84
• Dart version 2.10.4

[✓] Android toolchain - develop for Android devices (Android SDK version 29.0.3)
• Android SDK at /home/luiz/Android/Sdk
• Platform android-30, build-tools 29.0.3
• Java binary at: /home/luiz/Development/android-studio/jre/bin/java
• Java version OpenJDK Runtime Environment (build 1.8.0_202-release-1483-b49-5587405)
• All Android licenses accepted.

[✓] Android Studio (version 3.5)
• Android Studio at /home/luiz/Development/android-studio
• Flutter plugin version 44.0.1
• Dart plugin version 191.8593
• Java version OpenJDK Runtime Environment (build 1.8.0_202-release-1483-b49-5587405)

[✓] VS Code (version 1.51.1)
• VS Code at /usr/share/code
• Flutter extension version 3.17.0

[✓] Connected device (1 available)
• Android SDK built for x86 (mobile) • emulator-5554 • android-x86 • Android 10 (API 29) (emulator)

• No issues found!`

command line:
flutter drive --driver=test_driver/integration_driver.dart --target=test_driver/app.dart

console output:
`Using device Android SDK built for x86.
Starting application: test_driver/app.dart
Installing build/app/outputs/flutter-apk/app.apk... 0.8s
Running Gradle task 'assembleDebug'...
Running Gradle task 'assembleDebug'... Done 16.2s
✓ Built build/app/outputs/flutter-apk/app-debug.apk.
Installing build/app/outputs/flutter-apk/app.apk... 0.8s
I/flutter ( 3357): Observatory listening on http://127.0.0.1:42497/d6xnCTDB5vc=/
E/FlutterFcmService( 3357): Fatal: failed to find callback
VMServiceFlutterDriver: Connecting to Flutter application at http://127.0.0.1:39509/d6xnCTDB5vc=/
VMServiceFlutterDriver: Isolate found with number: 955153920992255
VMServiceFlutterDriver: Isolate is paused at start.
VMServiceFlutterDriver: Attempting to resume isolate
VMServiceFlutterDriver: Connected to Flutter application.
Unhandled exception:
FormatException: Unexpected character (at character 1)
No requestData Extension registered
^

#0 _ChunkedJsonParser.fail (dart:convert-patch/convert_patch.dart:1404:5)
#1 _ChunkedJsonParser.parseNumber (dart:convert-patch/convert_patch.dart:1271:9)
#2 _ChunkedJsonParser.parse (dart:convert-patch/convert_patch.dart:936:22)
#3 _parseJson (dart:convert-patch/convert_patch.dart:40:10)
#4 JsonDecoder.convert (dart:convert/json.dart:505:36)
#5 JsonCodec.decode (dart:convert/json.dart:156:41)
#6 Response.fromJson (package:integration_test/common.dart:59:52)
#7 integrationDriver (package:integration_test/integration_test_driver.dart:73:38)

#8 main (file:///home/luiz/projects/ewash/ewashPartnerApp/code/src/app/test_driver/integration_driver.dart:3:24)
#9 _startIsolate. (dart:isolate-patch/isolate_patch.dart:301:19)
#10 _RawReceivePortImpl._handleMessage (dart:isolate-patch/isolate_patch.dart:168:12)
Stopping application instance.
Driver tests failed: 255`

@fernandocerkal
Copy link

I/flutter ( 5443): Observatory listening on http://127.0.0.1:38955/uy7RO1jCdyE=/

VMServiceFlutterDriver: Connecting to Flutter application at http://127.0.0.1:39733/uy7RO1jCdyE=/

@fernandocerkal
Copy link

Guys, I solved this changing 'package:test/test.dart' to flutter_test.dart

@EthanShoeDev
Copy link

I am still having this issue on the most recent dev build. My app.main method has several async tasks and the test starts while there is still "Starting Test..." on the device screen. If I add a manual wait I can avoid the issue but that feels very wrong.

@github-actions
Copy link

github-actions bot commented Aug 3, 2021

This thread has been automatically locked since there has not been any recent activity after it was closed. If you are still experiencing a similar issue, please open a new bug, including the output of flutter doctor -v and a minimal reproduction of the issue.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Aug 3, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
t: flutter driver "flutter driver", flutter_drive, or a driver test tool Affects the "flutter" command-line tool. See also t: labels.
Projects
None yet
Development

No branches or pull requests