| name | test-engineering |
| description | Single authoritative testing skill for emdesign. Covers the complete 7-level testing pyramid that replaces human verification — from design system foundation through visual taste and quality gate. Every level uses TDD (RED/GREEN with vitest). Use at the START of any testing task. |
Test Engineering
emdesign testing is code-first: agents write Vitest .test.ts files that import @emdesign/testing primitives, then run npx vitest run <file> to get RED (fail) or GREEN (pass). No custom CLI commands — just standard Vitest.
Tests live in src/primitives/<ComponentName>/ alongside the component and story — co-located, discoverable by vitest config, runnable by developers.
The 7-Level Testing Pyramid
Every level has: TDD (RED→GREEN), primitives, threshold, and a template.
L6: QUALITY GATE ← composite ship/revise decision (runDoctor + all levels pass)
L5: VISUAL TASTE ← AI vision critique, anti-slop lint, accent discipline
L4: VISUAL REGRESSION ← pixel diff, DOM structure, computed CSS vs reference
L3: PAGE COMPOSITION ← landmarks, sections, responsive, navigation
L2: COMPONENT QUALITY ← states, behavior, spatial geometry, contrast, variants
L1: COMPONENT STRUCTURE ← render probe, lint, token binding, no hardcoded values
L0: DS FOUNDATION ← token contract, token accuracy vs DESIGN.md, DESIGN.md completeness, graph
| Level | What it catches | Primitives | Template |
|---|
| L0 | Missing tokens, token/DESIGN.md mismatch, incomplete spec, no graph | assertTokenContractComplete, assertDesignMdComplete, assertGraphContainsNodes, captureTokenSnapshot | ds-foundation.ts |
| L1 | Mount failure, anti-slop P0, raw hex colors, unresolved var(--), hardcoded px/fonts | assertRenderProbePasses, assertNoP0Findings, checkLint, inline regex scans | craft-component.ts |
| L2 | Missing states, no keyboard/ARIA, spatial overlaps, poor contrast, variant rendering | checkStates, assertHasClickHandler, assertSpatialAuditPasses, assertContrastPasses, assertVisionPasses | component-quality.ts |
| L3 | Missing header/main/footer nav, no responsive meta, no sections | assertHasPageStructure, assertHasNavigation, assertPageHasSections, assertHasResponsiveMeta | craft-page.ts, craft-sections.ts, responsive.ts |
| L4 | Visual regressions, DOM drift, style mismatches vs reference | checkVisualDiff (pixel 40% + structure 30% + CSS 30%) | storybook-visual.ts, visual-regression.ts |
| L5 | Low vision score, AI-default gradients, accent overuse, filler copy, emoji icons | assertVisionPasses, checkLint (anti-slop rules), accent count | visual-taste.ts |
| L6 | Composite below threshold, mustFix > 0, any lower level RED | runDoctor, aggregate all level results | quality-gate.ts |
DS Consistency (cross-cutting)
Every component test should also verify:
| Check | How | Threshold |
|---|
| Token contract complete | assertTokenContractComplete | 11 SEMANTIC_TOKEN_ROLES |
| Token values match DESIGN.md | Read DESIGN.md frontmatter → cross-ref tokens.css | Every --color-<key> matches frontmatter |
| No anti-pattern slop | checkLint for purple-gradient, trust-gradient, ai-default-indigo, emoji-icon, filler-copy, invented-metric | mustFix === 0 |
| No hardcoded spacing | Regex \d+px excluding 0px, 1px | 0 hardcoded px |
| No hardcoded fonts | Regex fontFamily outside var(-- | 0 hardcoded |
var(--) resolve | Cross-ref against tokens.css declared tokens | 0 unresolved |
| Variant rendering | Screenshot each variant via Storybook + Playwright | All variants render without error |
TDD: RED/GREEN Loop for Every Agent
1. WRITE a failing test first (RED):
- Select template from test-scenarios/
- Write to src/primitives/<Name>/<Name>.test.ts
- Run: $ npx vitest run src/primitives/<Name>/ --reporter=verbose
- Confirm: exit code != 0 (RED)
2. IMPLEMENT the component/fix (GREEN):
- Write the minimum code to pass the test
- Run: $ npx vitest run src/primitives/<Name>/ --reporter=verbose
- Confirm: exit code === 0 (GREEN)
3. REFACTOR if needed:
- Improve code quality without breaking tests
- Re-run vitest to confirm still GREEN
Template Reference
All templates at skills/test-engineering/test-scenarios/:
| Level | Template | File | What it tests |
|---|
| L0 | DS Foundation | ds-foundation.ts | Token contract, token accuracy vs DESIGN.md, 9 sections, graph, snapshot |
| L1+L2 | Craft Component | craft-component.ts | Render probe, lint, token binding, spatial, behavior, doctor gate |
| L2 | Component Quality | component-quality.ts | States, click/keyboard/ARIA, spatial, contrast, vision critique |
| L3 | Craft Page | craft-page.ts | Page structure, navigation, responsive, visual baseline |
| L3 | Craft Sections | craft-sections.ts | Section landmarks, page structure |
| L3 | Responsive | responsive.ts | Viewport meta, media queries |
| L4 | Storybook Visual | storybook-visual.ts | Pixel diff, DOM structure, computed CSS vs reference |
| L4 | Visual Regression | visual-regression.ts | DOM snapshot + visual similarity (file-to-file) |
| L4 | Overview vs Preview | overview-vs-preview.ts | Cross-DS token equivalence + visual similarity |
| L5 | Visual Taste | visual-taste.ts | AI vision critique, anti-slop, accent discipline, no filler |
| L6 | Quality Gate | quality-gate.ts | Composite doctor, all levels aggregate |
Thresholds
| Check | Threshold | When to use |
|---|
| Doctor gate composite | ≥ 0.8 | Final ship decision |
| Must-fix count | === 0 | Every component |
| Visual similarity (rendered vs ref) | ≥ 0.90 | Storybook visual regression |
| Visual similarity (file-to-file) | ≥ 0.98 | Before/after snapshot |
| Visual similarity (overview vs preview) | ≥ 0.85 | Cross-DS comparison |
| Vision critique | ≥ 0.7 | AI screenshot analysis |
| Spatial critical | === 0 | Geometry audit |
| WCAG AA contrast | ≥ 4.5:1 | Color pairs |
| Token contract | 11 roles | Every design system |
| DESIGN.md sections | 9 titles | Every design system |
| Accent usage | ≤ 2 per screen | Visual discipline |
| Lint mustFix | === 0 | Every component |
| Hardcoded px spacing | 0 | Every component |
| Unresolved var(--) | 0 | Every component |
Guardrails
- RED must be investigated. Never skip a failing test — fix the code, not the test.
- Tests before code. Every component starts with a RED test (TDD).
- No CLI commands. All verification is
npx vitest run — no custom gates.
- Skipped levels must be documented. If Storybook isn't available, note why L4 was skipped.
- The quality gate is final. Level 6 aggregates every level. If it's RED, nothing ships.
- Tests live in
src/primitives/<Name>/. Co-located with component, discovered by vitest config, runnable by developers.