-
-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: init @vitest/browser package (#1302)
Co-authored-by: Joaquín Sánchez Jiménez <joaquin.sanchez@fi2net.es> Co-authored-by: userquin <userquin@gmail.com> Co-authored-by: M. Bagher Abiat <zorofight94@gmail.com>
- Loading branch information
1 parent
7c2138f
commit 88033bc
Showing
61 changed files
with
795 additions
and
91 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
# @vitest/browser | ||
|
||
Browser runner for Vitest. | ||
|
||
> ⚠️ This package is **not yet ready** and it's for preview only. While this package will be released along with other packages, it will not follow semver for breaking changes until we mark it as ready. **Do not use it in production**. | ||
## Progress | ||
|
||
Current Status: **Working in progress** | ||
|
||
- [x] Init package and integration | ||
- [x] Stub node packages for Vitest runtime | ||
- [ ] Works in development mode | ||
- [ ] Better log in terminal | ||
- [ ] Fulfill tests (using Browser only APIs, Vue and React components) | ||
- [ ] Show progress and error on the browser page | ||
- [ ] Headless mode in CI | ||
- [ ] Docs | ||
|
||
Related PRs | ||
|
||
- [#1302](https://github.com/vitest-dev/vitest/pull/1302) | ||
|
||
## Development Setup | ||
|
||
At project root: | ||
|
||
```bash | ||
pnpm dev | ||
|
||
cd test/browser | ||
pnpm vitest --browser | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,88 @@ | ||
import type { VitestClient } from '@vitest/ws-client' | ||
import { createClient } from '@vitest/ws-client' | ||
// eslint-disable-next-line no-restricted-imports | ||
import type { ResolvedConfig } from 'vitest' | ||
|
||
// @ts-expect-error mocking some node apis | ||
globalThis.process = { env: {}, argv: [], stdout: { write: () => {} } } | ||
globalThis.global = globalThis | ||
|
||
export const PORT = import.meta.hot ? '51204' : location.port | ||
export const HOST = [location.hostname, PORT].filter(Boolean).join(':') | ||
export const ENTRY_URL = `${ | ||
location.protocol === 'https:' ? 'wss:' : 'ws:' | ||
}//${HOST}/__vitest_api__` | ||
|
||
let config: ResolvedConfig | undefined | ||
const browserHashMap = new Map<string, string>() | ||
|
||
export const client = createClient(ENTRY_URL, { | ||
handlers: { | ||
async onPathsCollected(paths) { | ||
if (!paths) | ||
return | ||
|
||
// const config = __vitest_worker__.config | ||
const now = `${new Date().getTime()}` | ||
paths.forEach((i) => { | ||
browserHashMap.set(i, now) | ||
}) | ||
|
||
await runTests(paths, config, client) | ||
}, | ||
}, | ||
}) | ||
|
||
const ws = client.ws | ||
|
||
async function loadConfig() { | ||
let retries = 5 | ||
do { | ||
try { | ||
await new Promise(resolve => setTimeout(resolve, 150)) | ||
config = await client.rpc.getConfig() | ||
return | ||
} | ||
catch (_) { | ||
// just ignore | ||
} | ||
} | ||
while (--retries > 0) | ||
|
||
throw new Error('cannot load configuration after 5 retries') | ||
} | ||
|
||
ws.addEventListener('open', async () => { | ||
await loadConfig() | ||
|
||
// @ts-expect-error mocking vitest apis | ||
globalThis.__vitest_worker__ = { | ||
config, | ||
browserHashMap, | ||
rpc: client.rpc, | ||
} | ||
|
||
// @ts-expect-error mocking vitest apis | ||
globalThis.__vitest_mocker__ = {} | ||
const paths = await client.rpc.getPaths() | ||
|
||
const now = `${new Date().getTime()}` | ||
paths.forEach(i => browserHashMap.set(i, now)) | ||
|
||
const iFrame = document.getElementById('vitest-ui') as HTMLIFrameElement | ||
iFrame.setAttribute('src', '/__vitest__/') | ||
|
||
await runTests(paths, config, client) | ||
}) | ||
|
||
async function runTests(paths: string[], config: any, client: VitestClient) { | ||
const name = '/__vitest_index__' | ||
const { startTests, setupGlobalEnv } = (await import(name)) as unknown as typeof import('vitest/browser') | ||
|
||
await setupGlobalEnv(config as any) | ||
|
||
await startTests(paths, config as any) | ||
|
||
await client.rpc.onFinished() | ||
await client.rpc.onWatcherStart() | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
<!DOCTYPE html> | ||
<html lang="en"> | ||
<head> | ||
<meta charset="UTF-8" /> | ||
<link rel="icon" href="/favicon.svg" type="image/svg+xml"> | ||
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> | ||
<title>Vitest Browser Runner</title> | ||
<style> | ||
html { | ||
overflow: hidden; | ||
padding: 0; | ||
margin: 0; | ||
} | ||
body { | ||
padding: 0; | ||
margin: 0; | ||
} | ||
#vitest-ui { | ||
width: 100vw; | ||
height: 100vh; | ||
border: none; | ||
} | ||
</style> | ||
</head> | ||
<body> | ||
<iframe id="vitest-ui" src=""></iframe> | ||
<script type="module" src="./client/main.ts"></script> | ||
</body> | ||
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,85 @@ | ||
import { fileURLToPath } from 'url' | ||
// eslint-disable-next-line no-restricted-imports | ||
import { resolve } from 'path' | ||
import { builtinModules } from 'module' | ||
import { polyfillPath } from 'modern-node-polyfills' | ||
import sirv from 'sirv' | ||
import type { Plugin } from 'vite' | ||
import { resolvePath } from 'mlly' | ||
|
||
const stubs = [ | ||
'fs', | ||
'local-pkg', | ||
'module', | ||
'noop', | ||
'perf_hooks', | ||
] | ||
|
||
const polyfills = [ | ||
'util', | ||
'tty', | ||
'process', | ||
'path', | ||
'buffer', | ||
] | ||
|
||
export default (base = '/'): Plugin[] => { | ||
const pkgRoot = resolve(fileURLToPath(import.meta.url), '../..') | ||
const distRoot = resolve(pkgRoot, 'dist') | ||
|
||
return [ | ||
{ | ||
enforce: 'pre', | ||
name: 'vitest:browser', | ||
async resolveId(id, _, ctx) { | ||
if (ctx.ssr) | ||
return | ||
|
||
if (id === '/__vitest_index__') { | ||
const result = await resolvePath('vitest/browser') | ||
return result | ||
} | ||
|
||
if (stubs.includes(id)) | ||
return resolve(pkgRoot, 'stubs', id) | ||
|
||
if (polyfills.includes(id)) | ||
return polyfillPath(normalizeId(id)) | ||
|
||
return null | ||
}, | ||
async configureServer(server) { | ||
server.middlewares.use( | ||
base, | ||
sirv(resolve(distRoot, 'client'), { | ||
single: false, | ||
dev: true, | ||
}), | ||
) | ||
}, | ||
}, | ||
{ | ||
name: 'modern-node-polyfills', | ||
async resolveId(id, _, ctx) { | ||
if (ctx.ssr || !builtinModules.includes(id)) | ||
return | ||
|
||
id = normalizeId(id) | ||
return { id: await polyfillPath(id), moduleSideEffects: false } | ||
}, | ||
}, | ||
] | ||
} | ||
|
||
function normalizeId(id: string, base?: string): string { | ||
if (base && id.startsWith(base)) | ||
id = `/${id.slice(base.length)}` | ||
|
||
return id | ||
.replace(/^\/@id\/__x00__/, '\0') // virtual modules start with `\0` | ||
.replace(/^\/@id\//, '') | ||
.replace(/^__vite-browser-external:/, '') | ||
.replace(/^node:/, '') | ||
.replace(/[?&]v=\w+/, '?') // remove ?v= query | ||
.replace(/\?$/, '') // remove end query mark | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
{ | ||
"name": "@vitest/browser", | ||
"type": "module", | ||
"version": "0.4.1", | ||
"description": "Browser running for Vitest", | ||
"repository": { | ||
"type": "git", | ||
"url": "git+https://github.com/vitest-dev/vitest.git", | ||
"directory": "packages/browser" | ||
}, | ||
"sideEffects": false, | ||
"exports": { | ||
".": { | ||
"types": "./dist/index.d.ts", | ||
"import": "./dist/index.js" | ||
}, | ||
"./*": "./*" | ||
}, | ||
"main": "./dist/index.js", | ||
"module": "./dist/index.js", | ||
"types": "./dist/index.d.ts", | ||
"files": [ | ||
"dist", | ||
"stubs" | ||
], | ||
"scripts": { | ||
"build": "rimraf dist && pnpm build:node && pnpm build:client && pnpm copy", | ||
"build:client": "vite build", | ||
"build:node": "rollup -c", | ||
"dev:client": "vite build --watch", | ||
"dev:node": "rollup -c --watch --watch.include=node/**", | ||
"dev": "rimraf dist && run-p dev:node dev:client", | ||
"copy": "esmo scripts/copy-ui-to-browser.ts" | ||
}, | ||
"dependencies": { | ||
"local-pkg": "^0.4.1", | ||
"mlly": "^0.5.2", | ||
"modern-node-polyfills": "^0.0.7", | ||
"rollup-plugin-node-polyfills": "^0.2.1", | ||
"sirv": "^2.0.2" | ||
}, | ||
"devDependencies": { | ||
"@types/ws": "^8.2.2", | ||
"@vitest/ws-client": "workspace:*", | ||
"picocolors": "^1.0.0", | ||
"rollup": "^2.67.2", | ||
"vitest": "workspace:*" | ||
} | ||
} |
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
import esbuild from 'rollup-plugin-esbuild' | ||
import dts from 'rollup-plugin-dts' | ||
import resolve from '@rollup/plugin-node-resolve' | ||
import commonjs from '@rollup/plugin-commonjs' | ||
import json from '@rollup/plugin-json' | ||
import alias from '@rollup/plugin-alias' | ||
import pkg from './package.json' | ||
|
||
const external = [ | ||
...Object.keys(pkg.dependencies), | ||
...Object.keys(pkg.peerDependencies || {}), | ||
'worker_threads', | ||
] | ||
|
||
const plugins = [ | ||
alias({ | ||
entries: [{ find: /^node:(.+)$/, replacement: '$1' }], | ||
}), | ||
resolve({ | ||
preferBuiltins: true, | ||
}), | ||
json(), | ||
commonjs(), | ||
esbuild({ | ||
target: 'node14', | ||
}), | ||
] | ||
|
||
export default () => [ | ||
{ | ||
input: [ | ||
'./node/index.ts', | ||
], | ||
output: { | ||
dir: 'dist', | ||
format: 'esm', | ||
}, | ||
external, | ||
plugins, | ||
}, | ||
{ | ||
input: './node/index.ts', | ||
output: { | ||
file: 'dist/index.d.ts', | ||
format: 'esm', | ||
}, | ||
external, | ||
plugins: [dts()], | ||
}, | ||
] |
Oops, something went wrong.