Skip to content

Commit b34ffad

Browse files
authored
fix(browser): await mocker invalidation to avoid race condition with "mock wasn't registered" (#8021)
1 parent d6ef0da commit b34ffad

File tree

5 files changed

+27
-21
lines changed

5 files changed

+27
-21
lines changed

packages/browser/src/node/providers/playwright.ts

Lines changed: 22 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -179,10 +179,14 @@ export class PlaywrightBrowserProvider implements BrowserProvider {
179179
const ids = sessionIds.get(sessionId) || []
180180
ids.push(moduleUrl.href)
181181
sessionIds.set(sessionId, ids)
182-
idPreficates.set(moduleUrl.href, predicate)
182+
idPreficates.set(predicateKey(sessionId, moduleUrl.href), predicate)
183183
return predicate
184184
}
185185

186+
function predicateKey(sessionId: string, url: string) {
187+
return `${sessionId}:${url}`
188+
}
189+
186190
return {
187191
register: async (sessionId: string, module: MockedModule): Promise<void> => {
188192
const page = this.getPage(sessionId)
@@ -200,17 +204,17 @@ export class PlaywrightBrowserProvider implements BrowserProvider {
200204
// https://github.com/microsoft/playwright/issues/18318
201205
const isWebkit = this.browserName === 'webkit'
202206
if (isWebkit) {
203-
const url = module.type === 'redirect'
204-
? (() => {
205-
// url has http:// which vite.trasnformRequest doesn't understand
206-
const url = new URL(module.redirect)
207-
return url.href.slice(url.origin.length)
208-
})()
209-
: (() => {
210-
const url = new URL(route.request().url())
211-
url.searchParams.set('mock', module.type)
212-
return url.href.slice(url.origin.length)
213-
})()
207+
let url: string
208+
if (module.type === 'redirect') {
209+
const redirect = new URL(module.redirect)
210+
url = redirect.href.slice(redirect.origin.length)
211+
}
212+
else {
213+
const request = new URL(route.request().url())
214+
request.searchParams.set('mock', module.type)
215+
url = request.href.slice(request.origin.length)
216+
}
217+
214218
const result = await this.project.browser!.vite.transformRequest(url).catch(() => null)
215219
if (!result) {
216220
return route.continue()
@@ -252,18 +256,20 @@ export class PlaywrightBrowserProvider implements BrowserProvider {
252256
},
253257
delete: async (sessionId: string, id: string): Promise<void> => {
254258
const page = this.getPage(sessionId)
255-
const predicate = idPreficates.get(id)
259+
const key = predicateKey(sessionId, id)
260+
const predicate = idPreficates.get(key)
256261
if (predicate) {
257-
await page.unroute(predicate).finally(() => idPreficates.delete(id))
262+
await page.unroute(predicate).finally(() => idPreficates.delete(key))
258263
}
259264
},
260265
clear: async (sessionId: string): Promise<void> => {
261266
const page = this.getPage(sessionId)
262267
const ids = sessionIds.get(sessionId) || []
263268
const promises = ids.map((id) => {
264-
const predicate = idPreficates.get(id)
269+
const key = predicateKey(sessionId, id)
270+
const predicate = idPreficates.get(key)
265271
if (predicate) {
266-
return page.unroute(predicate).finally(() => idPreficates.delete(id))
272+
return page.unroute(predicate).finally(() => idPreficates.delete(key))
267273
}
268274
return null
269275
})

packages/mocker/src/browser/interceptor-msw.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ export class ModuleMockerMSWInterceptor implements ModuleMockerInterceptor {
5555
this.mocks.delete(url)
5656
}
5757

58-
invalidate(): void {
58+
async invalidate(): Promise<void> {
5959
this.mocks.clear()
6060
}
6161

packages/mocker/src/browser/interceptor-native.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ export class ModuleMockerServerInterceptor implements ModuleMockerInterceptor {
1111
await rpc('vitest:interceptor:delete', id)
1212
}
1313

14-
invalidate(): void {
15-
rpc('vitest:interceptor:invalidate')
14+
async invalidate(): Promise<void> {
15+
await rpc('vitest:interceptor:invalidate')
1616
}
1717
}

packages/mocker/src/browser/interceptor.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,5 @@ import type { MockedModule } from '../registry'
33
export interface ModuleMockerInterceptor {
44
register: (module: MockedModule) => Promise<void>
55
delete: (url: string) => Promise<void>
6-
invalidate: () => void
6+
invalidate: () => Promise<void>
77
}

packages/mocker/src/browser/mocker.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ export class ModuleMocker {
5353
return
5454
}
5555
await this.rpc.invalidate(ids)
56-
this.interceptor.invalidate()
56+
await this.interceptor.invalidate()
5757
this.registry.clear()
5858
}
5959

0 commit comments

Comments
 (0)