Vitest Tests

Storybook >=10 addon that displays Vitest tests and coverage for the current component

View on GithubNew to Storybook?Get started

@pilmee/storybook-addon-vitest

ESM addon for Storybook >=10 that adds a Tests panel and shows only the Vitest tests and coverage related to the component rendered by the active story.

Requirements

  • Storybook >=10
  • Node.js >=20.19
  • Vitest >=3 when coverage is needed in the JSON report
  • A Vitest JSON report generated with the json reporter

Installation

npm install --save-dev @pilmee/storybook-addon-vitest

Register the addon immediately after Accessibility. Storybook keeps the addons array order when rendering panels:

// .storybook/main.ts
import type { StorybookConfig } from '@storybook/your-framework';

const config: StorybookConfig = {
  addons: [
    '@storybook/addon-a11y',
    {
      name: '@pilmee/storybook-addon-vitest',
      options: {
        reportPath: './vitest-report.json',
      },
    },
  ],
};

export default config;

reportPath is a browser-read URL relative to the published Storybook. The recommended setup is to generate the file inside the same folder as the static Storybook build, after Storybook has been built:

{
  "scripts": {
    "build-storybook": "storybook build",
    "test:storybook-report": "vitest run --reporter=json --coverage --outputFile=storybook-static/vitest-report.json",
    "storybook:ci": "npm run build-storybook && npm run test:storybook-report"
  }
}

Vitest needs a coverage provider such as @vitest/coverage-v8 when using --coverage. Vitest 3 and newer include the resulting coverageMap in the JSON report. Using a relative URL (./vitest-report.json) also works when Storybook is published under a subdirectory.

For local development, generate the file in a folder served through staticDirs:

// .storybook/main.ts
const config = {
  staticDirs: [{ from: '../storybook-reports', to: '/' }],
  addons: [
    '@storybook/addon-a11y',
    {
      name: '@pilmee/storybook-addon-vitest',
      options: { reportPath: './vitest-report.json' },
    },
  ],
};
vitest run --reporter=json --coverage --outputFile=storybook-reports/vitest-report.json

How Stories Are Matched With Vitest

By default, the addon infers the component from the story import path:

src/components/Button/Button.stories.tsx
                         ↓
src/components/Button/Button.tsx
src/components/Button/Button.test.tsx

It first selects suites whose coverage includes the component file. As a fallback, it compares *.test.* or *.spec.* paths. From global coverage, it keeps only the inferred component file.

When a story does not follow that convention, for example when it imports from an index.ts, declare the path explicitly in the CSF meta:

const meta = {
  component: Button,
  parameters: {
    vitest: {
      componentPath: 'src/components/Button/Button.tsx',
    },
  },
};

export default meta;

You can also override reportPath or disable results for a story/component:

parameters: {
  vitest: {
    reportPath: './reports/unit.json',
    disable: true,
  },
},

Utility API

The package exports filterVitestReport(report, storyImportPath, componentPath?) and inferComponentPath(storyImportPath) so the filtering logic can be reused or tested directly. It also exports the report, coverage, options, and story parameter TypeScript types.

Made by
  • pilmee
    pilmee
Work with
    Angular
    React
    Svelte
    Vue
    Web Components
Tags