Files
suaveplan/openspec/archive/2026-04-19-enterprise-testing-dom/proposal.md
2026-05-27 23:29:53 +01:00

3.8 KiB

Why

@suaveplan/testing-dom is the entry point for every React/DOM component test in the genesis monorepo and the home of the test runner adapter. Per the testing-package separation hard rule (see openspec/project.md), it owns:

  • The vitest primitive re-exports (describe, it, expect, vi, fn, spy, stub, mock, fakeClock, restoreMocks, restoreTimers)
  • The createTestConfig() factory and runner/environment detectors (detectRunner, detectEnvironment, createVitestConfig, createBunTestConfig)
  • The polyfills setup file (@suaveplan/testing-dom/polyfills)
  • React/DOM-specific helpers built on @testing-library/react, @testing-library/jest-dom, @testing-library/user-event

Genesis Layer 0 — testing-infra packages take no @suaveplan/* workspace deps. External catalog deps only. The runner adapter + DOM helpers live here (not in @suaveplan/testing) because DOM tests already imply vitest+happy-dom; co-locating the runner adapter with the DOM helpers is the natural home.

What Changes

  • New package @suaveplan/testing-dom at packages/universal/testing-dom/ (genesis-fresh, version 0.1.0).
  • Imports the staged runner/config/polyfills code from packages/universal/testing-dom-staging/ (created during the testing split refactor) and absorbs it cleanly.
  • Substitutions per genesis rules:
    • Local TestingDomError extends Error with { code, cause, context } shape (no @suaveplan/error)
    • @opentelemetry/api direct (no @suaveplan/opentelemetry)
    • zod direct (no @suaveplan/schema-registry)
    • English-only code machine-contract messages (no @suaveplan/i18n)
  • No @suaveplan/* workspace deps. External catalog deps only.

Public surface (this package)

  • Runner re-exports (vitest under default condition; bun-test under bun condition): describe, it, test, expect, vi, beforeAll, beforeEach, afterAll, afterEach, fn, spy, stub, mock, fakeClock, restoreMocks, restoreTimers
  • Config: createTestConfig, TestConfigOptions, TestRunner, TestEnvironment, VitestConfigOverrides, BunTestConfig, BunTestConfigOverrides
  • Polyfills: @suaveplan/testing-dom/polyfills side-effect module
  • DOM render: renderComponent (typed wrapper around @testing-library/react's render with sensible defaults: act-aware, cleanup hooked into vitest's afterEach)
  • DOM queries: re-exports screen, within, findByRole/getByRole/queryByRole, etc.; surfaces accessibility-first names with clearer aliases (e.g. byRole(name, opts) shortcut). getByTestId still re-exported but documented as a fallback.
  • User events: userEvent (v14+ instance) + a setupUser() factory wired to vitest fake timers when present
  • Matchers: extends expect with @testing-library/jest-dom matchers
  • Errors: TestingDomError, RenderError, MatcherError, ConfigError, AbortedError — each with stable TESTING_DOM.<DOMAIN>.<REASON> codes

Capabilities

New Capabilities

  • testing-dom: DOM/React testing infrastructure for genesis — runner adapter (vitest+bun-test conditional exports), createTestConfig factory, polyfills, React 19 render helpers, accessibility-first queries, jest-dom matchers, user-event v14.

Modified Capabilities

(none — no prior spec)

Impact

  • Affected code: packages/universal/testing-dom/** (fresh).
  • Affected consumers: every React/DOM-testing package (none yet on genesis; this is Layer 0).
  • Version: 0.1.0 (genesis baseline).
  • Catalogs added/extended: @testing-library/react, @testing-library/jest-dom, @testing-library/user-event, @testing-library/dom to a new catalogs.dom-testing (or extend catalogs.testing).
  • Pre-publish gate: bunx turbo lint typecheck test --filter=@suaveplan/testing-dom green + ≥ 95% coverage on touched modules.