···2727 /**
2828 * Called before running a single test. Doesn't have "result" yet.
2929 */
3030- onBeforeRunTask?: (test: TaskPopulated) => unknown
3030+ onBeforeRunTask?: (test: Test) => unknown
3131 /**
3232 * Called before actually running the test function. Already has "result" with "state" and "startTime".
3333 */
3434- onBeforeTryTask?: (test: TaskPopulated, options: { retry: number; repeats: number }) => unknown
3434+ onBeforeTryTask?: (test: Test, options: { retry: number; repeats: number }) => unknown
3535 /**
3636 * Called after result and state are set.
3737 */
3838- onAfterRunTask?: (test: TaskPopulated) => unknown
3838+ onAfterRunTask?: (test: Test) => unknown
3939 /**
4040 * Called right after running the test function. Doesn't have new state yet. Will not be called, if the test function throws.
4141 */
4242- onAfterTryTask?: (test: TaskPopulated, options: { retry: number; repeats: number }) => unknown
4242+ onAfterTryTask?: (test: Test, options: { retry: number; repeats: number }) => unknown
4343+ /**
4444+ * Called after the retry resolution happend. Unlike `onAfterTryTask`, the test now has a new state.
4545+ * All `after` hooks were also called by this point.
4646+ */
4747+ onAfterRetryTask?: (test: Test, options: { retry: number; repeats: number }) => unknown
43484449 /**
4550 * Called before running a single suite. Doesn't have "result" yet.
+1-1
docs/config/index.md
···2439243924402440Always print console traces when calling any `console` method. This is useful for debugging.
2441244124422442-### attachmentsDir <Version>3.2.0</Version>
24422442+### attachmentsDir <Version>3.2.0</Version> {#attachmentsdir}
2443244324442444- **Type:** `string`
24452445- **Default:** `'.vitest-attachments'`
+7
docs/guide/cli-generated.md
···376376377377Control if Vitest catches uncaught exceptions so they can be reported (default: `true`)
378378379379+### browser.trace
380380+381381+- **CLI:** `--browser.trace <mode>`
382382+- **Config:** [browser.trace](/guide/browser/config#browser-trace)
383383+384384+Enable trace view mode. Supported: "on", "off", "on-first-retry", "on-all-retries", "retain-on-failure".
385385+379386### pool
380387381388- **CLI:** `--pool <pool>`
+47-3
docs/guide/browser/config.md
···128128129129Configure 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.
130130131131-## browser.provider <Badge type="danger">advanced</Badge> {#browser-provider}
131131+## browser.provider {#browser-provider}
132132133133- **Type:** `BrowserProviderOption`
134134- **Default:** `'preview'`
···154154155155To configure how provider initializes the browser, you can pass down options to the factory function:
156156157157-```ts{7-15,22-27}
157157+```ts{7-13,20-26}
158158import { playwright } from '@vitest/browser/providers/playwright'
159159160160export default defineConfig({
···188188})
189189```
190190191191-### Custom Provider
191191+### Custom Provider <Badge type="danger">advanced</Badge>
192192193193::: danger ADVANCED API
194194The 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.
···305305306306::: info
307307This 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.
308308+:::
309309+310310+## browser.trace
311311+312312+- **Type:** `'on' | 'off' | 'on-first-retry' | 'on-all-retries' | 'retain-on-failure' | object`
313313+- **CLI:** `--browser.trace=on`, `--browser.trace=retain-on-failure`
314314+- **Default:** `'off'`
315315+316316+Capture a trace of your browser test runs. You can preview traces with [Playwright Trace Viewer](https://trace.playwright.dev/).
317317+318318+This options supports the following values:
319319+320320+- `'on'` - capture trace for all tests. (not recommended as it's performance heavy)
321321+- `'off'` - do not capture traces.
322322+- `'on-first-retry'` - capture trace only when retrying the test for the first time.
323323+- `'on-all-retries'` - capture trace on every retry of the test.
324324+- `'retain-on-failure'` - capture trace only for tests that fail. This will automatically delete traces for tests that pass.
325325+- `object` - an object with the following shape:
326326+327327+```ts
328328+interface TraceOptions {
329329+ mode: 'on' | 'off' | 'on-first-retry' | 'on-all-retries' | 'retain-on-failure'
330330+ /**
331331+ * The directory where all traces will be stored. By default, Vitest
332332+ * stores all traces in `__traces__` folder close to the test file.
333333+ */
334334+ tracesDir?: string
335335+ /**
336336+ * Whether to capture screenshots during tracing. Screenshots are used to build a timeline preview.
337337+ * @default true
338338+ */
339339+ screenshots?: boolean
340340+ /**
341341+ * If this option is true tracing will
342342+ * - capture DOM snapshot on every action
343343+ * - record network activity
344344+ * @default true
345345+ */
346346+ snapshots?: boolean
347347+}
348348+```
349349+350350+::: danger WARNING
351351+This option is supported only by the [**playwright**](/guide/browser/playwright) provider.
308352:::
309353310354## browser.trackUnhandledErrors
+1-1
docs/guide/browser/playwright.md
···18181919Vitest opens a single page to run all tests in the same file. You can configure the `launch`, `connect` and `context` when calling `playwright` at the top level or inside instances:
20202121-```ts{7-15,22-27} [vitest.config.js]
2121+```ts{7-14,21-26} [vitest.config.js]
2222import { playwright } from '@vitest/browser/providers/playwright'
2323import { defineConfig } from 'vitest/config'
2424
+74
docs/guide/browser/trace-viewer.md
···11+# Trace Viewer
22+33+Vitest Browser Mode supports generating Playwright's [trace files](https://playwright.dev/docs/trace-viewer#viewing-remote-traces). To enable tracing, you need to set the [`trace`](/guide/browser/config#browser-trace) option in the `test.browser` configuration.
44+55+::: warning
66+Generating trace files is only available when using the [Playwright provider](/guide/browser/playwright).
77+:::
88+99+::: code-group
1010+```ts [vitest.config.js]
1111+import { defineConfig } from 'vitest/config'
1212+import { playwright } from '@vitest/browser/providers/playwright'
1313+1414+export default defineConfig({
1515+ test: {
1616+ browser: {
1717+ provider: playwright(),
1818+ trace: 'on',
1919+ },
2020+ },
2121+})
2222+```
2323+```bash [CLI]
2424+vitest --browser.trace=on
2525+```
2626+:::
2727+2828+By default, Vitest will generate a trace file for each test. You can also configure it to only generate traces on test failures by setting `trace` to `'on-first-retry'`, `'on-all-retries'` or `'retain-on-failure'`. The files will be saved in `__traces__` folder next to your test files. The name of the trace includes the project name, the test name, the [`repeats` count and `retry` count](/api/#test-api-reference):
2929+3030+```
3131+chromium-my-test-0-0.trace.zip
3232+^^^^^^^^ project name
3333+ ^^^^^^ test name
3434+ ^ repeat count
3535+ ^ retry count
3636+```
3737+3838+To change the output directory, you can set the `tracesDir` option in the `test.browser.trace` configuration. This way all traces will be stored in the same directory, grouped by the test file.
3939+4040+```ts [vitest.config.js]
4141+import { defineConfig } from 'vitest/config'
4242+import { playwright } from '@vitest/browser/providers/playwright'
4343+4444+export default defineConfig({
4545+ test: {
4646+ browser: {
4747+ provider: playwright(),
4848+ trace: {
4949+ mode: 'on',
5050+ // the path is relative to the root of the project
5151+ tracesDir: './playwright-traces',
5252+ },
5353+ },
5454+ },
5555+})
5656+```
5757+5858+The traces are available in reporters as [annotations](/guide/test-annotations). For example, in the HTML reporter, you can find the link to the trace file in the test details.
5959+6060+## Preview
6161+6262+To open the trace file, you can use the Playwright Trace Viewer. Run the following command in your terminal:
6363+6464+```bash
6565+npx playwright show-trace "path-to-trace-file"
6666+```
6767+6868+This will start the Trace Viewer and load the specified trace file.
6969+7070+Alternatively, you can open the Trace Viewer in your browser at https://trace.playwright.dev and upload the trace file there.
7171+7272+## Limitations
7373+7474+At the moment, Vitest cannot populate the "Sources" tab in the Trace Viewer. This means that while you can see the actions and screenshots captured during the test, you won't be able to view the source code of your tests directly within the Trace Viewer. You will need to refer back to your code editor to see the test implementation.
···106106 test: Test,
107107 options: { retry: number; repeats: number }
108108 ) => unknown
109109+ /**
110110+ * Called after the retry resolution happend. Unlike `onAfterTryTask`, the test now has a new state.
111111+ * All `after` hooks were also called by this point.
112112+ */
113113+ onAfterRetryTask?: (
114114+ test: Test,
115115+ options: { retry: number; repeats: number }
116116+ ) => unknown
109117110118 /**
111119 * Called before running a single suite. Doesn't have "result" yet.
···11-import type { File, Task } from '@vitest/runner'
11+import type { File, Task, TestAnnotation } from '@vitest/runner'
22import type { SerializedError } from '@vitest/utils'
33import type { TestError, UserConsoleLog } from '../../types/general'
44import type { Vitest } from '../core'
···275275276276 const PADDING = ' '.repeat(padding)
277277278278- annotations.forEach(({ location, type, message }) => {
278278+ const groupedAnnotations: Record<string, TestAnnotation[]> = {}
279279+280280+ annotations.forEach((annotation) => {
281281+ const { location, type } = annotation
282282+ let group: string
279283 if (location) {
280284 const file = relative(test.project.config.root, location.file)
281281- this[console](`${PADDING}${c.blue(F_POINTER)} ${c.gray(`${file}:${location.line}:${location.column}`)} ${c.bold(type)}`)
285285+ group = `${c.gray(`${file}:${location.line}:${location.column}`)} ${c.bold(type)}`
282286 }
283287 else {
284284- this[console](`${PADDING}${c.blue(F_POINTER)} ${c.bold(type)}`)
288288+ group = c.bold(type)
285289 }
286286- this[console](`${PADDING} ${c.blue(F_DOWN_RIGHT)} ${message}`)
290290+291291+ groupedAnnotations[group] ??= []
292292+ groupedAnnotations[group].push(annotation)
287293 })
294294+295295+ for (const group in groupedAnnotations) {
296296+ this[console](`${PADDING}${c.blue(F_POINTER)} ${group}`)
297297+ groupedAnnotations[group].forEach(({ message }) => {
298298+ this[console](`${PADDING} ${c.blue(F_DOWN_RIGHT)} ${message}`)
299299+ })
300300+ }
288301 }
289302290303 protected getEntityPrefix(entity: TestCase | TestModule | TestSuite): string {
+36-1
packages/vitest/src/node/types/browser.ts
···33import type { Awaitable, ParsedStack, TestError } from '@vitest/utils'
44import type { StackTraceParserOptions } from '@vitest/utils/source-map'
55import type { ViteDevServer } from 'vite'
66+import type { BrowserTraceViewMode } from '../../runtime/config'
67import type { BrowserTesterOptions } from '../../types/browser'
78import type { TestProject } from '../project'
89import type { ApiConfig, ProjectConfig } from './config'
···169170 }
170171171172 /**
173173+ * Generate traces that can be viewed on https://trace.playwright.dev/
174174+ *
175175+ * This option is supported only by **playwright** provider.
176176+ */
177177+ trace?: BrowserTraceViewMode | {
178178+ mode: BrowserTraceViewMode
179179+ /**
180180+ * The directory where all traces will be stored. By default, Vitest
181181+ * stores all traces in `__traces__` folder close to the test file.
182182+ */
183183+ tracesDir?: string
184184+ /**
185185+ * Whether to capture screenshots during tracing. Screenshots are used to build a timeline preview.
186186+ * @default true
187187+ */
188188+ screenshots?: boolean
189189+ /**
190190+ * If this option is true tracing will
191191+ * - capture DOM snapshot on every action
192192+ * - record network activity
193193+ * @default true
194194+ */
195195+ snapshots?: boolean
196196+ }
197197+198198+ /**
172199 * Directory where screenshots will be saved when page.screenshot() is called
173200 * If not set, all screenshots are saved to __screenshots__ directory in the same folder as the test file.
174201 * If this is set, it will be resolved relative to the project root.
···269296 parseErrorStacktrace: (error: TestError, options?: StackTraceParserOptions) => ParsedStack[]
270297}
271298272272-export interface BrowserCommand<Payload extends unknown[]> {
299299+export interface BrowserCommand<Payload extends unknown[] = []> {
273300 (context: BrowserCommandContext, ...payload: Payload): Awaitable<any>
274301}
275302···317344 screenshotFailures: boolean
318345 locators: {
319346 testIdAttribute: string
347347+ }
348348+ trace: {
349349+ mode: BrowserTraceViewMode
350350+ tracesDir?: string
351351+ screenshots?: boolean
352352+ snapshots?: boolean
353353+ // TODO: map locations to test ones
354354+ // sources?: boolean
320355 }
321356}
322357