Loading...
Loading...
Storybook 10 testing patterns with Vitest integration, ESM-only distribution, CSF3 typesafe factories, play() interaction tests, Chromatic TurboSnap visual regression, module automocking, accessibility addon testing, and autodocs generation. Use when writing component stories, setting up visual regression testing, configuring Storybook CI pipelines, or migrating from Storybook 9.
npx skill4agent add yonatangross/orchestkit storybook-testingplay()sb.mockdefineMaindefinePreviewpreview.meta()meta.story()@storybook/teststorybook/testexperimental-addon-testaddon-vitestplay()| Rule | Impact | Description |
|---|---|---|
| HIGH | Typesafe CSF3 story factories with |
| CRITICAL | Interaction testing with |
| HIGH | Run stories as Vitest tests via |
| HIGH | TurboSnap reduces snapshot cost 60-90% |
| HIGH | Story-level module mocking with |
| CRITICAL | Automated axe-core accessibility scans in CI |
| MEDIUM | Auto-generated docs from stories |
┌──────────────┐
│ Visual │ Chromatic TurboSnap
│ Regression │ (snapshot diffs)
├──────────────┤
│ Accessibility│ @storybook/addon-a11y
│ (a11y) │ (axe-core scans)
├──────────────┤
│ Interaction │ play() functions
│ Tests │ (@storybook/test)
├──────────────┤
│ Unit Tests │ Vitest + storybookTest
│ (stories) │ plugin
└──────────────┘// Button.stories.tsx
import type { Meta, StoryObj } from '@storybook/react'
import { expect, fn, userEvent, within } from 'storybook/test'
import { Button } from './Button'
const meta = {
component: Button,
args: {
onClick: fn(),
},
} satisfies Meta<typeof Button>
export default meta
type Story = StoryObj<typeof meta>
export const Primary: Story = {
args: {
label: 'Click me',
variant: 'primary',
},
play: async ({ canvasElement, args }) => {
const canvas = within(canvasElement)
const button = canvas.getByRole('button', { name: /click me/i })
await userEvent.click(button)
await expect(args.onClick).toHaveBeenCalledOnce()
await expect(button).toHaveStyle({ backgroundColor: 'rgb(37, 99, 235)' })
},
}// vitest.config.ts
import { storybookTest } from '@storybook/addon-vitest/vitest-plugin'
import { defineConfig } from 'vitest/config'
export default defineConfig({
plugins: [storybookTest()],
test: {
setupFiles: ['./vitest.setup.ts'],
},
})play()satisfiessatisfies Meta<typeof Component>sb.mock(import(...)).storybook/preview.tsmocked()beforeEachvi.mocksb.mock| Anti-Pattern | Why It Fails | Use Instead |
|---|---|---|
CSF2 | Deprecated, no type inference, will be removed in SB 11 | CSF3 object stories with |
| Deprecated since Storybook 9 | |
| Leaks between stories, breaks isolation | Register |
| Full Chromatic snapshots on every PR | Expensive and slow | TurboSnap with |
| Manual accessibility checking | Misses violations, not repeatable | |
| Separate documentation site | Drifts from actual component behavior | Autodocs with |
| Testing implementation details | Brittle, breaks on refactors | Test user-visible behavior via |
| CJS imports in stories | ESM-only since SB 9/10 | Use ESM imports, set |
references/storybook-migration-guide.mdreferences/storybook-ci-strategy.mdreferences/storybook-addon-ecosystem.mdreact-server-components-frameworkaccessibilitydevops-deployment