Repository navigation
Description
With example in https://docs.flutter.dev/cookbook/testing/integration/introduction, after executing the command:
flutter drive \
--driver=test_driver/integration_test.dart \
--target=integration_test/app_test.dart \
-d chrome
One Chrome is opened. Be noticed that it is not labelled with 'chrome is controlled by automated test software'.
Then try to execute the command plus arg --no-headless:
flutter drive \
--driver=test_driver/integration_test.dart \
--target=integration_test/app_test.dart \
-d chrome \
--no-headless
Two Chrome instances are launched:
- One [backend one] is launched as device [this is NOT intend for test cases execution]
- The other [frontend one] is launched via webdriver (chromedriver this case) [this is intend for test cases execution, labelled with 'chrome is controlled by automated test software']
[Note: Mostly, the two Chromes are overlaid, please try to drag it away (up or down), then back one would be visible.]
Both Chrome instances have test executed. However, the Chrome is launched not via chromedriver has major negative impact to test:
- For js, css loading, increase the networking pressure as need to load two copies
- For some write, delete scenarios, the test will result in unexpected results (as two Chromes both will try to execute delete action)
That is, the unnecessary Chrome instance breaks the foundation of the integration test (via flutter drive)
---- Source Code Analysis: Flow the flutter drive flow ----
-
(1)
flutter/packages/flutter_tools/lib/src/commands/drive.dart
Lines 243 to 244 in 6af40a7
await driverService.start( buildInfo,
flutter/packages/flutter_tools/lib/src/commands/drive.dart
Lines 252 to 259 in 6af40a7
platformArgs: <String, Object>{ if (traceStartup) 'trace-startup': traceStartup, if (web) '--no-launch-chrome': true, if (boolArg('multidex')) 'multidex': true, }
flutter/packages/flutter_tools/lib/src/commands/drive.dart
Lines 274 to 275 in 6af40a7
final int testResult = await driverService.startTest( testFile, -
(2)
final Future<int> runFuture = _residentRunner.run( -
(3)
flutter/packages/flutter_tools/lib/src/isolated/resident_web_runner.dart
Lines 307 to 314 in 6af40a7
await device.device.startApp( package, mainPath: target, debuggingOptions: debuggingOptions, platformArgs: <String, Object>{ 'uri': url.toString(), }, ); -
(4)
flutter/packages/flutter_tools/lib/src/web/web_device.dart
Lines 120 to 153 in 6af40a7
Future<LaunchResult> startApp( covariant WebApplicationPackage package, { String? mainPath, String? route, required DebuggingOptions debuggingOptions, Map<String, Object?> platformArgs = const <String, Object?>{}, bool prebuiltApplication = false, bool ipv6 = false, String? userIdentifier, }) async { // See [ResidentWebRunner.run] in flutter_tools/lib/src/resident_web_runner.dart // for the web initialization and server logic. String url; if (debuggingOptions.webLaunchUrl != null) { final RegExp pattern = RegExp(r'^((http)?:\/\/)[^\s]+'); if (pattern.hasMatch(debuggingOptions.webLaunchUrl!)) { url = debuggingOptions.webLaunchUrl!; } else { throwToolExit('"${debuggingOptions.webLaunchUrl}" is not a vaild HTTP URL.'); } } else { url = platformArgs['uri']! as String; } final bool launchChrome = platformArgs['no-launch-chrome'] != true; if (launchChrome) { _chrome = await chromeLauncher.launch( url, cacheDir: _fileSystem.currentDirectory .childDirectory('.dart_tool') .childDirectory('chrome-device'), headless: debuggingOptions.webRunHeadless, debugPort: debuggingOptions.webBrowserDebugPort, ); }
Per above code, it shows:
- Per (1) the --no-launch-chrome is set to true if web, but per (3)(4) it is not passed to startApp, that is, below expression is always true
final bool launchChrome = platformArgs['no-launch-chrome'] != true; - However, even the --no-launch-chrome is passed correctly, the code will exit with error, as there exists isAppStarted check
flutter/packages/flutter_tools/lib/src/drive/web_driver_service.dart
Lines 117 to 119 in 6af40a7
if (!isAppStarted) { throw ToolExit('Failed to start application'); }


Activity
darshankawar commentedon Mar 21, 2022
@zpsean
I tried to replicate the scenario you mentioned but don't get to see two chrome instances being launched. I see only one as expected:
I am on latest stable (2.10.3) and used the steps as-is mentioned in the link you shared.
zpsean commentedon Mar 21, 2022
@darshankawar Mostly, the two Chromes are overlaid, please try to drag it away (up or down), then back one would be visible.
I'm running on macOS, with latest stable (2.10.3). And this can be reproduced by my mates.
darshankawar commentedon Mar 21, 2022
Thanks. I tried the same but don't see same behavior. Please confirm if the interpretation is not correct to replicate it properly:
100447.mov
zpsean commentedon Mar 21, 2022
Please refer to my screen capture, as my mac may be slow, give me chance to capture them.
flutter_drive_two_chromes.mp4
zpsean commentedon Mar 21, 2022
@darshankawar
I know the reason we got different results. Sorry, I provided the wrong command in original post, below is the one real used
Please be noticed that one of the Chrome has labelled 'chrome is controlled by automated test software', the other is not
More, if use below command, the Chrome opened by chromediver is in headless mode
Which means, in my understanding, the Chrome in your run is the Chrome which is opened as device, but not the one intend to be used as test (i.e. opened via chromedriver).
[-][Web][Integration Test] Two Chrome instances launched, and the unnecessary Chrome instance breaks the foundation of the integration test[/-][+][Web][Integration Test] Two Chrome instances launched, and the unnecessary Chrome instance breaks the foundation of the integration test [Edited][/+]zpsean commentedon Mar 22, 2022
#148915 is raised against the user doc https://docs.flutter.dev/cookbook/testing/integration/introduction, to avoid the misleading.
darshankawar commentedon Mar 22, 2022
Thanks @zpsean for providing detailed updates on the issue. I think this is an interesting find and do see the same behavior , ie, of two chrome instances being opened when running below command:
stable, master flutter doctor -v
darshankawar commentedon Mar 22, 2022
/cc @jiahaog
jiahaog commentedon Mar 22, 2022
Apologies, I'm not familiar with this, @yjbanov would you know more?
zpsean commentedon Mar 24, 2022
@darshankawar @yjbanov, any further comments on this?
yjbanov commentedon Mar 24, 2022
This is a duplicate of #67090
zpsean commentedon Mar 25, 2022
@yjbanov @darshankawar this key point of this issue i want to address is that expecting the Chrome (as device) is not to be opened. In #67090, it is stated as harmless but confusing, but I think, as stated in original post, is harmful, as we can Not reply on the real test results with the Chrome existence (device one).
Both Chrome instances have test executed. However, the Chrome is launched not via chromedriver has major negative impact to test:
For js, css loading, increase the networking pressure as need to load two copies
For some write, delete scenarios, the test will result in unexpected results (as two Chromes both will try to execute delete action)
zpsean commentedon Mar 25, 2022
We can have more discussion how two use option -d and --browser-name, maybe to prevent the Chrome (as device) to be opened have high priority as its impact (negative) to test .
github-actions commentedon Apr 8, 2022
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 -vand a minimal reproduction of the issue.