Skip to content

Addon-vitest: Filter Storybook instrumentation from reported stack traces - #36120

Merged
JReinhold merged 1 commit into
nextfrom
ghengeveld/filter-instrumentation-stack-frames
Sep 1, 2026
Merged

JReinhold merged 1 commit into
nextfrom
ghengeveld/filter-instrumentation-stack-frames

Conversation

@ghengeveld

@ghengeveld ghengeveld commented Sep 1, 2026 •

Copy link
Copy Markdown
Member

What I did

A failing expect in a play function reported seven frames of Storybook plumbing above the story that triggered it, which also made Vitest print its code excerpt from inside Instrumenter.invoke instead of from the story file:

 ❯ Proxy.expectWrapper node_modules/storybook/dist/test/index.js:13691:16
 ❯ Proxy.<anonymous> node_modules/storybook/dist/test/index.js:13211:17
 ❯ Proxy.methodWrapper node_modules/storybook/dist/test/index.js:7705:24
 ❯ Instrumenter.invoke node_modules/storybook/dist/instrumenter/index.js:322:22
 ❯ Instrumenter.intercept node_modules/storybook/dist/instrumenter/index.js:243:139
 ❯ Instrumenter.track node_modules/storybook/dist/instrumenter/index.js:238:378
 ❯ Proxy.toBeInTheDocument node_modules/storybook/dist/instrumenter/index.js:224:263
 ❯ toBeInTheDocument src/stories/Page.stories.ts:30:60

Instrumenting expect, userEvent and Testing Library is what lets the Interactions panel replay a play function step by step, so those wrapper frames are unavoidable; they just should not be reported. The Interactions panel was already unaffected because it renders matcher diffs rather than stacks.

Terminal, IDE and CI output. Vitest parses error.stack once per failure, source-maps each frame, drops frames matching its ignore list and caches the result on error.stacks, which every reporter then reads. Storybook's bundles were not in that ignore list. The Vitest project config the storybookTest plugin returns now registers a test.onStackTrace hook that filters them, chaining to any hook the user already configured. After this change the first frame is the story, so the code excerpt points there too.

MCP and tools CLI output. That path is separate: it read the raw error.stack string, which in browser mode is a list of http://localhost:PORT/.../sb-vitest/deps/chunk-*.js URLs. TestManager now builds the component test status description from error.stacks, so consumers get source-mapped file paths with the instrumentation already filtered. Since that switch takes the message from error.message, which carries the ANSI "Click to debug" banner that setup-file.ts prepends, the banner is stripped there.

The frame predicate matches Storybook's bundles in the shapes a frame can take: the published storybook/dist and @storybook/*/dist layouts after source maps are applied, and the pre-bundled deps/storybook_* files Vite serves when no source map is available.

Checklist for Contributors

Testing

The changes in this PR are covered in the following automated tests:

  • stories
  • unit tests
  • integration tests
  • end-to-end tests

Manual testing

Caution

This section is mandatory for all contributions. If you believe no manual test is necessary, please state so explicitly. Thanks!

  1. Set up a sandbox with the Vitest addon: yarn task sandbox --template react-vite/default-ts --start-from auto
  2. In src/stories/Page.stories.ts, make the LoggedIn story fail by changing await expect(loginButton).not.toBeInTheDocument(); to await expect(loginButton).toBeInTheDocument();
  3. Run npx vitest run
  4. Expected: the failure lists ❯ toBeInTheDocument src/stories/Page.stories.ts:30:60 as its first frame and prints the code excerpt from that story file. No frames from node_modules/storybook/dist/test/index.js, node_modules/storybook/dist/instrumenter/index.js or @storybook/addon-vitest/dist/... should appear.
  5. Replace the assertion with a plain runtime error (for example throw new Error('boom') in the play function, or a component that throws during render) and confirm the reported stack is still useful and points at project code.
  6. Add onStackTrace: (error, frame) => { console.log('user hook', frame.file); return true; } to test in the Vitest config, run npx vitest run again, and confirm the hook still logs, i.e. a user-configured hook is not shadowed.
  7. Agent-facing output: with Storybook running (yarn storybook), run npx storybook tools test run --stories '[{\"storyId\":\"example-page--logged-in\"}]'. The failing story section should show the assertion message followed by source-mapped file paths, not http://localhost:PORT/... URLs, and no instrumentation frames.
  8. Storybook UI: open the Component tests panel for the failing story and confirm the failure text still reads sensibly and does not include a raw "Click to debug the error directly in Storybook" line.

Most likely to regress: the frame matching is path-based, so Windows paths deserve a look (covered by a unit test, but worth confirming on a real Windows run); the status description format changed, which is what both the Storybook UI and the agent tooling display.

Documentation

  • Add or update documentation reflecting your changes
  • If you are deprecating/removing a feature, make sure to update
    MIGRATION.MD

Checklist for Maintainers

  • When this PR is ready for testing, make sure to add ci:normal, ci:merged or ci:daily GH label to it to run a specific set of sandboxes. The particular set of sandboxes can be found in code/lib/cli-storybook/src/sandbox-templates.ts

  • Declare whether manual QA will be needed for this PR during the next release, through qa:needed or qa:skip

  • Make sure this PR contains one of the labels below:

    Available labels
    • bug: Internal changes that fixes incorrect behavior.
    • maintenance: User-facing maintenance tasks.
    • dependencies: Upgrading (sometimes downgrading) dependencies.
    • build: Internal-facing build tooling & test updates. Will not show up in release changelog.
    • cleanup: Minor cleanup style change. Will not show up in release changelog.
    • documentation: Documentation only changes. Will not show up in release changelog.
    • feature request: Introducing a new feature.
    • BREAKING CHANGE: Changes that break compatibility in some way with current major version.
    • other: Changes that don't fit in the above categories.

🦋 Canary release

This PR does not have a canary release associated. You can request a canary release of this pull request by mentioning the @storybookjs/core team here.

core team members can create a canary release here or locally with gh workflow run --repo storybookjs/storybook publish.yml --field pr=<PR_NUMBER>

…aces

Instrumented expect/userEvent calls put a handful of Storybook wrapper frames
between the failing assertion and the story, which Vitest then reports and uses
for its code excerpt. Register those bundles with Vitest's onStackTrace hook so
they are dropped while parsing, and build the component test status description
from the source-mapped frames instead of the raw browser stack, so MCP and the
tools CLI report file paths rather than Vite dev-server URLs.
@ghengeveld ghengeveld added bug ci:normal Run our default set of CI jobs (choose this for most PRs). qa:needed Pull Requests that will need manual QA prior to release. labels Sep 1, 2026
@ghengeveld ghengeveld self-assigned this Sep 1, 2026
@ghengeveld
ghengeveld requested a review from JReinhold September 1, 2026 15:02
@ghengeveld
ghengeveld marked this pull request as ready for review September 1, 2026 15:04
@coderabbitai

coderabbitai Bot commented Sep 1, 2026

Copy link
Copy Markdown
Contributor

Caution

Review failed

An error occurred during the review process. Please try again later.


Comment @coderabbitai help to get the list of available commands.

@JReinhold
JReinhold merged commit b82a2c4 into next Sep 1, 2026
155 of 163 checks passed
@JReinhold
JReinhold deleted the ghengeveld/filter-instrumentation-stack-frames branch September 1, 2026 18:35
@github-actions github-actions Bot mentioned this pull request Sep 1, 2026
2 tasks done
brandhaug added a commit to brandhaug/b2b-saas-starter that referenced this pull request Sep 5, 2026
## Dependency Updates

| Package | From | To | Type |
| --- | --- | --- | --- |
| `storybook` | 10.5.10 | 10.6.0 | minor |

## Release Notes

<details>
<summary><b>storybook</b> (10.5.10 → 10.6.0)</summary>

## 10.6.0

> New skills architecture for agentic workflows

Storybook 10.6 contains hundreds of fixes and improvements:

- 💻 CLI bindings for agent tools/skills
- 🅰️ Angular-Vite MCP/skills support and improved docgen/snippets
(experimental)
- 🟢 Vue MCP/skills support and improved docgen/snippets (experimental)
- 🧩 Tanstack / NextJS-Vite framework bugfixes
- ⚡ Improved performance and reduced bundle size

<details>
<summary>List of all updates</summary>

- Addon MCP: Stop silently dropping composed refs from MCP composition -
[#36077](storybookjs/storybook#36077), thanks
@<!---->kasperpeulen!
- Addon Vitest: Pin storybook/test in optimizeDeps so its CJS-only deps
are prebundled -
[#35572](storybookjs/storybook#35572), thanks
@<!---->Nic-Polumeyv!
- Addon Vitest: Report test runs with failures as failed tool outcomes -
[#36080](storybookjs/storybook#36080), thanks
@<!---->kasperpeulen!
- Addon Vitest: Resolve story test globs against the project root -
[#36103](storybookjs/storybook#36103), thanks
@<!---->kasperpeulen!
- Addon-vitest: Filter Storybook instrumentation from reported stack
traces - [#36120](storybookjs/storybook#36120),
thanks @<!---->ghengeveld!
- Angular Vite: Resolve tsConfig against the workspace root -
[#36026](storybookjs/storybook#36026), thanks
@<!---->ndelangen!
- Angular-Vite: Run Compodoc on demand -
[#35776](storybookjs/storybook#35776), thanks
@<!---->valentinpalkovic!
- Angular: Add an in-process docgen analyzer, replacing Compodoc under
the flag -
[#35805](storybookjs/storybook#35805), thanks
@<!---->valentinpalkovic!
- Angular: Bind only what the component accepts in story snippets, and
report the rest -
[#35943](storybookjs/storybook#35943), thanks
@<!---->valentinpalkovic!
- Angular: Decide the migration\'s zone.js import from the dependency
tree - [#36008](https://github.com/story

…[full
notes](https://github.com/storybookjs/storybook/releases/tag/v10.6.0)

</details>

---
*This PR was auto-generated by
[catalog-update-action](https://github.com/brandhaug/catalog-update-action).*

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
brandhaug added a commit to brandhaug/b2b-saas-starter that referenced this pull request Sep 5, 2026
## Dependency Updates

| Package | From | To | Type |
| --- | --- | --- | --- |
| `@storybook/react-vite` | 10.5.10 | 10.6.0 | minor |

## Release Notes

<details>
<summary><b>@<!---->storybook/react-vite</b> (10.5.10 →
10.6.0)</summary>

## 10.6.0

> New skills architecture for agentic workflows

Storybook 10.6 contains hundreds of fixes and improvements:

- 💻 CLI bindings for agent tools/skills
- 🅰️ Angular-Vite MCP/skills support and improved docgen/snippets
(experimental)
- 🟢 Vue MCP/skills support and improved docgen/snippets (experimental)
- 🧩 Tanstack / NextJS-Vite framework bugfixes
- ⚡ Improved performance and reduced bundle size

<details>
<summary>List of all updates</summary>

- Addon MCP: Stop silently dropping composed refs from MCP composition -
[#36077](storybookjs/storybook#36077), thanks
@<!---->kasperpeulen!
- Addon Vitest: Pin storybook/test in optimizeDeps so its CJS-only deps
are prebundled -
[#35572](storybookjs/storybook#35572), thanks
@<!---->Nic-Polumeyv!
- Addon Vitest: Report test runs with failures as failed tool outcomes -
[#36080](storybookjs/storybook#36080), thanks
@<!---->kasperpeulen!
- Addon Vitest: Resolve story test globs against the project root -
[#36103](storybookjs/storybook#36103), thanks
@<!---->kasperpeulen!
- Addon-vitest: Filter Storybook instrumentation from reported stack
traces - [#36120](storybookjs/storybook#36120),
thanks @<!---->ghengeveld!
- Angular Vite: Resolve tsConfig against the workspace root -
[#36026](storybookjs/storybook#36026), thanks
@<!---->ndelangen!
- Angular-Vite: Run Compodoc on demand -
[#35776](storybookjs/storybook#35776), thanks
@<!---->valentinpalkovic!
- Angular: Add an in-process docgen analyzer, replacing Compodoc under
the flag -
[#35805](storybookjs/storybook#35805), thanks
@<!---->valentinpalkovic!
- Angular: Bind only what the component accepts in story snippets, and
report the rest -
[#35943](storybookjs/storybook#35943), thanks
@<!---->valentinpalkovic!
- Angular: Decide the migration\'s zone.js import from the dependency
tree - [#36008](https://github.com/story

…[full
notes](https://github.com/storybookjs/storybook/releases/tag/v10.6.0)

</details>

---
*This PR was auto-generated by
[catalog-update-action](https://github.com/brandhaug/catalog-update-action).*

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug ci:normal Run our default set of CI jobs (choose this for most PRs). qa:needed Pull Requests that will need manual QA prior to release.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants