Skip to content

Commit

Permalink
Merge branch 'main' into fix-vite-node-invalidate-source-map-cache
Browse files Browse the repository at this point in the history
  • Loading branch information
hi-ogawa authored Oct 28, 2024
2 parents 78e8f22 + 03a7703 commit f765391
Show file tree
Hide file tree
Showing 44 changed files with 520 additions and 130 deletions.
8 changes: 8 additions & 0 deletions docs/config/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -1640,6 +1640,14 @@ Run the browser in a `headless` mode. If you are running Vitest in CI, it will b

Run every test in a separate iframe.

#### browser.testerHtmlPath

- **Type:** `string`
- **Default:** `@vitest/browser/tester.html`
- **Version:** Since Vitest 2.1.4

A path to the HTML entry point. Can be relative to the root of the project. This file will be processed with [`transformIndexHtml`](https://vite.dev/guide/api-plugin#transformindexhtml) hook.

#### browser.api

- **Type:** `number | { port?, strictPort?, host? }`
Expand Down
2 changes: 1 addition & 1 deletion docs/guide/debugging.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ When debugging tests you might want to use `--test-timeout` CLI argument to prev

## VS Code

Quick way to debug tests in VS Code is via `JavaScript Debug Terminal`. Open a new `JavaScript Debug Terminal` and run `npm run test` or `vitest` directly. *this works with any code ran in Node, so will work with most JS testing frameworks*
Quick way to debug tests in VS Code is via `JavaScript Debug Terminal`. Open a new `JavaScript Debug Terminal` and run `npm run test` or `vitest` directly. *this works with any code run in Node, so will work with most JS testing frameworks*

![image](https://user-images.githubusercontent.com/5594348/212169143-72bf39ce-f763-48f5-822a-0c8b2e6a8484.png)

Expand Down
2 changes: 1 addition & 1 deletion packages/browser/rollup.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ export default () =>
input: './src/client/tester/state.ts',
output: {
file: 'dist/state.js',
format: 'esm',
format: 'iife',
},
plugins: [
esbuild({
Expand Down
4 changes: 3 additions & 1 deletion packages/browser/src/client/public/error-catcher.js
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,9 @@ async function reportUnexpectedError(
error,
) {
const processedError = serializeError(error)
await client.rpc.onUnhandledError(processedError, type)
await client.waitForConnection().then(() => {
return client.rpc.onUnhandledError(processedError, type)
}).catch(console.error)
const state = __vitest_browser_runner__

if (state.type === 'orchestrator') {
Expand Down
98 changes: 50 additions & 48 deletions packages/browser/src/client/public/esm-client-injector.js
Original file line number Diff line number Diff line change
@@ -1,50 +1,52 @@
const moduleCache = new Map();

function wrapModule(module) {
if (typeof module === "function") {
const promise = new Promise((resolve, reject) => {
if (typeof __vitest_mocker__ === "undefined")
return module().then(resolve, reject);
__vitest_mocker__.prepare().finally(() => {
module().then(resolve, reject);
(() => {
const moduleCache = new Map();

function wrapModule(module) {
if (typeof module === "function") {
const promise = new Promise((resolve, reject) => {
if (typeof __vitest_mocker__ === "undefined")
return module().then(resolve, reject);
__vitest_mocker__.prepare().finally(() => {
module().then(resolve, reject);
});
});
});
moduleCache.set(promise, { promise, evaluated: false });
return promise.finally(() => moduleCache.delete(promise));
moduleCache.set(promise, { promise, evaluated: false });
return promise.finally(() => moduleCache.delete(promise));
}
return module;
}
return module;
}

window.__vitest_browser_runner__ = {
wrapModule,
wrapDynamicImport: wrapModule,
moduleCache,
config: { __VITEST_CONFIG__ },
viteConfig: { __VITEST_VITE_CONFIG__ },
files: { __VITEST_FILES__ },
type: { __VITEST_TYPE__ },
contextId: { __VITEST_CONTEXT_ID__ },
testerId: { __VITEST_TESTER_ID__ },
provider: { __VITEST_PROVIDER__ },
providedContext: { __VITEST_PROVIDED_CONTEXT__ },
};

const config = __vitest_browser_runner__.config;

if (config.testNamePattern)
config.testNamePattern = parseRegexp(config.testNamePattern);

function parseRegexp(input) {
// Parse input
const m = input.match(/(\/?)(.+)\1([a-z]*)/i);

// match nothing
if (!m) return /$^/;

// Invalid flags
if (m[3] && !/^(?!.*?(.).*?\1)[gmixXsuUAJ]+$/.test(m[3]))
return RegExp(input);

// Create the regular expression
return new RegExp(m[2], m[3]);
}

window.__vitest_browser_runner__ = {
wrapModule,
wrapDynamicImport: wrapModule,
moduleCache,
config: { __VITEST_CONFIG__ },
viteConfig: { __VITEST_VITE_CONFIG__ },
files: { __VITEST_FILES__ },
type: { __VITEST_TYPE__ },
contextId: { __VITEST_CONTEXT_ID__ },
testerId: { __VITEST_TESTER_ID__ },
provider: { __VITEST_PROVIDER__ },
providedContext: { __VITEST_PROVIDED_CONTEXT__ },
};

const config = __vitest_browser_runner__.config;

if (config.testNamePattern)
config.testNamePattern = parseRegexp(config.testNamePattern);

function parseRegexp(input) {
// Parse input
const m = input.match(/(\/?)(.+)\1([a-z]*)/i);

// match nothing
if (!m) return /$^/;

// Invalid flags
if (m[3] && !/^(?!.*?(.).*?\1)[gmixXsuUAJ]+$/.test(m[3]))
return RegExp(input);

// Create the regular expression
return new RegExp(m[2], m[3]);
}
})();
7 changes: 1 addition & 6 deletions packages/browser/src/client/tester/tester.html
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<meta charset="UTF-8" />
<link rel="icon" href="{__VITEST_FAVICON__}" type="image/svg+xml">
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>{__VITEST_TITLE__}</title>
<title>Vitest Browser Tester</title>
<style>
html {
padding: 0;
Expand All @@ -16,13 +16,8 @@
min-height: 100vh;
}
</style>
{__VITEST_INJECTOR__}
<script>{__VITEST_STATE__}</script>
{__VITEST_INTERNAL_SCRIPTS__}
{__VITEST_SCRIPTS__}
</head>
<body>
<script type="module" src="./tester.ts"></script>
{__VITEST_APPEND__}
</body>
</html>
3 changes: 2 additions & 1 deletion packages/browser/src/client/vite.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,13 +42,14 @@ export default defineConfig({
)

const ui = resolve(root, 'ui/dist/client')
const uiEntryPoint = resolve(ui, 'index.html')
const browser = resolve(root, 'browser/dist/client/__vitest__/')

const timeout = setTimeout(
() => console.log('[copy-ui-plugin] Waiting for UI to be built...'),
1000,
)
await waitFor(() => fs.existsSync(ui))
await waitFor(() => fs.existsSync(ui) && fs.existsSync(uiEntryPoint))
clearTimeout(timeout)

const files = globSync(['**/*'], { cwd: ui, expandDirectories: false })
Expand Down
105 changes: 102 additions & 3 deletions packages/browser/src/node/plugin.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import type { Stats } from 'node:fs'
import type { HtmlTagDescriptor } from 'vite'
import type { WorkspaceProject } from 'vitest/node'
import type { BrowserServer } from './server'
import { lstatSync, readFileSync } from 'node:fs'
Expand Down Expand Up @@ -72,9 +73,11 @@ export default (browserServer: BrowserServer, base = '/'): Plugin[] => {
return
}

const html = await resolveTester(browserServer, url, res)
res.write(html, 'utf-8')
res.end()
const html = await resolveTester(browserServer, url, res, next)
if (html) {
res.write(html, 'utf-8')
res.end()
}
})

server.middlewares.use(
Expand Down Expand Up @@ -394,6 +397,102 @@ export default (browserServer: BrowserServer, base = '/'): Plugin[] => {
}
},
},
{
name: 'vitest:browser:transform-tester-html',
enforce: 'pre',
async transformIndexHtml(html, ctx) {
if (!ctx.path.startsWith(browserServer.prefixTesterUrl)) {
return
}

if (!browserServer.testerScripts) {
const testerScripts = await browserServer.formatScripts(
project.config.browser.testerScripts,
)
browserServer.testerScripts = testerScripts
}
const stateJs = typeof browserServer.stateJs === 'string'
? browserServer.stateJs
: await browserServer.stateJs

const testerScripts: HtmlTagDescriptor[] = []
if (resolve(distRoot, 'client/tester/tester.html') !== browserServer.testerFilepath) {
const manifestContent = browserServer.manifest instanceof Promise
? await browserServer.manifest
: browserServer.manifest
const testerEntry = manifestContent['tester/tester.html']

testerScripts.push({
tag: 'script',
attrs: {
type: 'module',
crossorigin: '',
src: `${browserServer.base}${testerEntry.file}`,
},
injectTo: 'head',
})

for (const importName of testerEntry.imports || []) {
const entryManifest = manifestContent[importName]
if (entryManifest) {
testerScripts.push(
{
tag: 'link',
attrs: {
href: `${browserServer.base}${entryManifest.file}`,
rel: 'modulepreload',
crossorigin: '',
},
injectTo: 'head',
},
)
}
}
}

return [
{
tag: 'script',
children: '{__VITEST_INJECTOR__}',
injectTo: 'head-prepend' as const,
},
{
tag: 'script',
children: stateJs,
injectTo: 'head-prepend',
} as const,
{
tag: 'script',
attrs: {
type: 'module',
src: browserServer.errorCatcherUrl,
},
injectTo: 'head' as const,
},
browserServer.locatorsUrl
? {
tag: 'script',
attrs: {
type: 'module',
src: browserServer.locatorsUrl,
},
injectTo: 'head',
} as const
: null,
...browserServer.testerScripts,
...testerScripts,
{
tag: 'script',
attrs: {
'type': 'module',
'data-vitest-append': '',
},
children: '{__VITEST_APPEND__}',
injectTo: 'body',
} as const,
].filter(s => s != null)
},
},
{
name: 'vitest:browser:support-testing-library',
config() {
Expand Down
3 changes: 1 addition & 2 deletions packages/browser/src/node/pool.ts
Original file line number Diff line number Diff line change
Expand Up @@ -101,8 +101,7 @@ export function createBrowserPool(ctx: Vitest): ProcessPool {
url.searchParams.set('contextId', contextId)
const page = provider
.openPage(contextId, url.toString(), () => setBreakpoint(contextId, files[0]))
.then(() => waitPromise)
promises.push(page)
promises.push(page, waitPromise)
}
})

Expand Down
Loading

0 comments on commit f765391

Please sign in to comment.