# 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 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](/advanced/api/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 - **Type:** `boolean` - **Default:** `true` - **CLI:** `--browser.isolate`, `--browser.isolate=false` Run every test in a separate iframe. ## 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-` 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 advanced ::: 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 /** * @experimental opt-in into file parallelisation */ supportsParallelism: boolean getCommandsContext: (sessionId: string) => Record openPage: (sessionId: string, url: string) => Promise getCDPSession?: (sessionId: string) => Promise close: () => Awaitable } ``` ## 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](/guide/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` - **Default:** `{ readFile, writeFile, ... }` Custom [commands](/guide/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**](/guide/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](/guide/browser/assertion-api.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](/guide/browser/assertion-api#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`](/guide/browser/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}` ```