mirror of
https://github.com/vitest-dev/vitest.git
synced 2025-12-08 18:26:03 +00:00
618 lines
18 KiB
Markdown
618 lines
18 KiB
Markdown
---
|
||
title: Browser Config Reference | Config
|
||
outline: deep
|
||
---
|
||
|
||
# Browser Config Reference
|
||
|
||
You can change the browser configuration by updating the `test.browser` field in your [config file](/config/). An example of a simple config file:
|
||
|
||
```ts [vitest.config.ts]
|
||
import { defineConfig } from 'vitest/config'
|
||
import { playwright } from '@vitest/browser-playwright'
|
||
|
||
export default defineConfig({
|
||
test: {
|
||
browser: {
|
||
enabled: true,
|
||
provider: playwright(),
|
||
instances: [
|
||
{
|
||
browser: 'chromium',
|
||
setupFile: './chromium-setup.js',
|
||
},
|
||
],
|
||
},
|
||
},
|
||
})
|
||
```
|
||
|
||
Please, refer to the ["Config Reference"](/config/) article for different config examples.
|
||
|
||
::: warning
|
||
_All listed options_ on this page are located within a `test` property inside the configuration:
|
||
|
||
```ts [vitest.config.js]
|
||
export default defineConfig({
|
||
test: {
|
||
browser: {},
|
||
},
|
||
})
|
||
```
|
||
:::
|
||
|
||
## browser.enabled
|
||
|
||
- **Type:** `boolean`
|
||
- **Default:** `false`
|
||
- **CLI:** `--browser`, `--browser.enabled=false`
|
||
|
||
Run all tests inside a browser by default. Note that `--browser` only works if you have at least one [`browser.instances`](#browser-instances) item.
|
||
|
||
## browser.instances
|
||
|
||
- **Type:** `BrowserConfig`
|
||
- **Default:** `[]`
|
||
|
||
Defines multiple browser setups. Every config has to have at least a `browser` field.
|
||
|
||
You can specify most of the [project options](/config/) (not marked with a <CRoot /> icon) and some of the `browser` options like `browser.testerHtmlPath`.
|
||
|
||
::: warning
|
||
Every browser config inherits options from the root config:
|
||
|
||
```ts{3,9} [vitest.config.ts]
|
||
export default defineConfig({
|
||
test: {
|
||
setupFile: ['./root-setup-file.js'],
|
||
browser: {
|
||
enabled: true,
|
||
testerHtmlPath: './custom-path.html',
|
||
instances: [
|
||
{
|
||
// will have both setup files: "root" and "browser"
|
||
setupFile: ['./browser-setup-file.js'],
|
||
// implicitly has "testerHtmlPath" from the root config // [!code warning]
|
||
// testerHtmlPath: './custom-path.html', // [!code warning]
|
||
},
|
||
],
|
||
},
|
||
},
|
||
})
|
||
```
|
||
|
||
For more examples, refer to the ["Multiple Setups" guide](/guide/browser/multiple-setups).
|
||
:::
|
||
|
||
List of available `browser` options:
|
||
|
||
- [`browser.headless`](#browser-headless)
|
||
- [`browser.locators`](#browser-locators)
|
||
- [`browser.viewport`](#browser-viewport)
|
||
- [`browser.testerHtmlPath`](#browser-testerhtmlpath)
|
||
- [`browser.screenshotDirectory`](#browser-screenshotdirectory)
|
||
- [`browser.screenshotFailures`](#browser-screenshotfailures)
|
||
- [`browser.provider`](#browser-provider)
|
||
|
||
Under the hood, Vitest transforms these instances into separate [test projects](/api/advanced/test-project) sharing a single Vite server for better caching performance.
|
||
|
||
## browser.headless
|
||
|
||
- **Type:** `boolean`
|
||
- **Default:** `process.env.CI`
|
||
- **CLI:** `--browser.headless`, `--browser.headless=false`
|
||
|
||
Run the browser in a `headless` mode. If you are running Vitest in CI, it will be enabled by default.
|
||
|
||
## browser.isolate <Deprecated />
|
||
|
||
- **Type:** `boolean`
|
||
- **Default:** the same as [`--isolate`](/config/#isolate)
|
||
- **CLI:** `--browser.isolate`, `--browser.isolate=false`
|
||
|
||
Run every test in a separate iframe.
|
||
|
||
::: danger DEPRECATED
|
||
This option is deprecated. Use [`isolate`](/config/#isolate) instead.
|
||
:::
|
||
|
||
## browser.testerHtmlPath
|
||
|
||
- **Type:** `string`
|
||
|
||
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? }`
|
||
- **Default:** `63315`
|
||
- **CLI:** `--browser.api=63315`, `--browser.api.port=1234, --browser.api.host=example.com`
|
||
|
||
Configure options for Vite server that serves code in the browser. Does not affect [`test.api`](#api) option. By default, Vitest assigns port `63315` to avoid conflicts with the development server, allowing you to run both in parallel.
|
||
|
||
## browser.provider {#browser-provider}
|
||
|
||
- **Type:** `BrowserProviderOption`
|
||
- **Default:** `'preview'`
|
||
- **CLI:** `--browser.provider=playwright`
|
||
|
||
The return value of the provider factory. You can import the factory from `@vitest/browser-<provider-name>` or make your own provider:
|
||
|
||
```ts{8-10}
|
||
import { playwright } from '@vitest/browser-playwright'
|
||
import { webdriverio } from '@vitest/browser-webdriverio'
|
||
import { preview } from '@vitest/browser-preview'
|
||
|
||
export default defineConfig({
|
||
test: {
|
||
browser: {
|
||
provider: playwright(),
|
||
provider: webdriverio(),
|
||
provider: preview(), // default
|
||
},
|
||
},
|
||
})
|
||
```
|
||
|
||
To configure how provider initializes the browser, you can pass down options to the factory function:
|
||
|
||
```ts{7-13,20-26}
|
||
import { playwright } from '@vitest/browser-playwright'
|
||
|
||
export default defineConfig({
|
||
test: {
|
||
browser: {
|
||
// shared provider options between all instances
|
||
provider: playwright({
|
||
launchOptions: {
|
||
slowMo: 50,
|
||
channel: 'chrome-beta',
|
||
},
|
||
actionTimeout: 5_000,
|
||
}),
|
||
instances: [
|
||
{ browser: 'chromium' },
|
||
{
|
||
browser: 'firefox',
|
||
// overriding options only for a single instance
|
||
// this will NOT merge options with the parent one
|
||
provider: playwright({
|
||
launchOptions: {
|
||
firefoxUserPrefs: {
|
||
'browser.startup.homepage': 'https://example.com',
|
||
},
|
||
},
|
||
})
|
||
}
|
||
],
|
||
},
|
||
},
|
||
})
|
||
```
|
||
|
||
### Custom Provider <Badge type="danger">advanced</Badge>
|
||
|
||
::: danger ADVANCED API
|
||
The custom provider API is highly experimental and can change between patches. If you just need to run tests in a browser, use the [`browser.instances`](#browser-instances) option instead.
|
||
:::
|
||
|
||
```ts
|
||
export interface BrowserProvider {
|
||
name: string
|
||
mocker?: BrowserModuleMocker
|
||
readonly initScripts?: string[]
|
||
/**
|
||
* @experimental opt-in into file parallelisation
|
||
*/
|
||
supportsParallelism: boolean
|
||
getCommandsContext: (sessionId: string) => Record<string, unknown>
|
||
openPage: (sessionId: string, url: string) => Promise<void>
|
||
getCDPSession?: (sessionId: string) => Promise<CDPSession>
|
||
close: () => Awaitable<void>
|
||
}
|
||
```
|
||
|
||
## browser.ui
|
||
|
||
- **Type:** `boolean`
|
||
- **Default:** `!isCI`
|
||
- **CLI:** `--browser.ui=false`
|
||
|
||
Should Vitest UI be injected into the page. By default, injects UI iframe during development.
|
||
|
||
## browser.viewport
|
||
|
||
- **Type:** `{ width, height }`
|
||
- **Default:** `414x896`
|
||
|
||
Default iframe's viewport.
|
||
|
||
## browser.locators
|
||
|
||
Options for built-in [browser locators](/api/browser/locators).
|
||
|
||
### browser.locators.testIdAttribute
|
||
|
||
- **Type:** `string`
|
||
- **Default:** `data-testid`
|
||
|
||
Attribute used to find elements with `getByTestId` locator.
|
||
|
||
## browser.screenshotDirectory
|
||
|
||
- **Type:** `string`
|
||
- **Default:** `__screenshots__` in the test file directory
|
||
|
||
Path to the screenshots directory relative to the `root`.
|
||
|
||
## browser.screenshotFailures
|
||
|
||
- **Type:** `boolean`
|
||
- **Default:** `!browser.ui`
|
||
|
||
Should Vitest take screenshots if the test fails.
|
||
|
||
## browser.orchestratorScripts
|
||
|
||
- **Type:** `BrowserScript[]`
|
||
- **Default:** `[]`
|
||
|
||
Custom scripts that should be injected into the orchestrator HTML before test iframes are initiated. This HTML document only sets up iframes and doesn't actually import your code.
|
||
|
||
The script `src` and `content` will be processed by Vite plugins. Script should be provided in the following shape:
|
||
|
||
```ts
|
||
export interface BrowserScript {
|
||
/**
|
||
* If "content" is provided and type is "module", this will be its identifier.
|
||
*
|
||
* If you are using TypeScript, you can add `.ts` extension here for example.
|
||
* @default `injected-${index}.js`
|
||
*/
|
||
id?: string
|
||
/**
|
||
* JavaScript content to be injected. This string is processed by Vite plugins if type is "module".
|
||
*
|
||
* You can use `id` to give Vite a hint about the file extension.
|
||
*/
|
||
content?: string
|
||
/**
|
||
* Path to the script. This value is resolved by Vite so it can be a node module or a file path.
|
||
*/
|
||
src?: string
|
||
/**
|
||
* If the script should be loaded asynchronously.
|
||
*/
|
||
async?: boolean
|
||
/**
|
||
* Script type.
|
||
* @default 'module'
|
||
*/
|
||
type?: string
|
||
}
|
||
```
|
||
|
||
## browser.commands
|
||
|
||
- **Type:** `Record<string, BrowserCommand>`
|
||
- **Default:** `{ readFile, writeFile, ... }`
|
||
|
||
Custom [commands](/api/browser/commands) that can be imported during browser tests from `vitest/browser`.
|
||
|
||
## browser.connectTimeout
|
||
|
||
- **Type:** `number`
|
||
- **Default:** `60_000`
|
||
|
||
The timeout in milliseconds. If connection to the browser takes longer, the test suite will fail.
|
||
|
||
::: info
|
||
This is the time it should take for the browser to establish the WebSocket connection with the Vitest server. In normal circumstances, this timeout should never be reached.
|
||
:::
|
||
|
||
## browser.trace
|
||
|
||
- **Type:** `'on' | 'off' | 'on-first-retry' | 'on-all-retries' | 'retain-on-failure' | object`
|
||
- **CLI:** `--browser.trace=on`, `--browser.trace=retain-on-failure`
|
||
- **Default:** `'off'`
|
||
|
||
Capture a trace of your browser test runs. You can preview traces with [Playwright Trace Viewer](https://trace.playwright.dev/).
|
||
|
||
This options supports the following values:
|
||
|
||
- `'on'` - capture trace for all tests. (not recommended as it's performance heavy)
|
||
- `'off'` - do not capture traces.
|
||
- `'on-first-retry'` - capture trace only when retrying the test for the first time.
|
||
- `'on-all-retries'` - capture trace on every retry of the test.
|
||
- `'retain-on-failure'` - capture trace only for tests that fail. This will automatically delete traces for tests that pass.
|
||
- `object` - an object with the following shape:
|
||
|
||
```ts
|
||
interface TraceOptions {
|
||
mode: 'on' | 'off' | 'on-first-retry' | 'on-all-retries' | 'retain-on-failure'
|
||
/**
|
||
* The directory where all traces will be stored. By default, Vitest
|
||
* stores all traces in `__traces__` folder close to the test file.
|
||
*/
|
||
tracesDir?: string
|
||
/**
|
||
* Whether to capture screenshots during tracing. Screenshots are used to build a timeline preview.
|
||
* @default true
|
||
*/
|
||
screenshots?: boolean
|
||
/**
|
||
* If this option is true tracing will
|
||
* - capture DOM snapshot on every action
|
||
* - record network activity
|
||
* @default true
|
||
*/
|
||
snapshots?: boolean
|
||
}
|
||
```
|
||
|
||
::: danger WARNING
|
||
This option is supported only by the [**playwright**](/config/browser/playwright) provider.
|
||
:::
|
||
|
||
## browser.trackUnhandledErrors
|
||
|
||
- **Type:** `boolean`
|
||
- **Default:** `true`
|
||
|
||
Enables tracking uncaught errors and exceptions so they can be reported by Vitest.
|
||
|
||
If you need to hide certain errors, it is recommended to use [`onUnhandledError`](/config/#onunhandlederror) option instead.
|
||
|
||
Disabling this will completely remove all Vitest error handlers, which can help debugging with the "Pause on exceptions" checkbox turned on.
|
||
|
||
## browser.expect
|
||
|
||
- **Type:** `ExpectOptions`
|
||
|
||
### browser.expect.toMatchScreenshot
|
||
|
||
Default options for the
|
||
[`toMatchScreenshot` assertion](/api/browser/assertions.html#tomatchscreenshot).
|
||
These options will be applied to all screenshot assertions.
|
||
|
||
::: tip
|
||
Setting global defaults for screenshot assertions helps maintain consistency
|
||
across your test suite and reduces repetition in individual tests. You can still
|
||
override these defaults at the assertion level when needed for specific test cases.
|
||
:::
|
||
|
||
```ts
|
||
import { defineConfig } from 'vitest/config'
|
||
|
||
export default defineConfig({
|
||
test: {
|
||
browser: {
|
||
enabled: true,
|
||
expect: {
|
||
toMatchScreenshot: {
|
||
comparatorName: 'pixelmatch',
|
||
comparatorOptions: {
|
||
threshold: 0.2,
|
||
allowedMismatchedPixels: 100,
|
||
},
|
||
resolveScreenshotPath: ({ arg, browserName, ext, testFileName }) =>
|
||
`custom-screenshots/${testFileName}/${arg}-${browserName}${ext}`,
|
||
},
|
||
},
|
||
},
|
||
},
|
||
})
|
||
```
|
||
|
||
[All options available in the `toMatchScreenshot` assertion](/api/browser/assertions#options)
|
||
can be configured here. Additionally, two path resolution functions are
|
||
available: `resolveScreenshotPath` and `resolveDiffPath`.
|
||
|
||
#### browser.expect.toMatchScreenshot.resolveScreenshotPath
|
||
|
||
- **Type:** `(data: PathResolveData) => string`
|
||
- **Default output:** `` `${root}/${testFileDirectory}/${screenshotDirectory}/${testFileName}/${arg}-${browserName}-${platform}${ext}` ``
|
||
|
||
A function to customize where reference screenshots are stored. The function
|
||
receives an object with the following properties:
|
||
|
||
- `arg: string`
|
||
|
||
Path **without** extension, sanitized and relative to the test file.
|
||
|
||
This comes from the arguments passed to `toMatchScreenshot`; if called
|
||
without arguments this will be the auto-generated name.
|
||
|
||
```ts
|
||
test('calls `onClick`', () => {
|
||
expect(locator).toMatchScreenshot()
|
||
// arg = "calls-onclick-1"
|
||
})
|
||
|
||
expect(locator).toMatchScreenshot('foo/bar/baz.png')
|
||
// arg = "foo/bar/baz"
|
||
|
||
expect(locator).toMatchScreenshot('../foo/bar/baz.png')
|
||
// arg = "foo/bar/baz"
|
||
```
|
||
|
||
- `ext: string`
|
||
|
||
Screenshot extension, with leading dot.
|
||
|
||
This can be set through the arguments passed to `toMatchScreenshot`, but
|
||
the value will fall back to `'.png'` if an unsupported extension is used.
|
||
|
||
- `browserName: string`
|
||
|
||
The instance's browser name.
|
||
|
||
- `platform: NodeJS.Platform`
|
||
|
||
The value of
|
||
[`process.platform`](https://nodejs.org/docs/v22.16.0/api/process.html#processplatform).
|
||
|
||
- `screenshotDirectory: string`
|
||
|
||
The value provided to
|
||
[`browser.screenshotDirectory`](/config/browser/screenshotdirectory),
|
||
if none is provided, its default value.
|
||
|
||
- `root: string`
|
||
|
||
Absolute path to the project's [`root`](/config/#root).
|
||
|
||
- `testFileDirectory: string`
|
||
|
||
Path to the test file, relative to the project's [`root`](/config/#root).
|
||
|
||
- `testFileName: string`
|
||
|
||
The test's filename.
|
||
|
||
- `testName: string`
|
||
|
||
The [`test`](/api/#test)'s name, including parent
|
||
[`describe`](/api/#describe), sanitized.
|
||
|
||
- `attachmentsDir: string`
|
||
|
||
The value provided to [`attachmentsDir`](/config/#attachmentsdir), if none is
|
||
provided, its default value.
|
||
|
||
For example, to group screenshots by browser:
|
||
|
||
```ts
|
||
resolveScreenshotPath: ({ arg, browserName, ext, root, testFileName }) =>
|
||
`${root}/screenshots/${browserName}/${testFileName}/${arg}${ext}`
|
||
```
|
||
|
||
#### browser.expect.toMatchScreenshot.resolveDiffPath
|
||
|
||
- **Type:** `(data: PathResolveData) => string`
|
||
- **Default output:** `` `${root}/${attachmentsDir}/${testFileDirectory}/${testFileName}/${arg}-${browserName}-${platform}${ext}` ``
|
||
|
||
A function to customize where diff images are stored when screenshot comparisons
|
||
fail. Receives the same data object as
|
||
[`resolveScreenshotPath`](#browser-expect-tomatchscreenshot-resolvescreenshotpath).
|
||
|
||
For example, to store diffs in a subdirectory of attachments:
|
||
|
||
```ts
|
||
resolveDiffPath: ({ arg, attachmentsDir, browserName, ext, root, testFileName }) =>
|
||
`${root}/${attachmentsDir}/screenshot-diffs/${testFileName}/${arg}-${browserName}${ext}`
|
||
```
|
||
|
||
#### browser.expect.toMatchScreenshot.comparators
|
||
|
||
- **Type:** `Record<string, Comparator>`
|
||
|
||
Register custom screenshot comparison algorithms, like [SSIM](https://en.wikipedia.org/wiki/Structural_similarity_index_measure) or other perceptual similarity metrics.
|
||
|
||
To create a custom comparator, you need to register it in your config. If using TypeScript, declare its options in the `ScreenshotComparatorRegistry` interface.
|
||
|
||
```ts
|
||
import { defineConfig } from 'vitest/config'
|
||
|
||
// 1. Declare the comparator's options type
|
||
declare module 'vitest/browser' {
|
||
interface ScreenshotComparatorRegistry {
|
||
myCustomComparator: {
|
||
sensitivity?: number
|
||
ignoreColors?: boolean
|
||
}
|
||
}
|
||
}
|
||
|
||
// 2. Implement the comparator
|
||
export default defineConfig({
|
||
test: {
|
||
browser: {
|
||
expect: {
|
||
toMatchScreenshot: {
|
||
comparators: {
|
||
myCustomComparator: async (
|
||
reference,
|
||
actual,
|
||
{
|
||
createDiff, // always provided by Vitest
|
||
sensitivity = 0.01,
|
||
ignoreColors = false,
|
||
}
|
||
) => {
|
||
// ...algorithm implementation
|
||
return { pass, diff, message }
|
||
},
|
||
},
|
||
},
|
||
},
|
||
},
|
||
},
|
||
})
|
||
```
|
||
|
||
Then use it in your tests:
|
||
|
||
```ts
|
||
await expect(locator).toMatchScreenshot({
|
||
comparatorName: 'myCustomComparator',
|
||
comparatorOptions: {
|
||
sensitivity: 0.08,
|
||
ignoreColors: true,
|
||
},
|
||
})
|
||
```
|
||
|
||
**Comparator Function Signature:**
|
||
|
||
```ts
|
||
type Comparator<Options> = (
|
||
reference: {
|
||
metadata: { height: number; width: number }
|
||
data: TypedArray
|
||
},
|
||
actual: {
|
||
metadata: { height: number; width: number }
|
||
data: TypedArray
|
||
},
|
||
options: {
|
||
createDiff: boolean
|
||
} & Options
|
||
) => Promise<{
|
||
pass: boolean
|
||
diff: TypedArray | null
|
||
message: string | null
|
||
}> | {
|
||
pass: boolean
|
||
diff: TypedArray | null
|
||
message: string | null
|
||
}
|
||
```
|
||
|
||
The `reference` and `actual` images are decoded using the appropriate codec (currently only PNG). The `data` property is a flat `TypedArray` (`Buffer`, `Uint8Array`, or `Uint8ClampedArray`) containing pixel data in RGBA format:
|
||
|
||
- **4 bytes per pixel**: red, green, blue, alpha (from `0` to `255` each)
|
||
- **Row-major order**: pixels are stored left-to-right, top-to-bottom
|
||
- **Total length**: `width × height × 4` bytes
|
||
- **Alpha channel**: always present. Images without transparency have alpha values set to `255` (fully opaque)
|
||
|
||
::: tip Performance Considerations
|
||
The `createDiff` option indicates whether a diff image is needed. During [stable screenshot detection](/guide/browser/visual-regression-testing#how-visual-tests-work), Vitest calls comparators with `createDiff: false` to avoid unnecessary work.
|
||
|
||
**Respect this flag to keep your tests fast**.
|
||
:::
|
||
|
||
::: warning Handle Missing Options
|
||
The `options` parameter in `toMatchScreenshot()` is optional, so users might not provide all your comparator options. Always make them optional with default values:
|
||
|
||
```ts
|
||
myCustomComparator: (
|
||
reference,
|
||
actual,
|
||
{ createDiff, threshold = 0.1, maxDiff = 100 },
|
||
) => {
|
||
// ...comparison logic
|
||
}
|
||
```
|
||
:::
|