Skip to content

Commit

Permalink
fix(browser): allow immidiate reinvalidation of mocked dependencies (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
sheremet-va authored Jul 12, 2024
1 parent 840e02f commit f44cc91
Show file tree
Hide file tree
Showing 11 changed files with 99 additions and 4 deletions.
18 changes: 18 additions & 0 deletions packages/browser/src/client/tester/msw.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,10 @@ export function createModuleMocker() {
http.get(/.+/, async ({ request }) => {
const path = cleanQuery(request.url.slice(location.origin.length))
if (!mocks.has(path)) {
if (path.includes('/deps/')) {
return fetch(bypass(request))
}

return passthrough()
}

Expand Down Expand Up @@ -128,6 +132,20 @@ function passthrough() {
})
}

function bypass(request: Request) {
const clonedRequest = request.clone()
clonedRequest.headers.set('x-msw-intention', 'bypass')
const cacheControl = clonedRequest.headers.get('cache-control')
if (cacheControl) {
clonedRequest.headers.set(
'cache-control',
// allow reinvalidation of the cache so mocks can be updated
cacheControl.replace(', immutable', ''),
)
}
return clonedRequest
}

const postfixRE = /[?#].*$/
function cleanUrl(url: string): string {
return url.replace(postfixRE, '')
Expand Down
2 changes: 1 addition & 1 deletion packages/browser/src/node/plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ export default (browserServer: BrowserServer, base = '/'): Plugin[] => {
})
// eslint-disable-next-line prefer-arrow-callback
server.middlewares.use(async function vitestBrowserMode(req, res, next) {
if (!req.url) {
if (!req.url || !browserServer.provider) {
return next()
}
const url = new URL(req.url, 'http://localhost')
Expand Down
1 change: 1 addition & 0 deletions test/browser/cjs-lib/lib.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export function lib(): string
3 changes: 3 additions & 0 deletions test/browser/cjs-lib/lib.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export function lib() {
return 'original'
}
6 changes: 5 additions & 1 deletion test/browser/cjs-lib/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@
"name": "@vitest/cjs-lib",
"type": "commonjs",
"exports": {
"default": "./index.js"
"./lib": {
"types": "./lib.d.ts",
"default": "./lib.mjs"
},
".": "./index.js"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { lib } from '@vitest/cjs-lib/lib'
import { vi, test, expect } from 'vitest'

vi.mock(import('@vitest/cjs-lib/lib'), () => {
return {
lib: vi.fn(() => 'mocked')
}
})

test('mocks correctly', () => {
expect(lib()).toBe('mocked')
})
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import { lib } from '@vitest/cjs-lib/lib'
import { test, expect } from 'vitest'

test('not mocked', () => {
expect(lib()).toBe('original')
})
22 changes: 22 additions & 0 deletions test/browser/fixtures/mocking-watch/vitest.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { fileURLToPath } from 'node:url'
import { defineConfig } from 'vitest/config'

const provider = process.env.PROVIDER || 'playwright'
const name =
process.env.BROWSER || (provider === 'playwright' ? 'chromium' : 'chrome')

export default defineConfig({
optimizeDeps: {
include: ['@vitest/cjs-lib', '@vitest/cjs-lib/lib'],
},
cacheDir: fileURLToPath(new URL("./node_modules/.vite", import.meta.url)),
test: {
browser: {
fileParallelism: false,
enabled: true,
provider,
name,
headless: true,
},
},
})
2 changes: 2 additions & 0 deletions test/browser/fixtures/mocking/vitest.config.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { fileURLToPath } from 'node:url'
import { defineConfig } from 'vitest/config'

const provider = process.env.PROVIDER || 'playwright'
Expand All @@ -9,6 +10,7 @@ export default defineConfig({
include: ['@vitest/cjs-lib'],
needsInterop: ['@vitest/cjs-lib'],
},
cacheDir: fileURLToPath(new URL("./node_modules/.vite", import.meta.url)),
test: {
browser: {
enabled: true,
Expand Down
1 change: 1 addition & 0 deletions test/browser/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
"test:safaridriver": "PROVIDER=webdriverio BROWSER=safari pnpm run test:unit",
"test-fixtures": "vitest",
"test-mocking": "vitest --root ./fixtures/mocking",
"test-mocking-watch": "vitest --root ./fixtures/mocking-watch",
"test-snapshots": "vitest --root ./fixtures/update-snapshot",
"coverage": "vitest --coverage.enabled --coverage.provider=istanbul --browser.headless=yes",
"test:browser:preview": "PROVIDER=preview vitest",
Expand Down
30 changes: 28 additions & 2 deletions test/browser/specs/mocking.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { expect, onTestFailed, test } from 'vitest'
import { runVitest } from '../../test-utils'
import { expect, onTestFailed, onTestFinished, test } from 'vitest'
import { editFile, runVitest } from '../../test-utils'

test.each([true, false])('mocking works correctly - isolated %s', async (isolate) => {
const result = await runVitest({
Expand All @@ -26,3 +26,29 @@ test.each([true, false])('mocking works correctly - isolated %s', async (isolate
expect(result.stdout).toContain('mocked-do-mock-factory.test.ts')
expect(result.exitCode).toBe(0)
})

test('mocking dependency correctly invalidates it on rerun', async () => {
const { vitest, ctx } = await runVitest({
root: 'fixtures/mocking-watch',
watch: true,
})
onTestFinished(async () => {
await ctx.close()
await ctx.closingPromise
})

await vitest.waitForStdout('Waiting for file changes...')

expect(vitest.stderr).toBe('')
expect(vitest.stdout).toContain('1_mocked-on-watch-change.test.ts')
expect(vitest.stdout).toContain('2_not-mocked-import.test.ts')

vitest.resetOutput()
editFile('./fixtures/mocking-watch/1_mocked-on-watch-change.test.ts', content => `${content}\n`)

await vitest.waitForStdout('Waiting for file changes...')

expect(vitest.stderr).toBe('')
expect(vitest.stdout).toContain('1_mocked-on-watch-change.test.ts')
expect(vitest.stdout).not.toContain('2_not-mocked-import.test.ts')
})

0 comments on commit f44cc91

Please sign in to comment.