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

4.3 KiB
Raw Permalink Blame History

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%