> Archived 2026-04-19: package shipped under universal/dev/testing-dom. Spec drift was rectified by `openspec/changes/testing-dom-spec-conformance/` (2026-04-26), which folded `**Verified by:**` lines into the canonical spec, pinned the dual-runner conditional-exports shape, and corrected the path reference in the coverage requirement. ## 1. Catalogs and package skeleton - [x] 1.1 Extend root `package.json` `catalogs.testing` (or new `catalogs.dom-testing`) with `@testing-library/react`, `@testing-library/jest-dom`, `@testing-library/user-event`, `@testing-library/dom`, `@vitejs/plugin-react`. Pin versions via Bun overrides where stability matters. - [x] 1.2 Create `packages/universal/testing-dom/` skeleton: `package.json` (version `0.1.0`, dual-runner conditional exports, runtime deps = vitest+happy-dom+testing-library+@opentelemetry/api+zod+tslib, devDep on `@suaveplan/testing`), `tsconfig.lib.json`, `vite.config.ts`, `vitest.config.ts`, `README.md`. - [x] 1.3 Verify `bunx turbo ls --filter=@suaveplan/testing-dom...` (runtime closure) contains zero `@suaveplan/*` packages. ## 2. Migrate from staging - [x] 2.1 Move `packages/universal/testing-dom-staging/runner/` into `packages/universal/testing-dom/src/runner/`. Update internal imports. - [x] 2.2 Move `packages/universal/testing-dom-staging/config/` into `packages/universal/testing-dom/src/config/`. - [x] 2.3 Move `packages/universal/testing-dom-staging/polyfills.ts` into `packages/universal/testing-dom/src/setup/polyfills.ts`. - [x] 2.4 Update `createTestConfig`'s polyfill setupFile path to `@suaveplan/testing-dom/polyfills`. - [x] 2.5 Delete `packages/universal/testing-dom-staging/` after migration. ## 3. Local error hierarchy - [x] 3.1 Implement `src/errors/testing-dom-error.ts` with `TestingDomError` base + `RenderError`, `MatcherError`, `ConfigError`, `AbortedError` subclasses. - [x] 3.2 Implement `src/errors/codes.ts` enumerating `TESTING_DOM..` constants. - [x] 3.3 Update migrated `createTestConfig` to throw `ConfigError` instead of the old `ConfigError` from `@suaveplan/testing`. - [x] 3.4 Co-locate tests + `.md` for the error module. ## 4. Render helpers - [x] 4.1 Implement `src/render/render-component.ts` with `renderComponent(ui, options?)` — wraps `@testing-library/react`'s `render`, returns `RenderResult` extended with `userEvent`. - [x] 4.2 Auto-register cleanup via vitest's `afterEach` (per-test-file, not global to avoid leak between unrelated suites). - [x] 4.3 Throws `RenderError("TESTING_DOM.RENDER.SETUP_FAILED")` on render-time exceptions. - [x] 4.4 Co-locate tests + `.md` + `.schemas.ts`. ## 5. Query aliases - [x] 5.1 Implement `src/queries/queries.ts` re-exporting `screen`, `within`, and accessibility-first aliases (`byRole`, `byLabelText`, `byText`, `byPlaceholderText`, `findRole`, `queryRole`, etc.). - [x] 5.2 Document the testid-as-fallback policy in the module's `.md`. ## 6. User events - [x] 6.1 Implement `src/user/setup-user.ts`: `setupUser(options?)` returning a `UserEvent` instance with happy-dom-friendly defaults (`pointerEventsCheck: 0`). - [x] 6.2 If `vi.isFakeTimers()` returns true at setup time, wire `advanceTimers: vi.advanceTimersByTime` automatically. - [x] 6.3 Co-locate tests + `.md`. ## 7. jest-dom matchers - [x] 7.1 Implement `src/matchers/matchers.ts` — side-effecting import that calls `expect.extend(...)` with the jest-dom matcher set. - [x] 7.2 Re-export under subpath `@suaveplan/testing-dom/matchers`. - [x] 7.3 Smoke test: import the matchers module, render a node, assert `toBeInTheDocument`. ## 8. OTEL instrumentation (gated) - [x] 8.1 Implement `src/observability/instrumented.ts` — counters/histograms gated behind `process.env.TESTING_DOM_OTEL_ENABLED === "1"`. No-op otherwise. - [x] 8.2 Wrap `renderComponent` and `setupUser` with the gated instrumentation. ## 9. Tests + cross-cutting guards - [x] 9.1 Co-located unit tests for every public module in `src/`. - [x] 9.2 `tests/dep-graph.test.ts` — assert no `@suaveplan/*` runtime deps. - [x] 9.3 `tests/no-disallowed.test.ts` — `any` / `ts-ignore` / `TODO` etc. grep guard. - [x] 9.4 `tests/tree-shake.test.ts` — verify subpaths don't drag unrelated modules. - [x] 9.5 `tests/properties.test.ts` — fast-check property tests for any pure helpers (matcher predicates, query name normalization). - [x] 9.6 Coverage ≥ 95% on every dimension (statements, branches, functions, lines). ## 10. Docs and examples - [x] 10.1 Every implementation file has a sibling `.md` with simple + advanced examples (≥ 200 words). - [x] 10.2 Root `README.md` covers install, quick usage (vitest config, basic component test), error code index, OTEL toggle. - [x] 10.3 `examples/basic-component.tsx` and `examples/with-providers.tsx` runnable scripts. ## 11. Pre-publish gate - [x] 11.1 `bunx turbo lint typecheck test --filter=@suaveplan/testing-dom` green. - [x] 11.2 `bunx turbo test:coverage --filter=@suaveplan/testing-dom` ≥ 95% on every dimension. - [x] 11.3 `openspec validate enterprise-testing-dom --type change` passes. ## 12. Publish (USER APPROVAL REQUIRED) - [x] 12.1 Surface the audit (test count, coverage, lint clean) and STOP. - [x] 12.2 On approval: `bun scripts/publish.ts --package @suaveplan/testing-dom`. - [x] 12.3 Archive change to `openspec/archive/-enterprise-testing-dom/`.