Skip to content

vitest-plugin-vis changelog

5.2.2

Patch Changes

  • #962 1847b46 Thanks @unional! - Point the package readmes and the review-image-snapshot-failures skill at the documentation website. Each readme now has install, minimal configuration, an example, a version compatibility table, and links to the matching website pages. The skill links the “Reviewing Failures with Agents” page on the website instead of a source file.

5.2.1

Patch Changes

5.2.0

Minor Changes

  • #920 6c2e58e Thanks @unional! - When an image snapshot mismatches, find the changed regions and write a review image.

    The failure message now lists the changed regions (Changed:) and points to a review image (Review:). The review image (<name>.review.png, next to the diff) places the baseline, result, and diff crops of each region side by side, so a person or a coding agent can see what changed without opening the full images. The regions are also written to <name>.regions.json next to the diff. The review image is skipped, and the message says why, when the image size changed, there are more than 5 regions, or the regions cover more than half of the image.

    Set reviewImage: false in vis() or toMatchImageSnapshot() to not write the review image.

    The Storybook Vis panel does not list the review image as a diff.

Patch Changes

  • #926 013d9b6 Thanks @unional! - Ship an llms.txt in each package so coding agents can find the entry points and documentation pages. It points agents to the new “Reviewing Failures with Agents” page, which tells them to open the review image of a failed image snapshot first, and shows what each view costs in tokens.

    Each package is also an agent plugin for Claude Code, Cursor, Codex and Copilot CLI. It ships the review-image-snapshot-failures skill, which tells an agent to read the error message and the review image before it opens a full image.

  • #946 65e4177 Thanks @dub578! - Decode images in toImageData with createImageBitmap and close the bitmap after reading the pixels.

    new Image() + drawImage left a full-size decode in Chromium’s image decode cache for every compared image, so renderer memory grew with each image snapshot comparison.

5.1.8

Patch Changes

5.1.7

Patch Changes

  • #889 b770cfe Thanks @unional! - Fix auto snapshots hanging until the test timeout when subject matches a hidden element.

    The subject selector was resolved with document.querySelector(), which returns the first match even when it is hidden. In Storybook, a selector such as button matched hidden buttons that Storybook adds to the document, so the screenshot waited for that element to become visible until the timeout. Auto snapshots now use the first visible match.

    If the selector matches only hidden elements, the snapshot now fails right away with a “not visible” error instead of waiting until the timeout. If it matches nothing, document.body is still used.

  • #890 affac03 Thanks @unional! - Trim leading and trailing whitespace from test and suite names when building the snapshot path (#847).

    Storybook appends two spaces to the describe title it generates for a CSF Next story that uses story.test(). Those spaces became two dashes in the snapshot folder name, so the snapshots landed under <story>--/.

    Snapshots of story.test() stories now land under <story>/. Move or regenerate the existing baselines from <story>--/ to <story>/. Snapshot paths of plain stories and regular tests do not change.

5.1.6

Patch Changes

  • #885 b674dfe Thanks @unional! - Update type-plus to 8.0.0-beta.12.

    type-plus 8.0.0-beta.12 no longer exports the distributive Pick and Omit from its root. The public types now use ObjectPlus.Pick and ObjectPlus.Omit, which behave the same.

5.1.5

Patch Changes

  • #870 5c2970c Thanks @unional! - Pin type-plus to 8.0.0-beta.10, exactly.

    Both packages already declared type-plus: ^8.0.0-beta.10 in the last published release (storybook-addon-vis@4.2.7, vitest-plugin-vis@5.1.4), so this is a range tightening, not a version move: type-plus 8’s typescript >= 5.6.0 peer already reaches consumers today, and this change does not alter what a fresh install resolves — it only forecloses later 8.0.0-beta.x prereleases plus 8.0.0 and 8.1.0.

    The version is pinned rather than caret-ranged. ^8.0.0-beta.10 resolves to >=8.0.0-beta.10 <9.0.0-0, which admits every later 8.0.0 prerelease as well as 8.0.0 and 8.1.0 — and 8 is a prerelease line where breaking changes land between betas (beta.10 to beta.11 changed Equal’s signature and removed isType.f). An exact version makes each bump a reviewable PR instead of something a lockfile refresh can do silently. Move back to a caret when 8.0.0 is stable.

    type-plus types leak into each package’s emitted declarations: storybook-addon-vis’s dist/exports/vitest-plugin.d.mts imports Omit from type-plus; vitest-plugin-vis’s dist/shared/commands.types.d.mts and dist/server/testing/stubSuite.d.mts import Pick and RecursivePartial. None of these symbols changed between 7 and 8, so no source change was needed.

5.1.4

Patch Changes

  • #861 ee4464a Thanks @unional! - Depend on type-plus ^8.0.0-beta.10 — back on the 8.x line, as a range.

    The previous release moved both packages to ^7.6.2. That was the wrong fix. These packages belong on the 8.x line; what was actually broken was that the dependency was an exact pin (8.0.0-beta.8), so it could never resolve forward and consumers were stuck on a build with a real CJS packaging defect: 8.0.0-beta.8 declares "type": "module" but ships a cjs/ build with no {"type":"commonjs"} marker, so require() of these packages failed with ReferenceError: exports is not defined in ES module scope.

    type-plus@8.0.0-beta.10 ships that cjs/package.json marker and fixes it. The dependency is now the range ^8.0.0-beta.10 rather than a pin, so later 8.x betas and stable 8.x flow in on their own instead of freezing at one build.

    The root barrel of 8.0.0-beta.10 is byte-identical to 8.0.0-beta.8’s, so there is no API change between the two. The local Merge alias in vis_server_context.types.ts stays as-is; it is version-independent.

5.1.3

Patch Changes

  • #859 62026f5 Thanks @unional! - Stop the server proxy from throwing before the vitest browser module loads.

    server’s get trap fell back to (ctx?.server as any)[prop]. The optional chain guards ctx, but the property access straight after it does not, so any read of server.<prop> before the dynamic import('vitest/browser') settled — or outside a browser run, where it never settles — threw TypeError: Cannot read properties of undefined instead of returning undefined. The fallback is now optional too.

5.1.2

Patch Changes

  • #851 5364614 Thanks @unional! - Show snapshot paths in failure messages relative to the project root (./__vis__/...) instead of absolute.

    Editors and terminals resolve the relative path just as well, and the output no longer leaks the local absolute path when a failure is pasted into a bug report. Paths outside the project root stay absolute. Filesystem operations are unaffected and still resolve to absolute paths.

  • 6697a67 Thanks @unional! - Raise dependency floors to pull in security fixes.

    glob, rimraf, pathe, dedent, is-ci, and pixelmatch move up within their existing major, which resolves the advisories reaching the runtime dependency tree through brace-expansion and tmp. No API change.

  • #858 6f65e20 Thanks @unional! - Depend on the stable type-plus line instead of an 8.x prerelease.

    Both packages carried "type-plus": "8.0.0-beta.8" as an exact pin in their runtime dependencies. type-plus@latest is deliberately 7.6.2; the 8.x line is an unfinished major parked in prerelease. The exact pin forced every consumer to install that prerelease, and consumers that also depend on something else pinning a different 8.x beta resolved two copies of type-plus. The pin now reads ^7.6.2.

    The only type this needed that 7.x does not export from its root is Merge, so Merge is now declared locally in vis_server_context.types.ts. Emitted output is otherwise byte-for-byte identical to the build under 8.0.0-beta.8: the sole difference in dist is that one alias moving from an import into the file. No API change.

5.1.1

Patch Changes

  • 581c416 Thanks @unional! - Fix aggregate errors when multiple themes are used.

5.1.0

Minor Changes

  • #723 69cde31 Thanks @unional! - Add createMissingBaseline for image matchers so a missing baseline can be written without -u / updateSnapshot: 'all', and support vis.setup({ createMissingBaseline: true }) defaults for auto snapshots (overridable per test). Document Storybook Vitest browser limitations for createMissingBaseline and the updateSnapshot workaround.

  • #723 fc139fd Thanks @unional! - Add opt-in shortenLongSnapshotPaths to vis(): when enabled, if representative absolute snapshot paths under __baselines__ (after snapshotRootDir and snapshotSubpath) would exceed Windows-safe limits (250 characters or a path segment over 255), keep subpath directories and shorten only the final component to {firstToken}-{hash12}{ext} (tersify-style prefix); legacy taskId-key.png names are unchanged. Fix getVisOption to merge __default plugin options with the active Vitest project. Storybook visProjects may set shortenLongSnapshotPaths for the Vis panel (same semantics as Vitest vis()). Export resolveSnapshotSubpathWithinLimits from vitest-plugin-vis/server-utils. vitest-plugin-vis/testing is browser-safe (fixtures only). getVisOption and stubSuite are available from vitest-plugin-vis/testing/node for Node/Vitest project tests.

5.0.0

Major Changes

  • #711 b4c34dc Thanks @unional! - Remove deprecated setup APIs and align with Vitest 4.

    • BREAKING: createVis is no longer re-exported from vitest-plugin-vis/setup. Import it from vitest-plugin-vis/setup-api instead.
    • BREAKING: Removed deprecated vis.presets, vis.beforeAll, and vis.afterEach helpers from the object returned by createVis. Use vis.setup() (and autoSnapshotMatcher where you need per-theme snapshots) instead.
    • BREAKING: Config preset none is renamed to custom.
    • BREAKING: Removed the vitest-plugin-vis/presets/enable entry point; use the manual or auto preset, or custom with your own vitest.setup.ts.
    • BREAKING: Browser helpers now rely on Vitest 4’s TestRunner.getCurrentTest / getCurrentSuite (via vitest instead of vitest/suite). Requires Vitest 4+ in browser projects.

4.2.2

Patch Changes

  • 494a8c7 Thanks @unional! - Drop an unnecessary Biome suppression from the Jest matcher module augmentation. Update Storybook-related dev dependencies for local development and remove @storybook/addon-mdx-gfm from the package Storybook config.

4.2.1

Patch Changes

  • 76faffe Thanks @unional! - fix support for multiple browser instances when test.name is not set.

4.2.0

Minor Changes

  • #577 d0c04d0 Thanks @unional! - Deprecate vis.beforeAll.setup(), vis.afterEach.matchImageSnapshot(), vis.afterEach.matchPerTheme() in vitest-plugin-vis/setup.

    There is no known use case for these methods. Reducing the API surface.

  • #672 ab4ca8a Thanks @unional! - Add projectName to the context of snapshotRootDir to allow users to customize the snapshot root directory based on the project name. This in useful when you use multiple instances in a Vitest project.

    The projectName is generated by Vitest (e.g. vpv:pw (chromium) where vpv:pw is the project name you defined and chromium is the browser name).

    export default defineConfig({
    test: {
    name: "vpv:pw",
    browser: {
    instances: [{ browser: "chromium" }],
    },
    },
    });

    If you specify the instance name, the projectName will be the instance name.

    The projectName will be HD in the following example.

    export default defineConfig({
    test: {
    name: "vpv:pw",
    browser: {
    instances: [{ browser: "chromium", name: "HD" }],
    },
    },
    });

    Also added rootDir to the context of snapshotRootDir to make the snapshot root directory more transparent.

  • #577 7ceb998 Thanks @unional! - Deprecate createVis in vitest-plugin-vis/setup. Added vitest-plugin-vis/setup-api.

  • #551 1c54a56 Thanks @unional! - Fail test when no baseline image is found. This behavior is closer to the Visual Regression Test from Vitest.

    The difference is that the baseline image is not created automatically. You need to create it manually by running the test with the updateSnapshot option set to all.

    This prevents you from accidentally committing a new snapshot or passing the tests when you running the tests for the second time.

    Closes #516

    Since this change can break existing tests (even though correctly), we will release it as a minor version.

Patch Changes

4.1.0

Minor Changes

  • #496 ea6b3b2 Thanks @unional! - Provide the autoSnapshotMatcher function to create a matcher for auto snapshot in Storybook.

4.0.0

Major Changes

Patch Changes

3.5.1

Patch Changes

  • #472 0ebfe75 Thanks @unional! - Replace starting “..” with “__” in trimCommonFolder function.

    This allows test project to reference tests in other projects within a monorepo.

3.5.0

Minor Changes

3.4.1

Patch Changes

3.4.0

Minor Changes

  • 30026e2 Thanks @unional! - Handle the case where the test config name is an object with a label. Vitest 3.2.0 starts doing this when running in workspace/project mode.

3.3.2

Patch Changes

  • cb735b9 Thanks @unional! - Revert the change of adding createVis from vitest-plugin-vis/setup to vitest-plugin-vis/client-api. createVis imports vitest, which cannot be imported in the client side.

3.3.1

Patch Changes

  • 5b25658 Thanks @unional! - Fix vis().setup({ auto: ... }) type to accept sync and async function with no return value.

3.3.0

Minor Changes

Patch Changes

  • #314 4fb0a22 Thanks @unional! - Allow getSnapshotRootDir to be called without specifying a snapshot root directory.

3.2.0

Minor Changes

3.1.0

Minor Changes

3.0.1

Patch Changes

  • 9a25501 Thanks @unional! - Fix manual preset to be the same as enable in v2. Note enable is deprecated and will be removed in v4.

3.0.0

Major Changes

Minor Changes

Patch Changes

2.4.4

Patch Changes

  • 0b83a6e - Sanitize suite ID to prevent invalid paths. (#270) Thanks @jacob-noble for the contribution 🎉

2.4.3

Patch Changes

2.4.2

Patch Changes

  • #251 349e021 Thanks @unional! - Fix handling of server options introduced by workspace support.

2.4.1

Patch Changes

  • #246 e877872 Thanks @unional! - Fix workspace feature to work with multiple browser instances.

2.4.0

Minor Changes

2.3.3

Patch Changes

2.3.2

Patch Changes

2.3.1

Patch Changes

2.3.0

Minor Changes

2.2.0

Minor Changes

2.1.1

Patch Changes

  • #219 bbbc8e8 Thanks @unional! - Improve setAutoSnapshotOptions() to work in beforeAll hook without passing in the suite object.

2.1.0

Minor Changes

2.0.1

Patch Changes

2.0.0

Major Changes

  • #204 020121f Thanks @unional! - Change the customizeSnapshotId to accept context object.

    This is a breaking change. Feature-wise, it is the same as before. We will enable better customization by passing viewport to the customizeSnapshotId function in the future.

  • #204 76b09cc Thanks @unional! - Add support to customize snapshotRootDir with a function. Deprecate platform option.

1.7.0

Minor Changes

  • #195 972db1b Thanks @unional! - Allow setAutoSnapshotOptions to specify additional properties. Each theme in vis.presets.theme() and vis.afterEach.matchPerTheme() will receive the options.

    vis.presets.theme({
    theme1(options) { ... }
    })

1.6.5

Patch Changes

  • #190 be483d4 Thanks @unional! - Support customizeSnapshotId option during theme auto snapshot.

1.6.4

Patch Changes

1.6.3

Patch Changes

1.6.2

Patch Changes

  • #183 49e8fbc Thanks @unional! - Export AutoSnapshotOptions to fix the inferred type cannot be named error.

1.6.1

Patch Changes

  • #182 537cf83 Thanks @unional! - Should not take snapshot when the test failed. Ensure the theme is awaited before taking the snapshot.

1.6.0

Minor Changes

1.5.1

Patch Changes

  • #166 611e0cc Thanks @unional! - Use config.root instead of runner.root. runner.root is protected in Vitest v3.

1.5.0

Minor Changes

  • #162 995140f Thanks @unional! - Support customizing platform by @joekrump.

    For example, with vis({ platform: 'ci' }), Instead of saving the snapshots to <root>/__vis__/{local or process.platform}, the snapshots will be saved to <root>/__vis__/ci.

Patch Changes

  • #156 72959a6 Thanks @unional! - Add top level types field to package.json for project not using ESM module resolution.

  • #160 d2fdcbe Thanks @unional! - Remove expectToFail from VisOptions. It should not have that property.

  • #161 43fc2ce Thanks @unional! - Change default timeout to 30s. The initial timeout of 1s was set by Vitest. It is causing tests to fail with TimeoutError, even when getting Locator like getByRole.

    This timeout will be removed in Vitest 3.

    The underlying provider (playwright) does not have a default timeout.

    Setting to 30s should be a good default for most cases.

    It could still be too short for slow CI or when it is running scripts in parallel. That was the case for storybook-test-runner but could be improved in Vitest browser mode.

    If timeout is still an issue, we can further default it to 60s or even 120s.

  • #158 a020417 Thanks @unional! - Add a blank line to separate the theme error messages.

  • #160 ee4ef14 Thanks @unional! - Fix the global setting not being applied.

1.4.0

Minor Changes

1.3.2

Patch Changes

1.3.1

Patch Changes

1.3.0

Minor Changes

  • #139 17510d3 Thanks @unional! - Add expectToFail support. This is useful to test where the visual should be changed beyond the threshold.

  • #144 f642dbf Thanks @unional! - Change import { matchImageSnapshot } from 'vitest-plugin-vis/client' to import { imageSnapshotMatcher } from 'vitest-plugin-vis/client'.

    This is a bug in 1.2.0 because matchImageSnapshot is hard loading @vitest/browser/context, which causes storybook to fail to load.

Patch Changes

  • #144 2d4f1c0 Thanks @unional! - Extends expect and page in presets.

  • #144 78cc195 Thanks @unional! - Augment expect and page in main so that consumer can load the types:

    {
    "compilerOptions": {
    "types": ["vitest-plugin-vis"]
    }
    }

1.2.0

Minor Changes

  • #137 e4bef32 Thanks @unional! - Assert context.testPath on setupVisSuite command.

    Add stubBrowserCommandContext to /testing.

Patch Changes

1.1.0

Minor Changes

  • 0360253 Thanks @unional! - Deprecate toTaskId.

  • #133 badf227 Thanks @unional! - Perform image comparison on the client side. This is similar to storybook-addon-vis@0.13.0, but the image taking is still done on the server side.

    Try to address the issue of the slower image comparison on the server side.

    Export matchImageSnapshot function on the client side. Mark parseImageSnapshotSubject as deprecated as it is not needed anymore.

Patch Changes

1.0.5

Patch Changes

1.0.4

Patch Changes

1.0.3

Patch Changes

  • #125 1068941 Thanks @unional! - Try to improve the performance of the plugin by skipping the rescale step and not checking the CRC of the image.

    This should be safe because the image is generated by the browser, or it is a base64 string (not 100% sure on this), and the CRC is not used for anything.

    If not performance improvement is seen, we can revert this change.

1.0.2

Patch Changes

1.0.1

Patch Changes

  • #117 ae98ec4 Thanks @unional! - Proxy vitest/suite.

    This fix the warning message Module "util" has been externalized for browser compatibility. when it is loaded in the browser.

    Fixes #101.

1.0.0

Major Changes