Files
suaveplan/openspec/changes/enterprise-testbed-verification/proposal.md
2026-05-27 23:29:53 +01:00

5.4 KiB

Why

CLAUDE.md declares a six-bullet "Web App & Page Verification" rule that any client-side page, website, or web app generated in this monorepo MUST satisfy before being declared done. The rule is normative ("verification is NOT optional"), but it is currently enforced informally — there is no spec that compels every apps/testbed route to attach the full invariant set, no spec that defines a release-readiness gate, and no machine-checkable mapping from each CLAUDE.md bullet to a Playwright assertion.

The test-suite audit at /mnt/s/web/genesis/docs/superpowers/specs/2026-04-25-test-suite-audit.md (sections 7 and 8) calls out three gaps that map directly to the six bullets:

  1. NetworkMonitor returned by attachNetworkMonitor(page) lacks dedicated assertions for missing assets, mixed content, and CORS errors — bullets 4 and 5 of CLAUDE.md cannot be enforced.
  2. There is no broken-link crawler, so navigation/routing transitions between pages (bullet 2) are only spot-checked.
  3. The testbed plan (/mnt/s/web/genesis/docs/superpowers/plans/2026-04-24-testbed-pages-and-e2e.md) and the design at /mnt/s/web/genesis/docs/superpowers/specs/2026-04-24-enterprise-testbed-design.md §7.4 list the invariants every page should run, but specs allow "baseline-only" navigation tests as the sole coverage for a route — bullet 2 ("every component on every page") and bullet 3 ("never trust HTTP 200 alone") are not machine-enforced.

This change closes those gaps by elevating the six-bullet rule into normative requirements across two capabilities: testing-e2e (gains the missing assertions and the crawler) and a new testbed capability (defines the per-page invariant contract and the release-readiness gate).

What Changes

testing-e2e — ADDED requirements

  • NetworkMonitor.assertNoMissingAssets() — fails on any 404 for image/font/script/stylesheet resource types, with monitor.allow404(predicate) opt-out. Maps to CLAUDE.md bullet 5 ("missing assets").
  • NetworkMonitor.assertNoMixedContent() — fails on any http:// subresource on an https:// page or any active mixed-content blocking event. Maps to CLAUDE.md bullet 5 ("mixed content").
  • NetworkMonitor.assertNoCorsErrors() — fails on any Access-Control-Allow-Origin violation, preflight failure, or net::ERR_CORS_*. Maps to CLAUDE.md bullet 5 ("CORS failures").
  • NetworkMonitor.assertNoUnexpectedRequests({ allowed }) — declarative allow-list for strict request-graph control.
  • crawlInternalLinks(page, options) — BFS-walks <a href> links from an entry page (default depth 2, same-origin), asserts each link returns 2xx, returns typed broken-link reports. Maps to CLAUDE.md bullet 2 ("every navigation/routing transition").
  • All four error families use stable codes under TESTING_E2E.NETWORK.* and TESTING_E2E.CRAWL.*.

testbed — ADDED capability

A new normative spec for apps/testbed verification:

  • Per-page interaction spec coverage — every route in apps/testbed/src/routes.ts SHALL have a sibling <route>.interaction.spec.ts that exercises every data-testid="demo-card", asserts non-empty output, and includes at least one demo-specific assertion. "Baseline-only" specs are forbidden as sole coverage. Maps to bullets 2 and 3.
  • Per-page invariants — every interaction spec SHALL attach attachConsoleMonitor (with assertNoErrors + assertNoWarnings), attachNetworkMonitor (with all four assertions above), attachAxe (per enterprise-testing-a11y), and visual regression (per enterprise-testing-visual-regression). Maps to bullets 3, 4, 5.
  • Release-readiness gate — a CI job runs against the testbed Docker stack and fails on any console error/warning, network failure, missing asset, mixed content, CORS error, axe violation, visual diff over 0.5%, broken internal link, or 5xx under load smoke (per enterprise-testing-load-perf). Mandatory for any merge touching apps/testbed or its dependency closure. Maps to bullets 1 and 6.
  • Zero-defect-to-live enforcement — gate failure blocks merge to main (and genesis until graduation). Bullet 6 becomes machine-enforced.
  • Component-on-page coverage — Storybook (per enterprise-browser-storybook-test-utils) covers components in isolation; interaction specs cover components on actual pages. Both required, neither substitutes for the other.

This change is additive. It does not modify existing testing-e2e requirements; it extends them. It also coordinates with enterprise-testing-a11y (axe assertion source), enterprise-testing-visual-regression (screenshot baseline policy), enterprise-testing-load-perf (load smoke composition), and enterprise-testing-operational (Docker staging stack composition).

Impact

  • Affected code: packages/universal/testing-e2e/src/network/** (new assertions), packages/universal/testing-e2e/src/crawl/** (new helper), apps/testbed/e2e/** (interaction specs), apps/testbed/playwright.config.ts (release-readiness project), CI workflow.
  • New capability spec: openspec/specs/testbed/spec.md (created on archive).
  • Modified capability spec: openspec/specs/testing-e2e/spec.md (folded on archive).
  • Cross-references: enterprise-testing-a11y, enterprise-testing-visual-regression, enterprise-testing-load-perf, enterprise-testing-operational, enterprise-browser-storybook-test-utils.
  • Pre-publish gate: unchanged — coverage and lint thresholds already 100% per openspec/AGENTS.md §7.