Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ concurrency:

env:
PLAYWRIGHT_BROWSERS_PATH: ${{ github.workspace }}/.cache/ms-playwright
VITEST_GENERATE_UI_TOKEN: 'true'

jobs:
lint:
Expand Down
1 change: 0 additions & 1 deletion .github/workflows/cr.yml
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,6 @@ jobs:
- name: Build
run: pnpm build
env:
VITEST_GENERATE_UI_TOKEN: 'true'
VITE_TEST_WATCHER_DEBUG: 'false'

- name: Publish to StackBlitz
Expand Down
1 change: 0 additions & 1 deletion .github/workflows/publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ permissions:
id-token: write

env:
VITEST_GENERATE_UI_TOKEN: 'true'
VITE_TEST_WATCHER_DEBUG: 'false'

jobs:
Expand Down
49 changes: 40 additions & 9 deletions packages/ui/CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -1,25 +1,56 @@
At project root, create terminals with each of the following commands:
# @vitest/ui Development

## UI

Use this setup for developing UI features with Vite HMR. It serves the UI from a separate dev server, so it can differ from the exact `vitest --ui` runtime path.

Start the UI dev server:

```bash
# Align with the API port configured in test/unit/vite.config.ts.
VITE_PORT=3023 pnpm -C packages/ui dev:client
```

Start a Vitest UI/API server for any test project you want to use as the backend. For example, from the repository root this runs the `test/unit` suite with UI enabled:

```bash
pnpm test --ui --open=false
```

The UI dev server only needs a real Vitest UI/API server to connect to; the backend can be `test/unit`, `packages/ui`, or another suite.

Open the URL printed by the UI dev server, usually `http://localhost:5173/`.

The UI dev server connects to the Vitest UI/API server on port `51204` by default. The root `test/unit` suite uses port `3023`, so the command above sets `VITE_PORT=3023`. If you use another backend port, pass the same port to the UI dev server:

```bash
nr ui:dev
VITE_PORT=12345 pnpm -C packages/ui dev:client
```

```bash
nr test --api
pnpm test --ui --open=false --api=12345
```

As the last command, you can use any of the available tests suites instead. Make sure that they run at 51204 port or specify a custom port with `VITE_PORT` environmental variable when running the first command. For example,
## Browser Mode UI

Use this setup for developing Browser Mode UI features with Vite HMR. It serves the Browser Mode UI from the UI dev server and injects state from a real browser-mode Vitest server.

Start a browser-mode Vitest server:

```bash
VITE_PORT=3200 nr ui:dev
pnpm -C packages/ui test:ui --browser.headless --ui --open=false
```

Start the UI dev server in browser preview mode:

```bash
nr test --api=3200
BROWSER_DEV=true pnpm -C packages/ui dev:client
```

Open the browser at the URL printed by the first command. For example, `http://localhost:5173/`. If you see a connection error, it means the port is specified incorrectly.
Open the URL printed by the UI dev server, usually `http://localhost:5173/`.

To preview the browser tab, uncomment the "browser-dev-preview" plugin in `vite.config.ts`.
The UI dev server fetches browser runner state from the browser runner server on port `63315` by default. If Vitest prints a different browser runner port, pass it to the UI dev server:

To configure the browser state, update the `__vitest_browser_runner__` object in `browser.dev.js`.
```bash
BROWSER_DEV_PORT=63316 BROWSER_DEV=true pnpm -C packages/ui dev:client
```
11 changes: 0 additions & 11 deletions packages/ui/browser.dev.js

This file was deleted.

2 changes: 1 addition & 1 deletion packages/ui/client/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@ export const PORT = import.meta.hot ? (import.meta.env.VITE_PORT || '51204') : l
export const HOST = [location.hostname, PORT].filter(Boolean).join(':')
export const ENTRY_URL = `${
location.protocol === 'https:' ? 'wss:' : 'ws:'
}//${HOST}/__vitest_api__?token=${(window as any).VITEST_API_TOKEN || '0'}`
}//${HOST}/__vitest_api__?token=${(window as any).VITEST_API_TOKEN}`
export const isReport = !!window.METADATA_PATH
export const BASE_PATH = isReport ? import.meta.env.BASE_URL : __BASE_PATH__
66 changes: 55 additions & 11 deletions packages/ui/vite.config.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import type { Plugin } from 'vite'
import Vue from '@vitejs/plugin-vue'
import { resolve } from 'pathe'
import { presetAttributify, presetIcons, presetUno, transformerDirectives } from 'unocss'
Expand Down Expand Up @@ -54,6 +55,7 @@ export default defineConfig({
Pages({
dirs: ['client/pages'],
}),
devUiScriptPlugin(),
// uncomment to see the HTML reporter preview
// {
// name: 'debug-html-report',
Expand All @@ -62,17 +64,6 @@ export default defineConfig({
// return html.replace('<!-- !LOAD_METADATA! -->', `<script>window.METADATA_PATH="${debugLink}/html.meta.json.gz"</script>`)
// },
// },

// uncomment to see the browser tab
// {
// name: 'browser-dev-preview',
// apply: 'serve',
// transformIndexHtml() {
// return [
// { tag: 'script', attrs: { src: './browser.dev.js' } },
// ]
// },
// },
{
// workaround `crossorigin` issues on some browsers
// https://github.com/vitejs/vite/issues/6648
Expand All @@ -89,3 +80,56 @@ export default defineConfig({
outDir: './dist/client',
},
})

function devUiScriptPlugin(): Plugin {
const UI_SCRIPT_RE = /<script>(window\.VITEST_API_TOKEN\s*=\s*"[^"]+")<\/script>/
const BROWSER_SCRIPT_RE = /<script type="module">([\s\S]*?window\.__vitest_browser_runner__\s*=\s*\{[\s\S]*?window\.VITEST_API_TOKEN\s*=[\s\S]*?)<\/script>/

const uiUrl = `http://localhost:${process.env.VITE_PORT || '51204'}/__vitest__/`
const browserUrl = `http://localhost:${process.env.BROWSER_DEV_PORT || '63315'}/__vitest_test__/`

return {
name: 'dev-ui-script',
apply(_config, env) {
return env.command === 'serve' && env.mode !== 'test'
},
async transformIndexHtml() {
if (process.env.BROWSER_DEV) {
const response = await fetch(browserUrl)
if (!response.ok) {
throw new Error(`Failed to fetch browser runner HTML from ${browserUrl}`)
}
const browserHtml = await response.text()
const browserScript = browserHtml.match(BROWSER_SCRIPT_RE)?.[1]
if (!browserScript) {
throw new Error('Failed to extract browser runner state from the response')
}
return [
{
tag: 'script',
attrs: { type: 'module' },
children: browserScript,
injectTo: 'head-prepend',
},
]
}

const response = await fetch(uiUrl)
if (!response.ok) {
throw new Error(`Failed to fetch VITEST_API_TOKEN from ${uiUrl}`)
}
const testHtml = await response.text()
Comment thread
sheremet-va marked this conversation as resolved.
const tokenScript = testHtml.match(UI_SCRIPT_RE)?.[1]
if (!tokenScript) {
throw new Error('Failed to extract VITEST_API_TOKEN from the response')
}
return [
{
tag: 'script',
children: tokenScript,
injectTo: 'head-prepend',
},
]
},
}
}
4 changes: 0 additions & 4 deletions packages/vitest/rollup.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -95,10 +95,6 @@ const plugins = [
transform: {
target: 'node20',
define: {
// __VITEST_GENERATE_UI_TOKEN__ is set as a global to catch accidental leaking,
// in the release version the "if" with this condition should not be present
// To test strict token locally, build by e.g. `VITEST_GENERATE_UI_TOKEN=true pnpm build`
__VITEST_GENERATE_UI_TOKEN__: process.env.VITEST_GENERATE_UI_TOKEN === 'true' ? 'true' : 'false',
...(process.env.VITE_TEST_WATCHER_DEBUG === 'false'
? {
'process.env.VITE_TEST_WATCHER_DEBUG': 'false',
Expand Down
2 changes: 1 addition & 1 deletion packages/vitest/src/node/config/resolveConfig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -675,7 +675,7 @@ export function resolveConfig(

// the server has been created, we don't need to override vite.server options
const api = resolveApiServerConfig(options, defaultPort)
resolved.api = { ...api, token: __VITEST_GENERATE_UI_TOKEN__ ? crypto.randomUUID() : '0' }
resolved.api = { ...api, token: crypto.randomUUID() }

if (options.related) {
resolved.related = toArray(options.related).map(file =>
Expand Down
5 changes: 0 additions & 5 deletions packages/vitest/src/shims.dev.d.ts

This file was deleted.

4 changes: 2 additions & 2 deletions scripts/publish-ci.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ import { readFileSync } from 'node:fs'
import { fileURLToPath } from 'node:url'
import { $ } from 'zx'

if (process.env.VITEST_GENERATE_UI_TOKEN !== 'true' || process.env.VITE_TEST_WATCHER_DEBUG !== 'false') {
throw new Error(`Cannot release Vitest without VITEST_GENERATE_UI_TOKEN=${process.env.VITEST_GENERATE_UI_TOKEN} and VITE_TEST_WATCHER_DEBUG=${process.env.VITE_TEST_WATCHER_DEBUG} environment variable. `)
if (process.env.VITE_TEST_WATCHER_DEBUG !== 'false') {
throw new Error(`Cannot release Vitest without VITE_TEST_WATCHER_DEBUG=${process.env.VITE_TEST_WATCHER_DEBUG} environment variable. `)
}

let version = process.argv[2]
Expand Down
2 changes: 0 additions & 2 deletions test/test-utils/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,6 @@ import { Cli } from './cli'

// override default colors to disable them in tests
Object.assign(tinyrainbow.default, tinyrainbow.getDefaultColors())
// @ts-expect-error not typed global
globalThis.__VITEST_GENERATE_UI_TOKEN__ = true

export interface VitestRunnerCLIOptions {
std?: 'inherit'
Expand Down
3 changes: 0 additions & 3 deletions test/unit/test/cli-test.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,6 @@ import { ReportersMap, rolldownVersion } from 'vitest/node'
import { createCLI, parseCLI } from '../../../packages/vitest/src/node/cli/cac.js'
import { resolveConfig } from '../../../packages/vitest/src/node/config/resolveConfig.js'

// @ts-expect-error not typed global
globalThis.__VITEST_GENERATE_UI_TOKEN__ = true

const vitestCli = createCLI()

function parseArguments(commands: string, full = false) {
Expand Down
Loading