Browser mode hangs at "0 passed" when a test file path contains a "+" (original) (raw)
Describe the bug
When the absolute path of a test file contains a +, browser mode hangs forever at Test Files 0 passed with no error. The browser launches and the orchestrator loads, but no test ever runs until the process is killed.
Root cause: createTestIframe in packages/browser/src/client/orchestrator.ts interpolates the test-file path (iframeId) into the tester iframe URL query without encoding:
const src = `/?sessionId=${getBrowserState().sessionId}&iframeId=${iframeId}`The tester reads it back with new URL(location.href).searchParams.get('iframeId'). A + in a URL query component is decoded as a space, so the tester's iframeId (…/a b.test.ts) no longer matches the one the orchestrator sends in its prepare/execute events (…/a+b.test.ts). The tester ignores every event, the orchestrator's prepare promise never resolves, and the run hangs.
This hits any project whose path contains a + — e.g. a git worktree named feat+whatever-…. Confirmed on main and v4.1.8.
Reproduction
https://github.com/Pduhard/vitest-browser-hang-plus-path
pnpm install
pnpm exec playwright install chromium
pnpm testThe repo contains a single test file named a+b.test.ts, so its absolute path always contains a + wherever it is cloned.
- Expected: the test in
a+b.test.tsruns and passes. - Actual: the run hangs forever at
Test Files 0 passed/Tests 0 passed. - Control: renaming the file to
ab.test.ts(no+) makes it pass in ~1s.
System Info
System: OS: macOS 26.3 CPU: (10) arm64 Apple M5 Memory: 24.00 GB Shell: 5.9 - /bin/zsh Binaries: Node: 22.22.1 npm: 10.9.4 pnpm: 10.28.0 Browsers: Chrome: 148.0.7778.215 Safari: 26.3 npmPackages: @vitest/browser-playwright: 4.1.8 => 4.1.8 playwright: 1.60.0 => 1.60.0 vitest: 4.1.8 => 4.1.8
Used Package Manager
pnpm
Validations
- Follow our Code of Conduct
- Read the Contributing Guidelines.
- Read the docs.
- Check that there isn't already an issue that reports the same bug to avoid creating a duplicate.
- Check that this is a concrete bug. For Q&A open a GitHub Discussion or join our Discord Chat Server.
- The provided reproduction is a minimal reproducible example of the bug.