Initial Commit

This commit is contained in:
2026-05-27 23:29:53 +01:00
commit fbc70f96e6
10000 changed files with 1102152 additions and 0 deletions

View File

@@ -0,0 +1,70 @@
## 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%