You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
flutter drive options -d and --browser-name have confusing behavior #67090
Currently if you run flutter drive -d chrome (and likely -d edge) but without --browser-name we will run the web test and succeed. However, there are two issues with this:
We already have a way to specify the browser when running driver tests --browser-name=BROWSER, so why is -d chrome allowed?
When running with -d chrome you will see the browser opened once, closed immediately, then opened again. It's ultimately harmless but confusing. (hypothesis: the first browser is opened by Flutter tool's existing logic for launching browsers for flutter run, and the second browser is launched by WebDriver).
It is also possible to run with --browser-name but without -d, but that will attempt to run an Android test, which may produce false positives (you think your web test succeeded but you actually ran an Android test).
Possible solution: only use the -d BROWSER and make it consistent with flutter run. Bypass Flutter tool's browser launching logic and delegate to WebDriver.
Reacted by David Iglesias, Robert Gersak, garrettApproachableGeek, Hue, emmapejko, Ivanro Lagazo, Donald Taylor, shawnAshton, David Richboy Echomgbe, s-khalid104 and 11 more
changed the title [-]`flutter drive` should not accept `-d BROWSER`[/-][+]`flutter drive` options `-d` and `--browser-name` have confusing behavior[/+]on Oct 1, 2020
@yjbanov@darshankawar this key point of the issue #100447 to address is that expecting the Chrome (as device) is not to be opened. In this post, it is stated as harmless but confusing, but I think, as stated in #100447 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)
Reacted by Zachary Bohn, Muayad Alrazehi and David Iglesias
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 .
Under the current running of integration tests on chrome the tests always run twice and there is no way to only run once. This can cause tests that should pass to fail as shown on #102250
Reacted by Hui Zhao, Zachary Bohn, Pavel, desmond206x, Muayad Alrazehi, Ph10 and Mihai-Alexandru Priboiu
This is causing duplicate writes to firestore in my integration tests.
The way that our company has gotten around this is to just add the Android platform and run the tests from there. It's more work, but at least the tests are able to run successfully.
This is causing duplicate writes to firestore in my integration tests.
The way that our company has gotten around this is to just add the Android platform and run the tests from there. It's more work, but at least the tests are able to run successfully.
Thanks for sharing this.
We actually now have Mac and windows versions of the app, but are still concerned about web specific behavior and libraries
This is causing duplicate writes to firestore in my integration tests.
The way that our company has gotten around this is to just add the Android platform and run the tests from there. It's more work, but at least the tests are able to run successfully.
Thanks for sharing this.
We actually now have Mac and windows versions of the app, but are still concerned about web specific behavior and libraries
As kindly suggested by @ZacharyBohn, I started relying on desktop tests. Unfortunately, due to some libraries (ex. riverpod) behaving differently on web, it resulted in a pretty broken app being deployed, despite successful desktop integration tests.
It's clear that running tests on other platforms does not ensure that the web app will function.
This issue seems to be a huge bottleneck in creating production grade web apps with flutterfire.
This is causing duplicate writes to firestore in my integration tests.
I finally came up with a workaround to "pause" the duplicate test, and then exit the duplicate when the original test completes:
Before starting your tests, create a firestore document with a specific id (ex. 'flag')
In each test, check if the document exists.
a. The document exists: Delete it and continue the test. After the test, add the document back.
b. the document doesn't exist: Stream the collection and wait for the document to be added. When it is added, exit the function (do not continue the test).
Basically this makes sure only the first test actually runs through, and the second test skips the actual testing and completes successfully once the first test completes (it is waiting for the first test to add the document back.
It's a bit messy, but it works, and web testing is SUPER important because many packages behave differently on web and relying on other platforms for testing will likely result in shipping buggy web apps (I learned this the hard way after only testing on mac and windows for the past few months).
Here is the code I use to wrap each test:
Future<void> webTestWrapper(Future<void> Function() theTest) async {
await Firebase.initializeApp(options: DefaultFirebaseOptions.currentPlatform);
if (kIsWeb) {
//get document 'flag' from collection 'flag'
var doc = await FirestoreService.get().getDocument('flag', 'flag');
if (doc == null) {
//the doc was already deleted, so this is the duplicate test
var waiting = true;
//stream collection 'flag', stop waiting when the document is back
stream = await FirestoreService.get().stream('flag', (docs) {
if (doc?['testflag'] == true) {
waiting = false;
}
});
while (waiting) {
await Future.delayed(const Duration(milliseconds: 500));
}
await stream?.cancel();
//original test completed, exit this duplicate test
return;
}
//this is the original test, delete the flag document
await FirestoreService.get().deleteDocument('flag', 'flag');
}
//run the actual tests
await theTest();
if (kIsWeb) {
//original test complete, add the flag document back for the next test, and to exit the duplicate test
var doc = await FirestoreService.get()
.addDocument('flag', {'testflag': true}, 'flag');
}
}
This is causing duplicate writes to firestore in my integration tests.
I finally came up with a workaround to "pause" the duplicate test, and then exit the duplicate when the original test completes:
Before starting your tests, create a firestore document with a specific id (ex. 'flag')
In each test, check if the document exists.
a. The document exists: Delete it and continue the test. After the test, add the document back.
b. the document doesn't exist: Stream the collection and wait for the document to be added. When it is added, exit the function (do not continue the test).
Basically this makes sure only the first test actually runs through, and the second test skips the actual testing and completes successfully once the first test completes (it is waiting for the first test to add the document back.
It's a bit messy, but it works, and web testing is SUPER important because many packages behave differently on web and relying on other platforms for testing will likely result in shipping buggy web apps (I learned this the hard way after only testing on mac and windows for the past few months).
Here is the code I use to wrap each test:
Future<void> webTestWrapper(Future<void> Function() theTest) async {
await Firebase.initializeApp(options: DefaultFirebaseOptions.currentPlatform);
if (kIsWeb) {
//get document 'flag' from collection 'flag'
var doc = await FirestoreService.get().getDocument('flag', 'flag');
if (doc == null) {
//the doc was already deleted, so this is the duplicate test
var waiting = true;
//stream collection 'flag', stop waiting when the document is back
stream = await FirestoreService.get().stream('flag', (docs) {
if (doc?['testflag'] == true) {
waiting = false;
}
});
while (waiting) {
await Future.delayed(const Duration(milliseconds: 500));
}
await stream?.cancel();
//original test completed, exit this duplicate test
return;
}
//this is the original test, delete the flag document
await FirestoreService.get().deleteDocument('flag', 'flag');
}
//run the actual tests
await theTest();
if (kIsWeb) {
//original test complete, add the flag document back for the next test, and to exit the duplicate test
var doc = await FirestoreService.get()
.addDocument('flag', {'testflag': true}, 'flag');
}
}
Yeah we tried something similar and got it to work. I appreciate you sharing your work around!
Just seems super crazy that the Flutter team put a double instance of the app into the codebase. Now we have to use weird arounds. Flutter web is not stable, despite what is claimed.
Tests will be executed twice for web.. 4 years and still no solution for this?
I wasted more than one day to find this issue, because I debugged all of our code until I found out, that we start the flutter drive command with -d chrome in some cases.
Wrap-up: flutter drive --driver=test_driver\test_driver.dart --target=integration_test\example_test.dart -d chrome --browser-name chrome -> Runs the test twice. One Chrome instance is visible. One hidden?
flutter drive --driver=test_driver\test_driver.dart --target=integration_test\example_test.dart -d web-server --browser-name chrome --no-headless -> Runs the test only once. Chrome instance is visible.
The command flutter drive --driver=test_driver/test_driver.dart --target=integration_test/example_test.dart -d web-server --browser-name chrome --no-headless has been functioning correctly in our company for over two years and across hundreds of test cases.
so I am pretty sure -d web-server --browser-name is the answer, hope it can helps.
Activity
[-]`flutter drive` should not accept `-d BROWSER`[/-][+]`flutter drive` options `-d` and `--browser-name` have confusing behavior[/+]zpsean commentedon Mar 25, 2022
@yjbanov @darshankawar this key point of the issue #100447 to address is that expecting the Chrome (as device) is not to be opened. In this post, it is stated as
harmless but confusing, but I think, as stated in #100447 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 .
garrettApproachableGeek commentedon Apr 22, 2022
Under the current running of integration tests on chrome the tests always run twice and there is no way to only run once. This can cause tests that should pass to fail as shown on #102250
ariCETester commentedon Jun 22, 2022
I am running into this as well. Integration tests interact with a dynamo DB on AWS. The duplicate writing and deleting is a real problem.
workaround for integration_test running 2x flutter/flutter#67090. The…
8 remaining items
ZacharyBohn commentedon Apr 20, 2023
The way that our company has gotten around this is to just add the Android platform and run the tests from there. It's more work, but at least the tests are able to run successfully.
Justus-M commentedon Jun 30, 2023
Thanks for sharing this.
We actually now have Mac and windows versions of the app, but are still concerned about web specific behavior and libraries
Justus-M commentedon Jul 25, 2023
As kindly suggested by @ZacharyBohn, I started relying on desktop tests. Unfortunately, due to some libraries (ex. riverpod) behaving differently on web, it resulted in a pretty broken app being deployed, despite successful desktop integration tests.
It's clear that running tests on other platforms does not ensure that the web app will function.
This issue seems to be a huge bottleneck in creating production grade web apps with flutterfire.
Are there any updates on this?
Justus-M commentedon Sep 15, 2023
I finally came up with a workaround to "pause" the duplicate test, and then exit the duplicate when the original test completes:
Basically this makes sure only the first test actually runs through, and the second test skips the actual testing and completes successfully once the first test completes (it is waiting for the first test to add the document back.
It's a bit messy, but it works, and web testing is SUPER important because many packages behave differently on web and relying on other platforms for testing will likely result in shipping buggy web apps (I learned this the hard way after only testing on mac and windows for the past few months).
Here is the code I use to wrap each test:
MoaidAlrazhy commentedon May 21, 2024
flutter drive --driver="test_driver/integration_test.dart" --target="integration_test/integration_test.dart" -d web-server --no-headless
seems valid work around to run a single instance.
ZacharyBohn commentedon May 23, 2024
Yeah we tried something similar and got it to work. I appreciate you sharing your work around!
Just seems super crazy that the Flutter team put a double instance of the app into the codebase. Now we have to use weird arounds. Flutter web is not stable, despite what is claimed.
desmond206x commentedon Sep 13, 2024
Tests will be executed twice for web.. 4 years and still no solution for this?
I wasted more than one day to find this issue, because I debugged all of our code until I found out, that we start the
flutter drivecommand with -d chrome in some cases.Wrap-up:
flutter drive --driver=test_driver\test_driver.dart --target=integration_test\example_test.dart -d chrome --browser-name chrome-> Runs the test twice. One Chrome instance is visible. One hidden?flutter drive --driver=test_driver\test_driver.dart --target=integration_test\example_test.dart -d web-server --browser-name chrome --no-headless-> Runs the test only once. Chrome instance is visible.linchen2chris commentedon Sep 26, 2024
The command
flutter drive --driver=test_driver/test_driver.dart --target=integration_test/example_test.dart -d web-server --browser-name chrome --no-headlesshas been functioning correctly in our company for over two years and across hundreds of test cases.so I am pretty sure
-d web-server --browser-nameis the answer, hope it can helps.Justus-M commentedon Aug 27, 2025
This is still an issue that prevents integration tests on web from working properly.
We tried -d web-server --browser-name and it works, but then you don't have any logs/prints which also makes it pretty unusable.
Since web now supports hot reload it seems like it is getting some more love - Maybe now is the time to fix integration tests? @darshankawar @kevmoo
blazetill commentedon Oct 2, 2025
I found a workaround for the duplicate browser issue
The Issue
flutter drive -d chromelaunches two browser instances:Both run the same tests, causing duplicate execution.
Workaround
Add user agent detection to kill the HeadlessChrome duplicate instance early in your integration test: