Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 13 additions & 1 deletion src/browser/setupWorker/setupWorker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ import { printStartMessage } from './start/utils/printStartMessage'
import { printStopMessage } from './stop/utils/printStopMessage'
import { supportsServiceWorker } from '../utils/supports'

const kSetupWorkerApplied = Symbol.for('msw.setupWorkerApplied')

export class SetupWorkerApi
extends SetupApi<LifeCycleEventsMap>
implements SetupWorker
Expand Down Expand Up @@ -180,5 +182,15 @@ export class SetupWorkerApi
export function setupWorker(
...handlers: Array<RequestHandler | WebSocketHandler>
): SetupWorker {
return new SetupWorkerApi(...handlers)
invariant(
Reflect.get(globalThis, kSetupWorkerApplied) == null,
devUtils.formatMessage(
'Failed to execute `setupWorker()` more than once in the same page. Create the worker once and reuse it for the lifetime of the page. If you wish to apply a different set of request handlers, use `worker.use()` or `worker.resetHandlers()` instead.',
),
)

const worker = new SetupWorkerApi(...handlers)
Reflect.set(globalThis, kSetupWorkerApplied, true)

return worker
}
7 changes: 7 additions & 0 deletions test/browser/msw-api/setup-worker/multiple-instances.mocks.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { setupWorker } from 'msw/browser'

Object.assign(window, {
msw: {
setupWorker,
},
})
36 changes: 36 additions & 0 deletions test/browser/msw-api/setup-worker/multiple-instances.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import type { setupWorker } from 'msw/browser'
import { test, expect } from '../../playwright.extend'

declare namespace window {
export const msw: {
setupWorker: typeof setupWorker
}
}

test('throws an error when calling "setupWorker()" more than once on the same page', async ({
loadExample,
page,
}) => {
await loadExample(new URL('./multiple-instances.mocks.ts', import.meta.url), {
skipActivation: true,
})

await page.waitForFunction(() => {
return typeof window.msw !== 'undefined'
})

const errorMessage = await page.evaluate(() => {
window.msw.setupWorker()

try {
window.msw.setupWorker()
return null
} catch (error) {
return error instanceof Error ? error.message : String(error)
}
})

expect(errorMessage).toContain(
'[MSW] Failed to execute `setupWorker()` more than once',
)
})
Loading