From 4c15bb3af0110287a778946da63423b16197f06a Mon Sep 17 00:00:00 2001 From: Vladimir Sheremet Date: Tue, 25 Jun 2024 17:02:35 +0200 Subject: [PATCH 01/19] feat(browser): add an option to take screenshots if the browser test failed --- docs/config/index.md | 14 ++++++++++++++ packages/browser/src/client/tester/runner.ts | 7 +++++++ packages/browser/src/client/tester/tester.ts | 4 ++-- packages/browser/src/client/vite.config.ts | 2 +- packages/runner/src/run.ts | 7 +++++++ packages/runner/src/types/runner.ts | 4 ++++ packages/vitest/src/node/config.ts | 1 + packages/vitest/src/types/browser.ts | 7 +++++++ 8 files changed, 43 insertions(+), 3 deletions(-) diff --git a/docs/config/index.md b/docs/config/index.md index 94d4a34e7706..27f77390954a 100644 --- a/docs/config/index.md +++ b/docs/config/index.md @@ -1620,6 +1620,20 @@ Should Vitest UI be injected into the page. By default, injects UI iframe during Default iframe's viewport. +#### browser.screenshotDirectory {#browser-screenshotdirectory} + +- **Type:** `string` +- **Default:** `__snapshots__` in the test file directory + +Path to the snapshots directory relative to the `root`. + +#### browser.screenshotFailures {#browser-screenshotfailures} + +- **Type:** `boolean` +- **Default:** `!browser.ui` + +Should Vitest take screenshots if the test failed. + #### browser.orchestratorScripts {#browser-orchestratorscripts} - **Type:** `BrowserScript[]` diff --git a/packages/browser/src/client/tester/runner.ts b/packages/browser/src/client/tester/runner.ts index ec1430e2b970..97d2f295ad73 100644 --- a/packages/browser/src/client/tester/runner.ts +++ b/packages/browser/src/client/tester/runner.ts @@ -4,6 +4,7 @@ import type { VitestExecutor } from 'vitest/execute' import { NodeBenchmarkRunner, VitestTestRunner } from 'vitest/runners' import { loadDiffConfig, loadSnapshotSerializers, takeCoverageInsideWorker } from 'vitest/browser' import { TraceMap, originalPositionFor } from 'vitest/utils' +import { page } from '@vitest/browser/context' import { importId } from '../utils' import { globalChannel } from '../channel' import { VitestBrowserSnapshotEnvironment } from './snapshot' @@ -53,6 +54,12 @@ export function createBrowserRunner( } } + onTaskFinished = async (task: Task) => { + if (this.config.browser.screenshotFailures && task.result?.state === 'fail') { + await page.screenshot() + } + } + onCancel = (reason: CancelReason) => { super.onCancel?.(reason) globalChannel.postMessage({ type: 'cancel', reason }) diff --git a/packages/browser/src/client/tester/tester.ts b/packages/browser/src/client/tester/tester.ts index a045e93d3387..d07acb08454c 100644 --- a/packages/browser/src/client/tester/tester.ts +++ b/packages/browser/src/client/tester/tester.ts @@ -92,8 +92,8 @@ async function runTests(files: string[]) { try { preparedData = await prepareTestEnvironment(files) } - catch (error) { - debug('data cannot be loaded because it threw an error') + catch (error: any) { + debug('data cannot be loaded because it threw an error', error.stack || error.message) await client.rpc.onUnhandledError(serializeError(error), 'Preload Error') done(files) return diff --git a/packages/browser/src/client/vite.config.ts b/packages/browser/src/client/vite.config.ts index 780d35b56489..d5a35ec38738 100644 --- a/packages/browser/src/client/vite.config.ts +++ b/packages/browser/src/client/vite.config.ts @@ -19,7 +19,7 @@ export default defineConfig({ orchestrator: resolve(__dirname, './orchestrator.html'), tester: resolve(__dirname, './tester/tester.html'), }, - external: [/__virtual_vitest__/], + external: [/__virtual_vitest__/, '@vitest/browser/context'], }, }, plugins: [ diff --git a/packages/runner/src/run.ts b/packages/runner/src/run.ts index 9fa34b8185f5..44291f143fa5 100644 --- a/packages/runner/src/run.ts +++ b/packages/runner/src/run.ts @@ -262,6 +262,13 @@ export async function runTest(test: Test | Custom, runner: VitestRunner) { return } + try { + await runner.onTaskFinished?.(test) + } + catch (e) { + failTask(test.result, e, runner.config.diffOptions) + } + try { await callSuiteHook(suite, test, 'afterEach', runner, [ test.context, diff --git a/packages/runner/src/types/runner.ts b/packages/runner/src/types/runner.ts index 49ec0198f7a5..ae8795c2fe24 100644 --- a/packages/runner/src/types/runner.ts +++ b/packages/runner/src/types/runner.ts @@ -80,6 +80,10 @@ export interface VitestRunner { test: Task, options: { retry: number; repeats: number } ) => unknown + /** + * When the task has finished running, but before cleanup hooks are called + */ + onTaskFinished?: (test: Task) => unknown /** * Called after result and state are set. */ diff --git a/packages/vitest/src/node/config.ts b/packages/vitest/src/node/config.ts index 4d369c996ac2..a894817b0bba 100644 --- a/packages/vitest/src/node/config.ts +++ b/packages/vitest/src/node/config.ts @@ -683,6 +683,7 @@ export function resolveConfig( resolved.browser.screenshotDirectory, ) } + resolved.browser.screenshotFailures ??= !resolved.browser.ui resolved.browser.viewport ??= {} as any resolved.browser.viewport.width ??= 414 diff --git a/packages/vitest/src/types/browser.ts b/packages/vitest/src/types/browser.ts index 14ae5293f0e4..a869746b571c 100644 --- a/packages/vitest/src/types/browser.ts +++ b/packages/vitest/src/types/browser.ts @@ -135,6 +135,13 @@ export interface BrowserConfigOptions { * @default __screenshots__ */ screenshotDirectory?: string + + /** + * Should Vitest take screenshots if the test failed + * @default !browser.ui + */ + screenshotFailures?: boolean + /** * Scripts injected into the tester iframe. */ From e1012ad5671c4ba3390e4a767b5480f5e51ade44 Mon Sep 17 00:00:00 2001 From: Vladimir Sheremet Date: Tue, 25 Jun 2024 17:03:33 +0200 Subject: [PATCH 02/19] chore: cleanup --- docs/config/index.md | 2 +- packages/vitest/src/types/browser.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/config/index.md b/docs/config/index.md index 27f77390954a..5749c8af73e7 100644 --- a/docs/config/index.md +++ b/docs/config/index.md @@ -1632,7 +1632,7 @@ Path to the snapshots directory relative to the `root`. - **Type:** `boolean` - **Default:** `!browser.ui` -Should Vitest take screenshots if the test failed. +Should Vitest take screenshots if the test fails. #### browser.orchestratorScripts {#browser-orchestratorscripts} diff --git a/packages/vitest/src/types/browser.ts b/packages/vitest/src/types/browser.ts index a869746b571c..454ce12fa1ff 100644 --- a/packages/vitest/src/types/browser.ts +++ b/packages/vitest/src/types/browser.ts @@ -137,7 +137,7 @@ export interface BrowserConfigOptions { screenshotDirectory?: string /** - * Should Vitest take screenshots if the test failed + * Should Vitest take screenshots if the test fails * @default !browser.ui */ screenshotFailures?: boolean From bc08dc23dd59bfe2673de517c6adb8edf256f5d4 Mon Sep 17 00:00:00 2001 From: Vladimir Sheremet Date: Tue, 25 Jun 2024 17:11:23 +0200 Subject: [PATCH 03/19] chore: fix types --- packages/vitest/src/node/cli/cli-config.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/vitest/src/node/cli/cli-config.ts b/packages/vitest/src/node/cli/cli-config.ts index 46b217013f2d..50293f2e9277 100644 --- a/packages/vitest/src/node/cli/cli-config.ts +++ b/packages/vitest/src/node/cli/cli-config.ts @@ -413,6 +413,7 @@ export const cliOptionsConfig: VitestCLIOptions = { commands: null, viewport: null, screenshotDirectory: null, + screenshotFailures: null, }, }, pool: { From 7e573fe7103d0688fa3499a89093a98b338e340d Mon Sep 17 00:00:00 2001 From: Vladimir Sheremet Date: Tue, 25 Jun 2024 17:15:17 +0200 Subject: [PATCH 04/19] chore: remove only vitest related deps from browser stack trace --- packages/utils/src/source-map.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/packages/utils/src/source-map.ts b/packages/utils/src/source-map.ts index cbbd7216e945..5e26cbcea91e 100644 --- a/packages/utils/src/source-map.ts +++ b/packages/utils/src/source-map.ts @@ -32,7 +32,10 @@ const stackIgnorePatterns = [ '/node_modules/tinypool/', '/node_modules/tinyspy/', // browser related deps - '/deps/', + '/deps/chunk-', + '/deps/@vitest', + '/deps/loupe', + '/deps/chai', /node:\w+/, /__vitest_test__/, /__vitest_browser__/, From dd2abbac9413d392e6844e271415d7d938438c80 Mon Sep 17 00:00:00 2001 From: Vladimir Sheremet Date: Tue, 25 Jun 2024 17:26:06 +0200 Subject: [PATCH 05/19] chore: gueard against preview provider --- packages/vitest/src/node/config.ts | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/packages/vitest/src/node/config.ts b/packages/vitest/src/node/config.ts index a894817b0bba..60ebde108f4a 100644 --- a/packages/vitest/src/node/config.ts +++ b/packages/vitest/src/node/config.ts @@ -683,7 +683,20 @@ export function resolveConfig( resolved.browser.screenshotDirectory, ) } - resolved.browser.screenshotFailures ??= !resolved.browser.ui + const isPreview = resolved.browser.provider === 'preview' + if (isPreview && resolved.browser.screenshotFailures === true) { + console.warn(c.yellow( + [ + `Browser provider "preview" doesn't support screenshots, `, + `so "browser.screenshotFailures" option is forcefully disabled. `, + `Set "browser.screenshotFailures" to false or remove it from the config to suppress this warning.`, + ].join(''), + )) + resolved.browser.screenshotFailures = false + } + else { + resolved.browser.screenshotFailures ??= !isPreview && !resolved.browser.ui + } resolved.browser.viewport ??= {} as any resolved.browser.viewport.width ??= 414 From c22cbeeeb11c301a442ae78958f67f972a866bb1 Mon Sep 17 00:00:00 2001 From: Vladimir Sheremet Date: Tue, 25 Jun 2024 18:56:48 +0200 Subject: [PATCH 06/19] test: add debug variable --- .github/workflows/ci.yml | 1 + packages/browser/src/client/tester/tester.ts | 2 +- packages/browser/src/node/providers/playwright.ts | 12 ++++++++++++ 3 files changed, 14 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 638ac8913ce5..253cd5a02be1 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -17,6 +17,7 @@ concurrency: env: PLAYWRIGHT_BROWSERS_PATH: ${{ github.workspace }}/.cache/ms-playwright + VITEST_PW_DEBUG: true jobs: lint: diff --git a/packages/browser/src/client/tester/tester.ts b/packages/browser/src/client/tester/tester.ts index d07acb08454c..07732a53e96b 100644 --- a/packages/browser/src/client/tester/tester.ts +++ b/packages/browser/src/client/tester/tester.ts @@ -93,7 +93,7 @@ async function runTests(files: string[]) { preparedData = await prepareTestEnvironment(files) } catch (error: any) { - debug('data cannot be loaded because it threw an error', error.stack || error.message) + debug('runner cannot be loaded because it threw an error', error.stack || error.message) await client.rpc.onUnhandledError(serializeError(error), 'Preload Error') done(files) return diff --git a/packages/browser/src/node/providers/playwright.ts b/packages/browser/src/node/providers/playwright.ts index c3e87da0c754..80e47bc342d1 100644 --- a/packages/browser/src/node/providers/playwright.ts +++ b/packages/browser/src/node/providers/playwright.ts @@ -141,6 +141,18 @@ export class PlaywrightBrowserProvider implements BrowserProvider { const page = await context.newPage() this.pages.set(contextId, page) + if (process.env.VITEST_PW_DEBUG) { + page.on('requestfailed', (request) => { + console.error( + request.resourceType(), + 'request failed for', + request.url(), + 'url:', + request.failure()?.errorText, + ) + }) + } + return page } From a352f6b58601afbd51756f227257bcea363523c2 Mon Sep 17 00:00:00 2001 From: Vladimir Sheremet Date: Tue, 25 Jun 2024 18:57:16 +0200 Subject: [PATCH 07/19] chore: cleanup --- packages/browser/src/node/providers/playwright.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/browser/src/node/providers/playwright.ts b/packages/browser/src/node/providers/playwright.ts index 80e47bc342d1..2fba6668d847 100644 --- a/packages/browser/src/node/providers/playwright.ts +++ b/packages/browser/src/node/providers/playwright.ts @@ -144,6 +144,7 @@ export class PlaywrightBrowserProvider implements BrowserProvider { if (process.env.VITEST_PW_DEBUG) { page.on('requestfailed', (request) => { console.error( + '[PW Error]', request.resourceType(), 'request failed for', request.url(), From d6572296ecc616f8ebbdf2d9d04c7876e2335fa6 Mon Sep 17 00:00:00 2001 From: Vladimir Sheremet Date: Tue, 25 Jun 2024 19:04:49 +0200 Subject: [PATCH 08/19] chore: gitignore every screenshot --- .gitignore | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 42754b1803b3..e5d7f1726288 100644 --- a/.gitignore +++ b/.gitignore @@ -22,6 +22,6 @@ docs/public/sponsors .eslintcache docs/.vitepress/cache/ !test/cli/fixtures/dotted-files/**/.cache -test/browser/test/__screenshots__/**/* +test/**/__screenshots__/**/* test/browser/fixtures/update-snapshot/basic.test.ts .vitest-reports From 5209c2cac04a7d870ce67e4fada7fa867accaa76 Mon Sep 17 00:00:00 2001 From: Vladimir Sheremet Date: Tue, 25 Jun 2024 19:22:13 +0200 Subject: [PATCH 09/19] fix: add custom modules to entries --- .github/workflows/ci.yml | 1 - packages/browser/src/node/plugin.ts | 63 ++++++++++++++++++++++++----- packages/vitest/src/node/config.ts | 7 ++++ 3 files changed, 61 insertions(+), 10 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 253cd5a02be1..638ac8913ce5 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -17,7 +17,6 @@ concurrency: env: PLAYWRIGHT_BROWSERS_PATH: ${{ github.workspace }}/.cache/ms-playwright - VITEST_PW_DEBUG: true jobs: lint: diff --git a/packages/browser/src/node/plugin.ts b/packages/browser/src/node/plugin.ts index 24f6d6b8f070..6bc338a1cf0a 100644 --- a/packages/browser/src/node/plugin.ts +++ b/packages/browser/src/node/plugin.ts @@ -122,17 +122,44 @@ export default (browserServer: BrowserServer, base = '/'): Plugin[] => { define[`import.meta.env.${env}`] = stringValue } + const entries: string[] = [ + ...browserTestFiles, + ...setupFiles, + resolve(vitestDist, 'index.js'), + resolve(vitestDist, 'browser.js'), + resolve(vitestDist, 'runners.js'), + resolve(vitestDist, 'utils.js'), + ...(project.config.snapshotSerializers || []), + ] + + if (project.config.diff) { + entries.push(project.config.diff) + } + + if (project.ctx.coverageProvider) { + const coverage = project.ctx.config.coverage + const provider = coverage.provider + if (provider === 'v8') { + const path = tryResolve('@vitest/coverage-v8', [project.ctx.config.root]) + if (path) { + entries.push(path) + } + } + else if (provider === 'istanbul') { + const path = tryResolve('@vitest/coverage-istanbul', [project.ctx.config.root]) + if (path) { + entries.push(path) + } + } + else if (provider) { + entries.push(resolve(project.ctx.config.root, coverage.customProviderModule)) + } + } + return { define, optimizeDeps: { - entries: [ - ...browserTestFiles, - ...setupFiles, - resolve(vitestDist, 'index.js'), - resolve(vitestDist, 'browser.js'), - resolve(vitestDist, 'runners.js'), - resolve(vitestDist, 'utils.js'), - ], + entries, exclude: [ 'vitest', 'vitest/utils', @@ -294,7 +321,7 @@ export default (browserServer: BrowserServer, base = '/'): Plugin[] => { { name: 'test-utils-rewrite', setup(build) { - const _require = createRequire(import.meta.url) + const _require = getRequire() build.onResolve({ filter: /@vue\/test-utils/ }, (args) => { // resolve to CJS instead of the browser because the browser version expects a global Vue object const resolved = _require.resolve(args.path, { @@ -313,6 +340,24 @@ export default (browserServer: BrowserServer, base = '/'): Plugin[] => { ] } +function tryResolve(path: string, paths: string[]) { + try { + const _require = getRequire() + return _require.resolve(path, { paths }) + } + catch { + return undefined + } +} + +let _require: NodeRequire +function getRequire() { + if (!_require) { + _require = createRequire(import.meta.url) + } + return _require +} + function resolveCoverageFolder(project: WorkspaceProject) { const options = project.ctx.config const htmlReporter = options.coverage?.enabled diff --git a/packages/vitest/src/node/config.ts b/packages/vitest/src/node/config.ts index 60ebde108f4a..b009e7294d7b 100644 --- a/packages/vitest/src/node/config.ts +++ b/packages/vitest/src/node/config.ts @@ -235,6 +235,13 @@ export function resolveConfig( } } + if (resolved.coverage.enabled && resolved.coverage.provider === 'custom' && resolved.coverage.customProviderModule) { + resolved.coverage.customProviderModule = resolvePath( + resolved.coverage.customProviderModule, + resolved.root, + ) + } + resolved.expect ??= {} resolved.deps ??= {} From 291eb8d330ec6520870f9700ba8aed6d12dddeb9 Mon Sep 17 00:00:00 2001 From: Vladimir Sheremet Date: Tue, 25 Jun 2024 19:31:58 +0200 Subject: [PATCH 10/19] test: fix custom coverage test --- test/config/test/failures.test.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/test/config/test/failures.test.ts b/test/config/test/failures.test.ts index c4f49d16e82b..7bb8a64337da 100644 --- a/test/config/test/failures.test.ts +++ b/test/config/test/failures.test.ts @@ -109,7 +109,8 @@ test('version number is printed when coverage provider fails to load', async () }) expect(stdout).toMatch(`RUN v${version}`) - expect(stderr).toMatch('Error: Failed to load custom CoverageProviderModule from ./non-existing-module.ts') + expect(stderr).toMatch('Error: Failed to load custom CoverageProviderModule from') + expect(stderr).toMatch('non-existing-module.ts') }) test('coverage.autoUpdate cannot update thresholds when configuration file doesnt define them', async () => { From 2457346d793ed2cdb8e6f935a5573235e618df9c Mon Sep 17 00:00:00 2001 From: Vladimir Sheremet Date: Tue, 25 Jun 2024 19:38:35 +0200 Subject: [PATCH 11/19] chore: cleanup --- packages/browser/src/node/plugin.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/browser/src/node/plugin.ts b/packages/browser/src/node/plugin.ts index 6bc338a1cf0a..e698927a4195 100644 --- a/packages/browser/src/node/plugin.ts +++ b/packages/browser/src/node/plugin.ts @@ -151,8 +151,8 @@ export default (browserServer: BrowserServer, base = '/'): Plugin[] => { entries.push(path) } } - else if (provider) { - entries.push(resolve(project.ctx.config.root, coverage.customProviderModule)) + else if (provider === 'custom' && coverage.customProviderModule) { + entries.push(coverage.customProviderModule) } } From f25669337c0cdd89ae94d96d2c59b24063738dd0 Mon Sep 17 00:00:00 2001 From: Vladimir Sheremet Date: Tue, 25 Jun 2024 20:00:03 +0200 Subject: [PATCH 12/19] chore: debug --- .github/workflows/ci.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 638ac8913ce5..253cd5a02be1 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -17,6 +17,7 @@ concurrency: env: PLAYWRIGHT_BROWSERS_PATH: ${{ github.workspace }}/.cache/ms-playwright + VITEST_PW_DEBUG: true jobs: lint: From 45656ba7e87d0b5ef186930bcd7dfae4790543b8 Mon Sep 17 00:00:00 2001 From: Vladimir Sheremet Date: Tue, 25 Jun 2024 20:22:41 +0200 Subject: [PATCH 13/19] chore: load @fs instead --- packages/browser/src/client/tester/runner.ts | 6 +++--- packages/browser/src/client/utils.ts | 7 ++++++- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/packages/browser/src/client/tester/runner.ts b/packages/browser/src/client/tester/runner.ts index 97d2f295ad73..84e7075b0959 100644 --- a/packages/browser/src/client/tester/runner.ts +++ b/packages/browser/src/client/tester/runner.ts @@ -5,7 +5,7 @@ import { NodeBenchmarkRunner, VitestTestRunner } from 'vitest/runners' import { loadDiffConfig, loadSnapshotSerializers, takeCoverageInsideWorker } from 'vitest/browser' import { TraceMap, originalPositionFor } from 'vitest/utils' import { page } from '@vitest/browser/context' -import { importId } from '../utils' +import { importFs } from '../utils' import { globalChannel } from '../channel' import { VitestBrowserSnapshotEnvironment } from './snapshot' import { rpc } from './rpc' @@ -149,7 +149,7 @@ export async function initiateRunner( = config.mode === 'test' ? VitestTestRunner : NodeBenchmarkRunner const BrowserRunner = createBrowserRunner(runnerClass, mocker, state, { takeCoverage: () => - takeCoverageInsideWorker(config.coverage, { executeId: importId }), + takeCoverageInsideWorker(config.coverage, { executeId: importFs }), }) if (!config.snapshotOptions.snapshotEnvironment) { config.snapshotOptions.snapshotEnvironment = new VitestBrowserSnapshotEnvironment() @@ -157,7 +157,7 @@ export async function initiateRunner( const runner = new BrowserRunner({ config, }) - const executor = { executeId: importId } as VitestExecutor + const executor = { executeId: importFs } as VitestExecutor const [diffOptions] = await Promise.all([ loadDiffConfig(config, executor), loadSnapshotSerializers(config, executor), diff --git a/packages/browser/src/client/utils.ts b/packages/browser/src/client/utils.ts index 0633a238b9be..c20ecc451d4f 100644 --- a/packages/browser/src/client/utils.ts +++ b/packages/browser/src/client/utils.ts @@ -1,7 +1,12 @@ import type { ResolvedConfig, WorkerGlobalState } from 'vitest' export async function importId(id: string) { - const name = `/@id/${id}` + const name = `/@id/${id}`.replace(/\\/g, '/') + return getBrowserState().wrapModule(() => import(name)) +} + +export async function importFs(id: string) { + const name = `/@fs/${id}`.replace(/\\/g, '/') return getBrowserState().wrapModule(() => import(name)) } From 94b9b246a1edfe3a1e83b3ba9b7dc06793ecaff8 Mon Sep 17 00:00:00 2001 From: Vladimir Sheremet Date: Tue, 25 Jun 2024 20:24:24 +0200 Subject: [PATCH 14/19] chore: test --- .github/workflows/ci.yml | 1 + packages/browser/src/node/index.ts | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 253cd5a02be1..24a4d4eea0da 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -18,6 +18,7 @@ concurrency: env: PLAYWRIGHT_BROWSERS_PATH: ${{ github.workspace }}/.cache/ms-playwright VITEST_PW_DEBUG: true + VITEST_BROWSER_DEBUG: info jobs: lint: diff --git a/packages/browser/src/node/index.ts b/packages/browser/src/node/index.ts index 27abee9b3b08..f6c61638f55c 100644 --- a/packages/browser/src/node/index.ts +++ b/packages/browser/src/node/index.ts @@ -25,7 +25,7 @@ export async function createBrowserServer( const vite = await createServer({ ...project.options, // spread project config inlined in root workspace config base: '/', - logLevel: 'error', + logLevel: (process.env.VITEST_BROWSER_DEBUG as 'info') ?? 'error', mode: project.config.mode, configFile: configPath, // watch is handled by Vitest From 91b7091f74a1b941852adb748f92f64db1dcc7b9 Mon Sep 17 00:00:00 2001 From: Vladimir Sheremet Date: Tue, 25 Jun 2024 20:35:40 +0200 Subject: [PATCH 15/19] chore: cleanup --- packages/browser/src/client/tester/mocker.ts | 6 +++--- packages/browser/src/client/tester/runner.ts | 16 ++++++++++++---- packages/browser/src/client/utils.ts | 4 ++-- packages/browser/src/client/vite.config.ts | 3 +++ 4 files changed, 20 insertions(+), 9 deletions(-) diff --git a/packages/browser/src/client/tester/mocker.ts b/packages/browser/src/client/tester/mocker.ts index 20efe5eb54e9..8ff6b7f0567a 100644 --- a/packages/browser/src/client/tester/mocker.ts +++ b/packages/browser/src/client/tester/mocker.ts @@ -64,7 +64,7 @@ export class VitestBrowserClientMocker { const actualUrl = `${url.pathname}${ url.search ? `${url.search}&${query}` : `?${query}` }${url.hash}` - return getBrowserState().wrapModule(() => import(actualUrl)) + return getBrowserState().wrapModule(() => import(/* @vite-ignore */ actualUrl)) } public async importMock(rawId: string, importer: string) { @@ -86,11 +86,11 @@ export class VitestBrowserClientMocker { if (type === 'redirect') { const url = new URL(`/@id/${mockPath}`, location.href) - return import(url.toString()) + return import(/* @vite-ignore */ url.toString()) } const url = new URL(`/@id/${resolvedId}`, location.href) const query = url.search ? `${url.search}&t=${now()}` : `?t=${now()}` - const moduleObject = await import(`${url.pathname}${query}${url.hash}`) + const moduleObject = await import(/* @vite-ignore */ `${url.pathname}${query}${url.hash}`) return this.mockObject(moduleObject) } diff --git a/packages/browser/src/client/tester/runner.ts b/packages/browser/src/client/tester/runner.ts index 84e7075b0959..4cd4a7e9ef3c 100644 --- a/packages/browser/src/client/tester/runner.ts +++ b/packages/browser/src/client/tester/runner.ts @@ -5,7 +5,7 @@ import { NodeBenchmarkRunner, VitestTestRunner } from 'vitest/runners' import { loadDiffConfig, loadSnapshotSerializers, takeCoverageInsideWorker } from 'vitest/browser' import { TraceMap, originalPositionFor } from 'vitest/utils' import { page } from '@vitest/browser/context' -import { importFs } from '../utils' +import { importFs, importId } from '../utils' import { globalChannel } from '../channel' import { VitestBrowserSnapshotEnvironment } from './snapshot' import { rpc } from './rpc' @@ -130,7 +130,7 @@ export function createBrowserRunner( const prefix = `/${/^\w:/.test(filepath) ? '@fs/' : ''}` const query = `${test ? 'browserv' : 'v'}=${hash}` const importpath = `${prefix}${filepath}?${query}`.replace(/\/+/g, '/') - await import(importpath) + await import(/* @vite-ignore */ importpath) } } } @@ -147,9 +147,17 @@ export async function initiateRunner( } const runnerClass = config.mode === 'test' ? VitestTestRunner : NodeBenchmarkRunner + + const executeId = (id: string) => { + if (id[0] === '/' || id[1] === ':') { + return importFs(id) + } + return importId(id) + } + const BrowserRunner = createBrowserRunner(runnerClass, mocker, state, { takeCoverage: () => - takeCoverageInsideWorker(config.coverage, { executeId: importFs }), + takeCoverageInsideWorker(config.coverage, { executeId }), }) if (!config.snapshotOptions.snapshotEnvironment) { config.snapshotOptions.snapshotEnvironment = new VitestBrowserSnapshotEnvironment() @@ -157,7 +165,7 @@ export async function initiateRunner( const runner = new BrowserRunner({ config, }) - const executor = { executeId: importFs } as VitestExecutor + const executor = { executeId } as VitestExecutor const [diffOptions] = await Promise.all([ loadDiffConfig(config, executor), loadSnapshotSerializers(config, executor), diff --git a/packages/browser/src/client/utils.ts b/packages/browser/src/client/utils.ts index c20ecc451d4f..7a00d2a64766 100644 --- a/packages/browser/src/client/utils.ts +++ b/packages/browser/src/client/utils.ts @@ -2,12 +2,12 @@ import type { ResolvedConfig, WorkerGlobalState } from 'vitest' export async function importId(id: string) { const name = `/@id/${id}`.replace(/\\/g, '/') - return getBrowserState().wrapModule(() => import(name)) + return getBrowserState().wrapModule(() => import(/* @vite-ignore */ name)) } export async function importFs(id: string) { const name = `/@fs/${id}`.replace(/\\/g, '/') - return getBrowserState().wrapModule(() => import(name)) + return getBrowserState().wrapModule(() => import(/* @vite-ignore */ name)) } export function getConfig(): ResolvedConfig { diff --git a/packages/browser/src/client/vite.config.ts b/packages/browser/src/client/vite.config.ts index d5a35ec38738..818e47607821 100644 --- a/packages/browser/src/client/vite.config.ts +++ b/packages/browser/src/client/vite.config.ts @@ -8,6 +8,9 @@ export default defineConfig({ server: { watch: { ignored: ['**/**'] }, }, + esbuild: { + legalComments: 'inline', + }, build: { minify: false, outDir: '../../dist/client', From ce4fe5ad4d50e11672fff01a5046423b2eee9cb1 Mon Sep 17 00:00:00 2001 From: Vladimir Sheremet Date: Tue, 25 Jun 2024 20:47:16 +0200 Subject: [PATCH 16/19] chore: add loupe, use info logLevel --- packages/browser/src/node/index.ts | 2 +- packages/browser/src/node/plugin.ts | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/browser/src/node/index.ts b/packages/browser/src/node/index.ts index f6c61638f55c..791c1b3752d9 100644 --- a/packages/browser/src/node/index.ts +++ b/packages/browser/src/node/index.ts @@ -25,7 +25,7 @@ export async function createBrowserServer( const vite = await createServer({ ...project.options, // spread project config inlined in root workspace config base: '/', - logLevel: (process.env.VITEST_BROWSER_DEBUG as 'info') ?? 'error', + logLevel: (process.env.VITEST_BROWSER_DEBUG as 'info') ?? 'info', mode: project.config.mode, configFile: configPath, // watch is handled by Vitest diff --git a/packages/browser/src/node/plugin.ts b/packages/browser/src/node/plugin.ts index e698927a4195..7cd3c5cba236 100644 --- a/packages/browser/src/node/plugin.ts +++ b/packages/browser/src/node/plugin.ts @@ -190,6 +190,7 @@ export default (browserServer: BrowserServer, base = '/'): Plugin[] => { 'vitest > chai > loupe', 'vitest > @vitest/runner > p-limit', 'vitest > @vitest/utils > diff-sequences', + 'vitest > @vitest/utils > loupe', '@vitest/browser > @testing-library/user-event', '@vitest/browser > @testing-library/dom', ], @@ -262,10 +263,9 @@ export default (browserServer: BrowserServer, base = '/'): Plugin[] => { enforce: 'post', async config(viteConfig) { // Enables using ignore hint for coverage providers with @preserve keyword - if (viteConfig.esbuild !== false) { - viteConfig.esbuild ||= {} - viteConfig.esbuild.legalComments = 'inline' - } + viteConfig.esbuild ||= {} + viteConfig.esbuild.legalComments = 'inline' + const server = resolveApiServerConfig( viteConfig.test?.browser || {}, defaultBrowserPort, From 138e3f15a640578a3a774e37b2faccf029e486f2 Mon Sep 17 00:00:00 2001 From: Vladimir Sheremet Date: Tue, 25 Jun 2024 21:40:24 +0200 Subject: [PATCH 17/19] chore: don't remove @vite-ignore --- packages/browser/src/node/esmInjector.ts | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/packages/browser/src/node/esmInjector.ts b/packages/browser/src/node/esmInjector.ts index c151983468e5..554b70029540 100644 --- a/packages/browser/src/node/esmInjector.ts +++ b/packages/browser/src/node/esmInjector.ts @@ -26,11 +26,13 @@ export function injectDynamicImport( // s.update(node.start, node.end, viImportMetaKey) }, onDynamicImport(node) { - const replace = '__vitest_browser_runner__.wrapModule(() => import(' + const replaceString = '__vitest_browser_runner__.wrapModule(() => import(' + const importSubstring = code.substring(node.start, node.end) + const hasIgnore = importSubstring.includes('/* @vite-ignore */') s.overwrite( node.start, (node.source as Positioned).start, - replace, + replaceString + (hasIgnore ? '/* @vite-ignore */ ' : ''), ) s.overwrite(node.end - 1, node.end, '))') }, From 8051ba8bef150e284aae215b5a315946531819f2 Mon Sep 17 00:00:00 2001 From: Vladimir Sheremet Date: Tue, 25 Jun 2024 21:49:26 +0200 Subject: [PATCH 18/19] chore: remove debug --- .github/workflows/ci.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 24a4d4eea0da..638ac8913ce5 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -17,8 +17,6 @@ concurrency: env: PLAYWRIGHT_BROWSERS_PATH: ${{ github.workspace }}/.cache/ms-playwright - VITEST_PW_DEBUG: true - VITEST_BROWSER_DEBUG: info jobs: lint: From b85b242fad4b264f69535a69d2f94f27fded8002 Mon Sep 17 00:00:00 2001 From: Vladimir Sheremet Date: Tue, 25 Jun 2024 21:51:46 +0200 Subject: [PATCH 19/19] chore: cleanup --- packages/browser/src/node/plugin.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/browser/src/node/plugin.ts b/packages/browser/src/node/plugin.ts index 7cd3c5cba236..f8d5ecd4689c 100644 --- a/packages/browser/src/node/plugin.ts +++ b/packages/browser/src/node/plugin.ts @@ -321,8 +321,8 @@ export default (browserServer: BrowserServer, base = '/'): Plugin[] => { { name: 'test-utils-rewrite', setup(build) { - const _require = getRequire() build.onResolve({ filter: /@vue\/test-utils/ }, (args) => { + const _require = getRequire() // resolve to CJS instead of the browser because the browser version expects a global Vue object const resolved = _require.resolve(args.path, { paths: [args.importer],