Skip to content

feat(browser): support dom snapshot trace view#10102

Open
hi-ogawa wants to merge 152 commits intovitest-dev:mainfrom
hi-ogawa:wip-builtin-trace-system
Open

feat(browser): support dom snapshot trace view#10102
hi-ogawa wants to merge 152 commits intovitest-dev:mainfrom
hi-ogawa:wip-builtin-trace-system

Conversation

@hi-ogawa
Copy link
Copy Markdown
Collaborator

@hi-ogawa hi-ogawa commented Apr 8, 2026

Description

Please read docs for overview https://deploy-preview-10102--vitest-dev.netlify.app/guide/browser/trace-view

There are quite a few TODOs scattered in this PR. I made a tracking issue intended as follow-up but please feel free to bring it up as this PR's review if anything worth addressing or discussing early:

Demo

# watch ui
# - trace viewer shows up next to live view
pnpm -C examples/lit test --browser.traceView

# watch ui
# - this is not orchestrator UI, but "pure" UI mode with trace viewer
# - The orchestrator/tester runs in a separate headless browser
pnpm -C examples/lit test --browser.traceView --browser.headless --ui

# watch ui
# - trace viewer UI same as above
# - headed "live view" is in a separate headed browser driver window
pnpm -C examples/lit test --browser.traceView --browser.headless=false --browser.ui=false --ui

# html reporter
# - static UI mode but same content, so works almost identically with watch mode.
pnpm -C examples/lit test --browser.traceView --browser.headless --reporter=html
pnpm dlx serve examples/lit/html/
Screenshot
VITE_FAIL_TEST=true pnpm -C examples/lit test --browser.traceView --browser.headless --ui
image
VITE_FAIL_TEST=true pnpm -C examples/lit test --browser.traceView
image

TODO

  • snapshot + view prototype
    • snapshot + render
    • selector highlight
    • source location
    • external resources (css, images, font, etc.) (this is actually complex. documented as limitation for now and will create a follow-up issue)
    • window/viewport size, overflow scroll
  • design viewer
    • step list
    • snapshot view
    • link to code view
    • link from code view (later. agents can one-shot it but I'm not ready to review)
    • open trace from artifact
  • option to differentiate playwright trace and builtin trace.
    • test.browser.traceView: true
    • the idea is to provide new experience around dome snapshot viewer as first-class citizen
    • imply --browser.headless --ui on watch
    • imply --browser.headless --reporter html on non watch
  • test
    • provideres
      • playwright
      • webdriverio (highlight broken)
      • preview (no idea)
    • e2e: test/ui (verifies trace view is actually visible)
      • pnpm -C test/ui test trace.spec.ts
    • e2e: test/browser (verifies trace artifacts recording)
    • unit: packages/ui (component level interaction)
    • test on real projects in the ecosystem https://gist.github.com/hi-ogawa/2f1d9686457186cc845f4b9194dd4a5f
      • vueuse: pnpm test:chromium --browser.traceView --ui
      • vuetify: pnpm -C packages/vuetify/ test:browser --browser.traceView --ui --watch --standalone
  • docs
    • basic
    • more options
    • known limitations
  • enhance trace
    • semantic color, status
    • timestamp
    • duration
    • rename __vitest_click -> vitest:click
  • review left out TODOs
  • review slop
  • review rrweb
  • design efficient trace format and persistence (later)

Please don't delete this checklist! Before submitting the PR, please make sure you do the following:

  • It's really useful if your PR references an issue where it is discussed ahead of time. If the feature is substantial or introduces breaking changes without a discussion, PR might be closed.
  • Ideally, include a test that fails without this PR but passes with it.
  • Please, don't make changes to pnpm-lock.yaml unless you introduce a new test example.
  • Please check Allow edits by maintainers to make review process faster. Note that this option is not available for repositories that are owned by Github organizations.

Tests

  • Run the tests with pnpm test:ci.

Documentation

  • If you introduce new functionality, document it. You can run documentation with pnpm run docs command.

Changesets

  • Changes in changelog are generated from PR name. Please, make sure that it explains your changes in an understandable manner. Please, prefix changeset messages with feat:, fix:, perf:, docs:, or chore:.

@netlify
Copy link
Copy Markdown

netlify Bot commented Apr 8, 2026

Deploy Preview for vitest-dev ready!

Built without sensitive environment variables

Name Link
🔨 Latest commit 0c11f7f
🔍 Latest deploy log https://app.netlify.com/projects/vitest-dev/deploys/69e83dcac8d8a800080f84f2
😎 Deploy Preview https://deploy-preview-10102--vitest-dev.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

@hi-ogawa hi-ogawa changed the title feat(browser): support trace viewer with dom snaphost feat(browser): support trace viewer with dom snapshot Apr 9, 2026
hi-ogawa and others added 9 commits April 9, 2026 15:54
… safe)

- store { serialized, nodeId } as snapshot payload in BrowserTraceEntry
- takeSnapshot() passes explicit Mirror to snapshot(), resolves ivya selector → nodeId
- TraceView.vue uses mirror.getNode(nodeId) after rebuild() instead of querySelector
- removes CSS selector approach which breaks for shadow DOM elements
- drops __vitest_css_from_element__ global (no longer needed)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- use getBoundingClientRect + position:fixed overlay div instead of inline styles
- snapshot DOM is untouched; overlay is purely visual
- use requestAnimationFrame to ensure layout before reading rect
- credit Playwright's highlight.ts as reference for the technique
- mirror.getNode(selectorId) for shadow DOM-safe element lookup

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- add __vitest_recordBrowserTrace server command (mirrors annotateTraces pattern)
  - resolves stack → location via parseStacktrace in one batch server-side
  - calls _testRun.recordArtifact directly, no browser-side recordArtifact
- BrowserTraceEntry gains location?: { file, line, column }
- TraceView shows clickable source location per step via openLocation composable

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@hi-ogawa hi-ogawa changed the title feat(browser): support trace viewer with dom snapshot feat(browser): support dom snapshot trace view Apr 9, 2026
hi-ogawa and others added 3 commits April 10, 2026 09:46
Move browser traces out of the report card into the top panel layout and allow the trace viewer to open without browser orchestrator state.

Keep BrowserIframe visible during browser orchestration by splitting the top pane when a trace is active.

Co-authored-by: Codex <noreply@openai.com>
Wrap the trace viewer in a dedicated pane with a header and close action, and rename the component to TraceViewPane for consistency with the split layout.

Co-authored-by: Codex <noreply@openai.com>
@hi-ogawa hi-ogawa marked this pull request as ready for review April 17, 2026 08:49
Comment thread docs/.vitepress/config.ts
text: 'Playwright Traces',
link: '/guide/browser/playwright-traces',
docFooterText: 'Playwright Traces | Browser Mode',
},
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

New trace view took over the page, so I rename the playwright trace. Not sure if we should keep the sidebar though.

Comment thread packages/ui/client/composables/trace-view.ts
Comment thread patches/rrweb-snapshot.patch
@hi-ogawa hi-ogawa moved this from P2 - 2 to Approved in Team Board Apr 18, 2026
@hi-ogawa hi-ogawa removed the p2-to-be-discussed Enhancement under consideration (priority) label Apr 18, 2026
Comment thread packages/browser/src/client/tester/tester-utils.ts
Comment thread packages/browser/src/client/tester/runner.ts Outdated
@hi-ogawa hi-ogawa added this to the 5.0.0 milestone Apr 22, 2026
pseudoClassIds: Record<PsudoClassName, number[]>
}

const PSUDO_CLASS_NAMES = [':hover', ':focus', ':focus-within'] as const
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Any reason why :active is not here? User might want to see what the snapshot looked like when button was pressed (and some annoying box shadow was rendered 🙃). Atm with Vitest it's really difficult to make button pressed for specific time, but that might change in #8190.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

Status: Approved

Development

Successfully merging this pull request may close these issues.

Built-in trace viewer with DOM snapshots for browser mode

3 participants