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
[BUG] webServer.reuseExistingServer is broken on node 18 #24101
Clone this repo and using your shell of choice navigate to the root of the repo.
Execute npm start. This will build and run an angular app.
Once the angular app is running, execute npm test
When running with node 16.19.1 the output after step 3 is:
> [email protected] test
> npx playwright test
Running 1 test using 1 worker
✓ 1 [chromium] › example.spec.ts:3:5 › dummy test (1.8s)
1 passed (2.6s)
When running with node 18.16.0 the output after step 3 is:
> [email protected] test
> npx playwright test
[WebServer] ? Port 4200 is already in use.
Would you like to use a different port? (Y/n) [WebServer]
Error: Timed out waiting 30000ms from config.webServer.
As you can see, it tries to execute the webServer.command and then eventually times out because the port is already taken.
Expected
When running on node 18.16.0 it should NOT try to execute the webServer.command when webServer.reuseExistingServer is set to true.
Actual
When running on node 18.16.0 it executes the webServer.command when webServer.reuseExistingServer is set to true.
Other
I used nvm to swap between node versions whilst testing this.
Since you're running with node 18.6.1, I've installed that version but I still get the same problem:
> [email protected] test
> npx playwright test
[WebServer] ? Port 4200 is already in use.
Would you like to use a different port? (Y/n) [WebServer]
Error: Timed out waiting 30000ms from config.webServer.
I'm running on Windows build 10.0.19045.0 and through powershell 7.3.5. Any thoughts?
I would guess that the problem is due to the ipv4 vs ipv6 mismatch, Node migrated to ipv6 in Node 18. So if you are already running ng on ipv4 elsewhere, it could probably manifest this way. But I'm trying this on Linux and it works fine. I ran npx ng serve --port 4200 on Node 16 and then ran tests on Node 18.
Hum... On my windows machine if I try to use the demo repo I provided on this issue and from the root of the repo I run:
docker run -it --rm --ipc=host --workdir=/app -v "$(Get-Location):/app" mcr.microsoft.com/playwright:v1.35.1-jammy npx playwright test
I still get an error that indicates that Playwright is trying to execute the webServer.command:
[WebServer] - Generating browser application bundles (phase: setup)...
Error: Timed out waiting 30000ms from config.webServer.
P.S: I do know that I didn't start anything on port 4000 inside the container so it would always timeout eventually, but I shouldn't see the message from the WebServer trying to execute the command instruction with will do ng serve and is where that Generating browser application bundles (phase: setup)... message comes from.
It does seem that Playwright tries to execute the webServer.command if I run this docker command from Windows:
docker run -it --rm --ipc=host --workdir=/app -v "$(Get-Location):/app" mcr.microsoft.com/playwright:v1.35.1-jammy npx playwright test .
I'm saying it seems to because otherwise I can't explain that WebServer log message which comes from ng serve.
However, if I do:
docker run -it --rm --ipc=host --workdir=/app -v "$(Get-Location):/app" mcr.microsoft.com/playwright:v1.35.1-jammy
This gets me into a shell in the docker container so now I can run some commands
I start the server by running npx ng serve --port 4200 & which outputs:
root@adfd8d17e006:/app# npx ng serve --port 4200 &
[1] 9
✔ Browser application bundle generation complete.
Initial Chunk Files | Names | Raw Size
vendor.js | vendor | 1.97 MB |
polyfills.js | polyfills | 333.15 kB |
styles.css, styles.js | styles | 230.67 kB |
main.js | main | 45.98 kB |
runtime.js | runtime | 6.51 kB |
| Initial Total | 2.58 MB
Build at: 2023-07-07T17:25:59.983Z - Hash: 315d6fa9a434d37b - Time: 4745ms
** Angular Live Development Server is listening on localhost:4200, open your browser on http://localhost:4200/ **
✔ Compiled successfully.
I run a wget to see that the app is running fine wget http://localhost:4200:
Ran Playwright tests via Docker but setting a gateway that allows Docker to talk with the app running on my Windows host:
docker run -it --rm --ipc=host --add-host=host.docker.internal:host-gateway --env USE_DOCKER_HOST_WEBSERVER=true --workdir=/app -v "$(Get-Location):/app" mcr.microsoft.com/playwright:v1.35.1-jammy npx playwright test
Using node 16 ON MY WINDOWS HOST, the docker test command works as expected. When using node 18 ON MY WINDOWS HOST the docker test command fails because Playwright tries to execute the webServer.commandON THE DOCKER CONTAINER.
Here's some images:
Working fine with Node 16:
A) Run the app
B) Run the tests via Docker that will connect to the app running on the host. All works as expected.
Fails in Node 18:
A) Run the app
B) Run the tests via Docker that will connect to the app running on the host. Tests fail because tries to execute the webServer.command.
P.S. - the commit I did to allow this docker connectivity from inside docker container to the app running on docker's host doesn't impact the reproducibility of the bug using the demo repo when running without docker. Following the steps initially describe on this issue still result in error for me when running on Windows.
I did not realize there was docker involved in your setup. To re-iterate, the main thing that happened in Node 18 which is different from Node 16 is that the ports are now bound using ipv6 by default. So when you bind :4000, it is [:1]:4000, not 127.0.0.1:4000 anymore. Those are different ports, even though the port number is the same. Browsers (and Playwright) are using technology called Happy Eyeballs to mitigate that, but I'm not sure how this goes through the docker boundary.
Pavel Feldman (@pavelfeldman) note that on the original description of the issue there is no Docker involved. For me the issue happens without Docker and running on Windows just by swapping from node 16 to 18.
I did further testing using Docker after you pointed out you couldn't replicate the issue on linux.
EDIT:
Can you replicate what I saw in this comment for instance? I don't understand why it seems Playwright seems to execute the webServer.command.
Pavel Feldman (@pavelfeldman) I think part of the issue was that I didn't understand that webServer.reuseExistingServer will fallback to execute the webServer.command if it can't get to the specified webServer.url. As noted in the webServer.reuseExistingServer documentation:
If true, it will re-use an existing server on the port or url when available. If no server is running on that port or url, it will run the command to start a new server. If false, it will throw if an existing process is listening on the port or url. This should be commonly set to !process.env.CI to allow the local dev server when running tests locally.
The other part of this issue is very likely related to the change you've mentioned about the fact that Node migrated to ipv6 in Node 18. Somehow that is affecting the way Playwright tries to check if the webServer.url is up and running and then falls back to executing the webServer.command.
And you were absolutely right regarding the root cause Pavel Feldman (@pavelfeldman) . Thank you very much for pointing me in the right direction.
On the package.json I changed the npm start command so that it would bind specifically to 127.0.0.1 by passing a --host flag to the ng serve command:
"start": "npx ng version && npx ng serve --host=127.0.0.1 --port 4200 -o",
And then running npm test or via docker with docker run -it --rm --ipc=host --add-host=host.docker.internal:host-gateway --env USE_DOCKER_HOST_WEBSERVER=true --workdir=/app -v "$(Get-Location):/app" mcr.microsoft.com/playwright:v1.35.1-jammy npx playwright test, everything works as expected.
I just noticed that you were using 127.0.0.1 explicitly in your config. Switching it to localhost would trigger all those happy eyeballs paths. But I would recommend keeping it as you have it as it makes everything simpler for both browser and Playwright.
Activity
pavelfeldman commentedon Jul 7, 2023
Here is what I get on Node 18:
edumserrano commentedon Jul 7, 2023
Since you're running with node
18.6.1, I've installed that version but I still get the same problem:I'm running on Windows build
10.0.19045.0and through powershell7.3.5. Any thoughts?pavelfeldman commentedon Jul 7, 2023
I would guess that the problem is due to the ipv4 vs ipv6 mismatch, Node migrated to ipv6 in Node 18. So if you are already running ng on ipv4 elsewhere, it could probably manifest this way. But I'm trying this on Linux and it works fine. I ran
npx ng serve --port 4200on Node 16 and then ran tests on Node 18.edumserrano commentedon Jul 7, 2023
Hum... On my windows machine if I try to use the demo repo I provided on this issue and from the root of the repo I run:
docker run -it --rm --ipc=host --workdir=/app -v "$(Get-Location):/app" mcr.microsoft.com/playwright:v1.35.1-jammy npx playwright testI still get an error that indicates that Playwright is trying to execute the
webServer.command:P.S: I do know that I didn't start anything on port 4000 inside the container so it would always timeout eventually, but I shouldn't see the message from the WebServer trying to execute the
commandinstruction with will dong serveand is where thatGenerating browser application bundles (phase: setup)...message comes from.edumserrano commentedon Jul 7, 2023
Well, there's something weird going on.
It does seem that Playwright tries to execute the
webServer.commandif I run this docker command from Windows:docker run -it --rm --ipc=host --workdir=/app -v "$(Get-Location):/app" mcr.microsoft.com/playwright:v1.35.1-jammy npx playwright test.I'm saying it seems to because otherwise I can't explain that
WebServerlog message which comes fromng serve.However, if I do:
docker run -it --rm --ipc=host --workdir=/app -v "$(Get-Location):/app" mcr.microsoft.com/playwright:v1.35.1-jammynpx ng serve --port 4200 &which outputs:wgetto see that the app is running finewget http://localhost:4200:npx playwright testand it works as expected, it didn't try to execute thewebServer.command:edumserrano commentedon Jul 7, 2023
I'm so confused right now as to what might be causing this 😵 . So here's what I did:
webServer.commandON THE DOCKER CONTAINER.Here's some images:
Working fine with Node 16:
A) Run the app

B) Run the tests via Docker that will connect to the app running on the host. All works as expected.

Fails in Node 18:
A) Run the app

B) Run the tests via Docker that will connect to the app running on the host. Tests fail because tries to execute the

webServer.command.P.S. - the commit I did to allow this docker connectivity from inside docker container to the app running on docker's host doesn't impact the reproducibility of the bug using the demo repo when running without docker. Following the steps initially describe on this issue still result in error for me when running on Windows.
pavelfeldman commentedon Jul 7, 2023
I did not realize there was docker involved in your setup. To re-iterate, the main thing that happened in Node 18 which is different from Node 16 is that the ports are now bound using ipv6 by default. So when you bind :4000, it is [:1]:4000, not 127.0.0.1:4000 anymore. Those are different ports, even though the port number is the same. Browsers (and Playwright) are using technology called Happy Eyeballs to mitigate that, but I'm not sure how this goes through the docker boundary.
edumserrano commentedon Jul 7, 2023
Pavel Feldman (@pavelfeldman) note that on the original description of the issue there is no Docker involved. For me the issue happens without Docker and running on Windows just by swapping from node 16 to 18.
I did further testing using Docker after you pointed out you couldn't replicate the issue on linux.
EDIT:
Can you replicate what I saw in this comment for instance? I don't understand why it seems Playwright seems to execute the
webServer.command.edumserrano commentedon Jul 7, 2023
Pavel Feldman (@pavelfeldman) I think part of the issue was that I didn't understand that
webServer.reuseExistingServerwill fallback to execute thewebServer.commandif it can't get to the specifiedwebServer.url. As noted in thewebServer.reuseExistingServerdocumentation:The other part of this issue is very likely related to the change you've mentioned about the fact that Node migrated to ipv6 in Node 18. Somehow that is affecting the way Playwright tries to check if the
webServer.urlis up and running and then falls back to executing thewebServer.command.edumserrano commentedon Jul 7, 2023
And you were absolutely right regarding the root cause Pavel Feldman (@pavelfeldman) . Thank you very much for pointing me in the right direction.
On the
package.jsonI changed thenpm startcommand so that it would bind specifically to127.0.0.1by passing a--hostflag to theng servecommand:And then running
npm testor via docker withdocker run -it --rm --ipc=host --add-host=host.docker.internal:host-gateway --env USE_DOCKER_HOST_WEBSERVER=true --workdir=/app -v "$(Get-Location):/app" mcr.microsoft.com/playwright:v1.35.1-jammy npx playwright test, everything works as expected.Feel free to close this issue.
pavelfeldman commentedon Jul 7, 2023
I just noticed that you were using 127.0.0.1 explicitly in your config. Switching it to
localhostwould trigger all those happy eyeballs paths. But I would recommend keeping it as you have it as it makes everything simpler for both browser and Playwright.