Skip to content

fix(browser): remove orphaned Playwright route when same module is mocked via multiple ids (fix #9957)#10267

Merged
sheremet-va merged 3 commits into
vitest-dev:mainfrom
Zelys-DFKH:fix/browser-playwright-duplicate-mock-routes
May 8, 2026
Merged

fix(browser): remove orphaned Playwright route when same module is mocked via multiple ids (fix #9957)#10267
sheremet-va merged 3 commits into
vitest-dev:mainfrom
Zelys-DFKH:fix/browser-playwright-duplicate-mock-routes

Conversation

@Zelys-DFKH

@Zelys-DFKH Zelys-DFKH commented May 4, 2026

Copy link
Copy Markdown
Contributor

Fixes #9957.

Description

If you call vi.mock('~/modal') and vi.mock('./modal') in the same test file, and both aliases resolve to the same URL, createMocker() in playwright.ts registers two Playwright routes. The second call overwrites the predicate in idPredicates without removing the first route. When clear() runs at the end of the file, it only finds the second predicate -- the first route stays attached to the browser context.

That orphaned route fires when the next test file loads the same module. Its handler calls module.resolve() through a birpc channel that belongs to the previous session, which is already closed. That's where [birpc] rpc is closed comes from.

playwright.ts: before registering a route for a session+URL, check idPredicates for an existing predicate and unroute() it first. Switched sessionIds from string[] to Set<string> so URL entries can't duplicate and clear() removes each route exactly once.

Testing

Added test/browser/fixtures/mocking/src/dual-id/ with a source module, a consumer that imports it via the alias, and two test files. The probe registers the module through both ~/dual-id/modal and ./dual-id/modal. The target (same browser session, runs after) asserts the real implementation is visible. Without this fix, the target crashes with [birpc] rpc is closed; with it, the mock is cleaned up between files.

PROVIDER=playwright BROWSER=chromium corepack pnpm -C test/browser exec vitest run --config vitest.config.unit.mts specs/mocking.test.ts -t 'manual mocks do not leak'

@netlify

netlify Bot commented May 4, 2026

Copy link
Copy Markdown

Deploy Preview for vitest-dev ready!

Built without sensitive environment variables

Name Link
🔨 Latest commit 7915a41
🔍 Latest deploy log https://app.netlify.com/projects/vitest-dev/deploys/69f8d969e0004b0008da3a75
😎 Deploy Preview https://deploy-preview-10267--vitest-dev.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.
🤖 Make changes Run an agent on this branch

To edit notification comments on pull requests, go to your Netlify project configuration.

}
return rpc().onCollected(this.method, files)
const result = await rpc().onCollected(this.method, files)
if (this.method === 'collect') {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think there are any tests that cover test collection with mocking (this is collect only in vitest list command)

@Zelys-DFKH

Copy link
Copy Markdown
Contributor Author

Good catch. Removed the runner.ts change. It was addressing a separate scenario (routes not invalidated after vitest list) with no test coverage, and it's out of scope for #9957. The core fix lives entirely in playwright.ts. I can file a separate issue for the collect path if that'd be useful.

@sheremet-va sheremet-va changed the title fix(browser-playwright): remove orphaned Playwright route when same module is mocked via multiple ids (fix #9957) fix(browser): remove orphaned Playwright route when same module is mocked via multiple ids (fix #9957) May 8, 2026
@sheremet-va sheremet-va merged commit 41db6ce into vitest-dev:main May 8, 2026
15 of 17 checks passed
@sheremet-va

Copy link
Copy Markdown
Member

Thanks!

@Zelys-DFKH

Copy link
Copy Markdown
Contributor Author

And you! 🙏

@github-actions github-actions Bot locked and limited conversation to collaborators May 28, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Browser Mode leaks a manual mock across spec files when the same module is mocked via two ids

2 participants