Repository navigation
unit-test: browser-mode runs stall ("iframe did not become ready") when a Docker container starts alongside #34390
Description
Command
test
Is this a regression?
- Yes, this behavior used to work in the previous version
The previous version in which this bug was not present was
No response
Description
With "browsers": ["chromiumHeadless"] and @vitest/browser-playwright, ng test stalls in roughly 4 runs of 10 when a Docker container starts while the tests start up. That is what happens when another package of a workspace runs integration tests with Testcontainers at the same time. A few test iframes load Vitest's runtime and never request the Angular test setup (init-testbed.js) or their spec chunks; after 60 s the run fails.
On a fresh ng new app with six generated components:
| runs | stalled | |
|---|---|---|
ng test |
15 | 0 |
ng test with docker run -d alpine:3 sleep 8 starting beside it |
47 | 21 |
| plain Vitest browser mode (no Angular builder), seven trivial files, same container | 11 | 0 |
The last row (on Vitest 5.0.4; the others on 5.0.4 and 5.0.5 alike) is why I am filing it here rather than with Vitest. Ruled out on the same machine: CPU load (all 16 cores busy), synchronous disk writes, touching a source file mid-run, the image or a published port (alpine sleep is enough), and the headless shell itself (the full Chromium build stalls too, less often). Chromium logs no failed request and no console error, and a page opening ~1000 fresh connections to localhost while a container starts loses none.
With DEBUG=vitest:browser:*, all seven sessions connect to the tester API at the same moment, then only two send their first command (__vitest_viewport); the other five stay silent until the 60 s timeout. A Vite request trace (DEBUG=vite:time) of a stalled run shows those five iframes fetched index, plugins and rolldown-runtime from the optimized deps and nothing after; a passing run goes on to init-compiler.js, init-testbed.js, the Angular deps and the spec files.
It may be the same family as vitest-dev/vitest#11171 (a rejected import inside the tester iframe never fires iframe.onerror, so the orchestrator waits until the timeout), closed there for want of a reproduction.
Minimal Reproduction
npx @angular/cli@22.2.3 new ng-docker-stall --defaults --skip-git --ssr=false --style=css
cd ng-docker-stall
for c in alpha bravo charlie delta echo foxtrot; do npx ng g c "$c"; done
npm install -D --save-exact vitest@5.0.5 @vitest/browser-playwright@5.0.5 playwright@1.64.1
npx playwright install --only-shell chromium
npx ng config projects.ng-docker-stall.architect.test.options.browsers '["chromiumHeadless"]'
npx ng test # passesThen, with Docker running, this script, ./stall.sh 10:
#!/bin/sh
# Runs `ng test` several times while a Docker container starts beside it, and
# counts the runs whose test iframes stall.
runs=${1:-5}
stalled=0
for i in $(seq 1 "$runs"); do
(id=$(docker run -d alpine:3 sleep 8); sleep 9; docker rm -f "$id" > /dev/null) &
if npx ng test 2>&1 | grep -q 'did not become ready'; then
stalled=$((stalled + 1))
echo "run $i: stalled"
else
echo "run $i: passed"
fi
wait
done
echo "$stalled of $runs runs stalled"Expected: every run passes, as without the container. Actual: some runs stall and fail after 60 s.
Exception or Error
⎯⎯⎯⎯⎯⎯ Unhandled Error ⎯⎯⎯⎯⎯⎯⎯
Error: Failed to run the test /…/ng-docker-stall/src/app/echo/echo.spec.ts.
❯ process.processTicksAndRejections node:internal/process/task_queues:104:5
Caused by: Error: The iframe "__vitest_all__" did not become ready within 60000ms. The tester likely failed to initialize, check the browser console for errors.
❯ ../../../../../../../__vitest_browser__/orchestrator-C2U7TVD1.js:198:28
Test Files (7)
Tests no tests
Errors 1 error
Duration 61.05s
Your Environment
Angular CLI : 22.2.3
Angular : 22.2.3
Node.js : 24.22.0
Package Manager : npm 11.19.1
Operating System : linux x64
┌───────────────────────────┬───────────────────┬───────────────────┐
│ Package │ Installed Version │ Requested Version │
├───────────────────────────┼───────────────────┼───────────────────┤
│ @angular/build │ 22.2.3 │ ^22.2.3 │
│ @angular/cli │ 22.2.3 │ ^22.2.3 │
│ @angular/common │ 22.2.3 │ ^22.2.0 │
│ @angular/compiler │ 22.2.3 │ ^22.2.0 │
│ @angular/compiler-cli │ 22.2.3 │ ^22.2.0 │
│ @angular/core │ 22.2.3 │ ^22.2.0 │
│ @angular/forms │ 22.2.3 │ ^22.2.0 │
│ @angular/platform-browser │ 22.2.3 │ ^22.2.0 │
│ @angular/router │ 22.2.3 │ ^22.2.0 │
│ rxjs │ 7.8.2 │ ~7.8.0 │
│ typescript │ 6.0.3 │ ~6.0.2 │
│ vitest │ 5.0.5 │ 5.0.5 │
└───────────────────────────┴───────────────────┴───────────────────┘
Anything else relevant?
@vitest/browser-playwright5.0.5,playwright1.64.1 (Chrome Headless Shell 156.0.8078.4). Only Chromium was tried.- Ubuntu 26.04.1 LTS, Linux 7.0.0, Docker 29.9.1 (native engine, cgroup v2).
- The workaround we use is running the workspace's packages one after another, so no container starts while the browser tests run.
Activity
MeAkib commentedon Oct 18, 2026
Does ng test --isolate still stall, and does plain Vitest stall with isolate: false?
Does the browser console or network log show net::ERR_NETWORK_CHANGED (container start adds network interfaces, and Chromium aborts in-flight requests on network changes), or a 504 "Outdated Optimize Dep" response (with DEBUG=vite:*), as in vitest-dev/vitest#11171?
andsouto commentedon Oct 18, 2026
Thanks,
ERR_NETWORK_CHANGEDwas it, and it isn't a builder bug: I've reported it to Vitest as vitest-dev/vitest#11636.Starting a container changes the host's IP addresses, and Chromium then aborts module requests in flight to the dev server. In the stalled runs, all of them were Vitest's and Vite's own modules, and there was no 504. When one of the tester's modules fails to load, Vitest waits out the 60 s iframe timeout instead of failing. Failing one of those requests on purpose stalls plain Vitest the same way, with or without
isolate, and that's the reproduction in the Vitest issue. Angular's testers load more modules, so they get caught more often, which is why plain Vitest looked unaffected next to a container.ng test --isolatestalls as well, in 1 run of 10.One correction to my report: the builder sets its own Playwright provider when
browsersis set, so the Chromium flags I passed throughrunnerConfignever reached the browser. The "no failed request" check and the "full Chromium" runs didn't test what they said.Closing this in favour of the Vitest issue.