Files
2026-05-27 23:29:53 +01:00

71 lines
4.3 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
## ADDED Requirements
### Requirement: Storybook test-runner config factory
The `@suaveplan/testing-dom` package SHALL export `createStorybookTestRunnerConfig(opts?)` returning a `@storybook/test-runner` config object that wires a `postVisit` hook capturing a screenshot for every story variant. The threshold (`maxDiffPixelRatio: 0.005`), animation policy (`animations: 'disabled'`), and viewport (`1280×720`) MUST match the e2e visual path defined in `testing-e2e/spec.md`.
#### Scenario: Threshold matches e2e path
- **WHEN** `createStorybookTestRunnerConfig()` is invoked with no overrides
- **THEN** the resulting config's screenshot threshold equals the value emitted by `configureVisualRegression()` in `@suaveplan/testing-e2e`
#### Scenario: postVisit hook installed
- **WHEN** the test-runner executes a story
- **THEN** the `postVisit` hook captures a screenshot named after the story id
### Requirement: `pinStoryEnvironment` determinism harness
The package SHALL export `pinStoryEnvironment(page)` which locks viewport to `1280×720`, awaits `document.fonts.ready`, sets `prefers-reduced-motion: reduce`, and applies the story's declared `colorScheme` (`light` or `dark`) via `page.emulateMedia`. Failure to reach font readiness within `timeoutMs` MUST throw `StorybookVisualError` with `code === 'TESTING_DOM.STORYBOOK_VISUAL.RUNNER_LOAD_FAILED'`.
#### Scenario: Determinism levers applied
- **WHEN** `pinStoryEnvironment(page)` resolves
- **THEN** `prefers-reduced-motion` is `'reduce'` AND fonts are loaded AND viewport is `1280×720`
#### Scenario: Color scheme honoured
- **WHEN** a story declares `parameters.colorScheme === 'dark'`
- **THEN** `pinStoryEnvironment(page)` calls `page.emulateMedia({ colorScheme: 'dark' })` before capture
### Requirement: Theme and locale decorator pinning
`ThemeDecorator` and `LocaleDecorator` consumed by `*.stories.tsx` files SHALL apply a deterministic theme and locale per story file (no per-render randomness, no `Date.now()`-derived choices). Stories that need to vary theme or locale MUST do so via explicit `parameters` rather than runtime state.
#### Scenario: Decorator output stable
- **WHEN** the same story is rendered twice with identical `parameters`
- **THEN** the resulting DOM and visual screenshot are bit-identical
### Requirement: Per-variant baseline coverage
Every `*.stories.tsx` file registered with the Storybook test-runner SHALL produce a baseline screenshot per declared variant (named export). Stories with no baseline on the active platform MUST throw `StorybookVisualError` with `code === 'TESTING_DOM.STORYBOOK_VISUAL.BASELINE_MISSING'` unless `--update-snapshots` is in effect.
#### Scenario: Variant baseline missing
- **WHEN** a story variant has no baseline on the active platform AND `--update-snapshots` is NOT set
- **THEN** the run throws `StorybookVisualError` with `code === 'TESTING_DOM.STORYBOOK_VISUAL.BASELINE_MISSING'`
#### Scenario: Variant pixel diff exceeded
- **WHEN** a variant comparison exceeds the configured `maxDiffPixelRatio`
- **THEN** the run throws `StorybookVisualError` with `code === 'TESTING_DOM.STORYBOOK_VISUAL.PIXEL_DIFF_EXCEEDED'` whose `context` contains `{ storyId, baselinePath, actualPath, diffPath, pixelRatio }`
### Requirement: Structured error codes
All errors thrown from the Storybook visual helpers SHALL be subclasses of `TestingDomError` carrying `{ code, cause?, context? }` and SHALL match the regex `^TESTING_DOM\.STORYBOOK_VISUAL\.[A-Z_]+$`. Defined codes are `TESTING_DOM.STORYBOOK_VISUAL.PIXEL_DIFF_EXCEEDED`, `TESTING_DOM.STORYBOOK_VISUAL.BASELINE_MISSING`, `TESTING_DOM.STORYBOOK_VISUAL.RUNNER_LOAD_FAILED`.
#### Scenario: Coded error
- **WHEN** any Storybook visual helper throws
- **THEN** the thrown value `instanceof TestingDomError` is true AND `err.code` matches the regex
### Requirement: Coverage gate at 100%
Istanbul statement, branch, function, and line coverage across `packages/testing/testing-dom/src/storybook-visual/` (excluding `*.bench.ts`, `*.schemas.ts`, barrel `index.ts`) MUST be 100% on every dimension. The pre-publish gate (`bunx turbo test:coverage --filter=@suaveplan/testing-dom`) hard-fails below 100%.
#### Scenario: Coverage gate enforces 100%
- **WHEN** `bunx turbo test:coverage --filter=@suaveplan/testing-dom` runs
- **THEN** statements, branches, functions, and lines coverage all equal 100%