Skip to content

Commit 9e34557

Browse files
mblandsheremet-va
andauthoredJan 4, 2024
fix(browser): handle config.base (#4686) (#4692)
Co-authored-by: Vladimir Sheremet <sleuths.slews0s@icloud.com>
1 parent b8140fc commit 9e34557

File tree

9 files changed

+82
-41
lines changed

9 files changed

+82
-41
lines changed
 

‎packages/browser/src/client/logger.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@ import { importId } from './utils'
33

44
const { Date, console } = globalThis
55

6-
export async function setupConsoleLogSpy() {
7-
const { stringify, format, inspect } = await importId('vitest/utils') as typeof import('vitest/utils')
6+
export async function setupConsoleLogSpy(basePath: string) {
7+
const { stringify, format, inspect } = await importId('vitest/utils', basePath) as typeof import('vitest/utils')
88
const { log, info, error, dir, dirxml, trace, time, timeEnd, timeLog, warn, debug, count, countReset } = console
99
const formatInput = (input: unknown) => {
1010
if (input instanceof Node)

‎packages/browser/src/client/main.ts

+7-4
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import type { ResolvedConfig } from 'vitest'
33
import type { CancelReason, VitestRunner } from '@vitest/runner'
44
import type { VitestExecutor } from '../../../vitest/src/runtime/execute'
55
import { createBrowserRunner } from './runner'
6-
import { importId } from './utils'
6+
import { importId as _importId } from './utils'
77
import { setupConsoleLogSpy } from './logger'
88
import { createSafeRpc, rpc, rpcDone } from './rpc'
99
import { setupDialogsSpy } from './dialog'
@@ -24,6 +24,10 @@ const url = new URL(location.href)
2424
const testId = url.searchParams.get('id') || 'unknown'
2525
const reloadTries = Number(url.searchParams.get('reloadTries') || '0')
2626

27+
const basePath = () => config?.base || '/'
28+
const importId = (id: string) => _importId(id, basePath())
29+
const viteClientPath = () => `${basePath()}@vite/client`
30+
2731
function getQueryPaths() {
2832
return url.searchParams.getAll('path')
2933
}
@@ -181,15 +185,14 @@ ws.addEventListener('open', async () => {
181185
const iFrame = document.getElementById('vitest-ui') as HTMLIFrameElement
182186
iFrame.setAttribute('src', '/__vitest__/')
183187

184-
await setupConsoleLogSpy()
188+
await setupConsoleLogSpy(basePath())
185189
setupDialogsSpy()
186190
await runTests(paths, config!)
187191
})
188192

189193
async function prepareTestEnvironment(config: ResolvedConfig) {
190194
// need to import it before any other import, otherwise Vite optimizer will hang
191-
const viteClientPath = '/@vite/client'
192-
await import(viteClientPath)
195+
await import(viteClientPath())
193196

194197
const {
195198
startTests,

‎packages/browser/src/client/runner.ts

+6-5
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,10 @@ interface CoverageHandler {
1212
}
1313

1414
export function createBrowserRunner(
15-
original: { new(config: ResolvedConfig): VitestRunner },
15+
VitestRunner: { new(config: ResolvedConfig): VitestRunner },
1616
coverageModule: CoverageHandler | null,
1717
): { new(options: BrowserRunnerOptions): VitestRunner } {
18-
return class BrowserTestRunner extends original {
18+
return class BrowserTestRunner extends VitestRunner {
1919
public config: ResolvedConfig
2020
hashMap = new Map<string, [test: boolean, timstamp: string]>()
2121

@@ -69,11 +69,12 @@ export function createBrowserRunner(
6969
hash = Date.now().toString()
7070
this.hashMap.set(filepath, [false, hash])
7171
}
72+
const base = this.config.base || '/'
7273

7374
// on Windows we need the unit to resolve the test file
74-
const importpath = /^\w:/.test(filepath)
75-
? `/@fs/${filepath}?${test ? 'browserv' : 'v'}=${hash}`
76-
: `${filepath}?${test ? 'browserv' : 'v'}=${hash}`
75+
const prefix = `${base}${/^\w:/.test(filepath) ? '@fs/' : ''}`
76+
const query = `${test ? 'browserv' : 'v'}=${hash}`
77+
const importpath = `${prefix}${filepath}?${query}`.replace(/\/+/g, '/')
7778
await import(importpath)
7879
}
7980
}

‎packages/browser/src/client/utils.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
export async function importId(id: string) {
2-
const name = `/@id/${id}`
1+
export async function importId(id: string, basePath: string) {
2+
const name = `${basePath}@id/${id}`
33
// @ts-expect-error mocking vitest apis
44
return __vi_wrap_module__(import(name))
55
}

‎test/browser/package.json

+3-3
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,9 @@
44
"private": true,
55
"scripts": {
66
"test": "pnpm run test:webdriverio && pnpm run test:playwright",
7-
"test:webdriverio": "PROVIDER=webdriverio node --test specs/",
8-
"test:playwright": "PROVIDER=playwright node --test specs/",
9-
"test:safaridriver": "PROVIDER=webdriverio BROWSER=safari node --test specs/",
7+
"test:webdriverio": "PROVIDER=webdriverio node --test --test-concurrency=1 specs/",
8+
"test:playwright": "PROVIDER=playwright node --test --test-concurrency=1 specs/",
9+
"test:safaridriver": "PROVIDER=webdriverio BROWSER=safari node --test --test-concurrency=1 specs/",
1010
"coverage": "vitest --coverage.enabled --coverage.provider=istanbul --browser.headless=yes"
1111
},
1212
"devDependencies": {

‎test/browser/specs/fix-4686.test.mjs

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
// fix #4686
2+
3+
import assert from 'node:assert'
4+
import test from 'node:test'
5+
import runVitest from './run-vitest.mjs'
6+
7+
const {
8+
stderr,
9+
browserResultJson,
10+
passedTests,
11+
failedTests,
12+
} = await runVitest(['--config', 'vitest.config-basepath.mts', 'basic.test.ts'])
13+
14+
await test('tests run in presence of config.base', async () => {
15+
assert.ok(browserResultJson.testResults.length === 1, 'Not all the tests have been run')
16+
assert.ok(passedTests.length === 1, 'Some tests failed')
17+
assert.ok(failedTests.length === 0, 'Some tests have passed but should fail')
18+
19+
assert.doesNotMatch(stderr, /Unhandled Error/, 'doesn\'t have any unhandled errors')
20+
})

‎test/browser/specs/run-vitest.mjs

+30
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
import { readFile } from 'node:fs/promises'
2+
import { execa } from 'execa'
3+
4+
const browser = process.env.BROWSER || (process.env.PROVIDER === 'playwright' ? 'chromium' : 'chrome')
5+
6+
export default async function runVitest(moreArgs = []) {
7+
const argv = ['vitest', '--run', `--browser.name=${browser}`]
8+
9+
if (browser !== 'safari')
10+
argv.push('--browser.headless')
11+
12+
const { stderr, stdout } = await execa('npx', argv.concat(moreArgs), {
13+
env: {
14+
...process.env,
15+
CI: 'true',
16+
NO_COLOR: 'true',
17+
},
18+
reject: false,
19+
})
20+
const browserResult = await readFile('./browser.json', 'utf-8')
21+
const browserResultJson = JSON.parse(browserResult)
22+
23+
const getPassed = results => results.filter(result => result.status === 'passed')
24+
const getFailed = results => results.filter(result => result.status === 'failed')
25+
26+
const passedTests = getPassed(browserResultJson.testResults)
27+
const failedTests = getFailed(browserResultJson.testResults)
28+
29+
return { stderr, stdout, browserResultJson, passedTests, failedTests }
30+
}

‎test/browser/specs/runner.test.mjs

+8-25
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,14 @@
11
import assert from 'node:assert'
2-
import { readFile } from 'node:fs/promises'
32
import test from 'node:test'
4-
import { execa } from 'execa'
3+
import runVitest from './run-vitest.mjs'
54

6-
const browser = process.env.BROWSER || (process.env.PROVIDER === 'playwright' ? 'chromium' : 'chrome')
7-
const argv = ['vitest', '--run', `--browser.name=${browser}`]
8-
9-
if (browser !== 'safari')
10-
argv.push('--browser.headless')
11-
12-
const { stderr, stdout } = await execa('npx', argv, {
13-
env: {
14-
...process.env,
15-
CI: 'true',
16-
NO_COLOR: 'true',
17-
},
18-
reject: false,
19-
})
20-
21-
const browserResult = await readFile('./browser.json', 'utf-8')
22-
const browserResultJson = JSON.parse(browserResult)
23-
24-
const getPassed = results => results.filter(result => result.status === 'passed')
25-
const getFailed = results => results.filter(result => result.status === 'failed')
26-
27-
const passedTests = getPassed(browserResultJson.testResults)
28-
const failedTests = getFailed(browserResultJson.testResults)
5+
const {
6+
stderr,
7+
stdout,
8+
browserResultJson,
9+
passedTests,
10+
failedTests,
11+
} = await runVitest()
2912

3013
await test('tests are actually running', async () => {
3114
assert.ok(browserResultJson.testResults.length === 10, 'Not all the tests have been run')
+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
import { defineConfig, mergeConfig } from 'vitest/config'
2+
import baseConfig from './vitest.config.mjs'
3+
4+
export default mergeConfig(baseConfig, defineConfig({ base: '/fix-4686' }))

0 commit comments

Comments
 (0)
Please sign in to comment.