close
Skip to content

Commit 7eddd27

Browse files
hi-ogawaclaudecodex
authored
feat(browser): support dom snapshot trace view (#10102)
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com> Co-authored-by: Codex <noreply@openai.com>
1 parent 04d37e9 commit 7eddd27

66 files changed

Lines changed: 4180 additions & 138 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

‎docs/.vitepress/config.ts‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -806,6 +806,11 @@ export default ({ mode }: { mode: string }) => {
806806
link: '/guide/browser/trace-view',
807807
docFooterText: 'Trace View | Browser Mode',
808808
},
809+
{
810+
text: 'Playwright Traces',
811+
link: '/guide/browser/playwright-traces',
812+
docFooterText: 'Playwright Traces | Browser Mode',
813+
},
809814
{
810815
text: 'ARIA Snapshots',
811816
link: '/guide/browser/aria-snapshots',

‎docs/config/browser/trace.md‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ outline: deep
1111

1212
Capture a trace of your browser test runs. You can preview traces with [Playwright Trace Viewer](https://trace.playwright.dev/).
1313

14+
See [Playwright Traces](/guide/browser/playwright-traces) for the full workflow.
15+
1416
This options supports the following values:
1517

1618
- `'on'` - capture trace for all tests. (not recommended as it's performance heavy)

‎docs/config/browser/traceview.md‎

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
---
2+
title: browser.traceView | Config
3+
outline: deep
4+
---
5+
6+
# browser.traceView <Badge type="warning" text="Experimental" /> <Version>5.0.0</Version>
7+
8+
- **Type:** `boolean | { enabled?: boolean; recordCanvas?: boolean; inlineImages?: boolean }`
9+
- **CLI:** `--browser.traceView`
10+
- **Default:** `false`
11+
12+
Enable trace-view collection for browser tests. Vitest captures DOM snapshots for browser interactions and can show them in the browser UI, Vitest UI, or HTML reporter when those surfaces are enabled — no external tools required.
13+
14+
```ts
15+
export default defineConfig({
16+
test: {
17+
browser: {
18+
traceView: true,
19+
},
20+
},
21+
})
22+
```
23+
24+
Use the object form to enable additional snapshot fidelity options:
25+
26+
```ts
27+
export default defineConfig({
28+
test: {
29+
browser: {
30+
traceView: {
31+
enabled: true,
32+
inlineImages: true,
33+
recordCanvas: true,
34+
},
35+
},
36+
},
37+
})
38+
```
39+
40+
| Option | Default | Description |
41+
| --- | --- | --- |
42+
| `enabled` | `false` | Enables Vitest trace-view artifact collection. |
43+
| `inlineImages` | `false` | Inlines loaded `<img>` pixels into snapshots for more portable replay, useful in the HTML reporter. |
44+
| `recordCanvas` | `false` | Captures canvas pixels in snapshots. |
45+
46+
## browser.traceView.enabled {#traceview-enabled}
47+
48+
- **Type:** `boolean`
49+
- **Default:** `false`
50+
- **CLI:** `--browser.traceView.enabled`
51+
52+
Enables Vitest trace-view artifact collection.
53+
54+
## browser.traceView.inlineImages {#traceview-inlineimages}
55+
56+
- **Type:** `boolean`
57+
- **Default:** `false`
58+
- **CLI:** `--browser.traceView.inlineImages`
59+
60+
Inlines loaded `<img>` pixels into snapshots for more portable replay, useful in the HTML reporter.
61+
62+
## browser.traceView.recordCanvas {#traceview-recordcanvas}
63+
64+
- **Type:** `boolean`
65+
- **Default:** `false`
66+
- **CLI:** `--browser.traceView.recordCanvas`
67+
68+
Captures canvas pixels in snapshots. This enables a weaker replay iframe sandbox because rrweb needs scripts to redraw canvas data.
69+
70+
See [Trace View](/guide/browser/trace-view) for full documentation.

‎docs/guide/browser/index.md‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -330,6 +330,8 @@ Since Vitest 3.2, if you don't have the `browser` option in your config but spec
330330

331331
By default, Vitest will automatically open the browser UI for development. Your tests will run inside an iframe in the center. You can configure the viewport by selecting the preferred dimensions, calling `page.viewport` inside the test, or setting default values in [the config](/config/browser/viewport).
332332

333+
For an alternative debugging model that captures DOM snapshots for every test instead of showing a live iframe, see [Trace View](/guide/browser/trace-view).
334+
333335
## Headless
334336

335337
Headless mode is another option available in the browser mode. In headless mode, the browser runs in the background without a user interface, which makes it useful for running automated tests. The headless option in Vitest can be set to a boolean value to enable or disable headless mode.
Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
# Playwright Traces
2+
3+
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`](/config/browser/trace) option in the `test.browser` configuration.
4+
5+
::: warning
6+
Generating trace files is only available when using the [Playwright provider](/config/browser/playwright).
7+
:::
8+
9+
::: code-group
10+
```ts [vitest.config.js]
11+
import { defineConfig } from 'vitest/config'
12+
import { playwright } from '@vitest/browser-playwright'
13+
14+
export default defineConfig({
15+
test: {
16+
browser: {
17+
provider: playwright(),
18+
trace: 'on',
19+
},
20+
},
21+
})
22+
```
23+
```bash [CLI]
24+
vitest --browser.trace=on
25+
```
26+
:::
27+
28+
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`](/api/test#repeats) count and [`retry`](/api/test#retry) count:
29+
30+
```
31+
chromium-my-test-0-0.trace.zip
32+
^^^^^^^^ project name
33+
^^^^^^ test name
34+
^ repeat count
35+
^ retry count
36+
```
37+
38+
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.
39+
40+
```ts [vitest.config.js]
41+
import { defineConfig } from 'vitest/config'
42+
import { playwright } from '@vitest/browser-playwright'
43+
44+
export default defineConfig({
45+
test: {
46+
browser: {
47+
provider: playwright(),
48+
trace: {
49+
mode: 'on',
50+
// the path is relative to the root of the project
51+
tracesDir: './playwright-traces',
52+
},
53+
},
54+
},
55+
})
56+
```
57+
58+
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.
59+
60+
## Trace markers
61+
62+
You can add explicit named markers to make the trace timeline easier to read:
63+
64+
```ts
65+
import { page } from 'vitest/browser'
66+
67+
document.body.innerHTML = `
68+
<button type="button">Sign in</button>
69+
`
70+
71+
await page.getByRole('button', { name: 'Sign in' }).mark('sign in button rendered')
72+
```
73+
74+
Both `page.mark(name)` and `locator.mark(name)` are available.
75+
76+
You can also group multiple operations under one marker with `page.mark(name, callback)`:
77+
78+
```ts
79+
await page.mark('sign in flow', async () => {
80+
await page.getByRole('textbox', { name: 'Email' }).fill('john@example.com')
81+
await page.getByRole('textbox', { name: 'Password' }).fill('secret')
82+
await page.getByRole('button', { name: 'Sign in' }).click()
83+
})
84+
```
85+
86+
You can also wrap reusable helpers with [`vi.defineHelper()`](/api/vi#vi-defineHelper) so trace entries point to where the helper is called, not its internals:
87+
88+
```ts
89+
import { vi } from 'vitest'
90+
import { page } from 'vitest/browser'
91+
92+
const myRender = vi.defineHelper(async (content: string) => {
93+
document.body.innerHTML = content
94+
await page.elementLocator(document.body).mark('render helper')
95+
})
96+
97+
test('renders content', async () => {
98+
await myRender('<button>Hello</button>') // trace points to this line
99+
})
100+
```
101+
102+
## Preview
103+
104+
To open the trace file, you can use the Playwright Trace Viewer. Run the following command in your terminal:
105+
106+
```bash
107+
npx playwright show-trace "path-to-trace-file"
108+
```
109+
110+
This will start the Trace Viewer and load the specified trace file.
111+
112+
Alternatively, you can open the Trace Viewer in your browser at https://trace.playwright.dev and upload the trace file there.
113+
114+
<img alt="Trace Viewer showing the trace timeline and rendered component" img-light src="/trace-viewer-light.png">
115+
<img alt="Trace Viewer showing the trace timeline and rendered component" img-dark src="/trace-viewer-dark.png">
116+
117+
## Source Location
118+
119+
When you open a trace, you'll notice that Vitest groups browser interactions and links them back to the exact line in your test that triggered them. This happens automatically for:
120+
121+
- `expect.element(...)` assertions
122+
- Interactive actions like `click`, `fill`, `type`, `hover`, `selectOptions`, `upload`, `dragAndDrop`, `tab`, `keyboard`, `wheel`, and screenshots
123+
124+
Under the hood, Playwright still records its own low-level action events as usual. Vitest wraps them with source-location groups so you can jump straight from the trace timeline to the relevant line in your test.
125+
126+
For anything not covered automatically, you can use `page.mark()` or `locator.mark()` to add your own trace groups — see [Trace markers](#trace-markers) above.

0 commit comments

Comments
 (0)