Skip to content

V3 E2E Testing Contract v1

Decision

The v3 migration should use a new workflow-level E2E contract. Do not port fragile v1 Playwright tests as-is.

The old v1 tests exist to protect the demo/internal continuity surface while it remains active. They should not define the v3 test architecture. As v3 production pages replace v1 pages, new v3 tests should become the release gate and old v1 tests should be retired with the old routes.

Principles

  • Test workflows, not component implementation details.
  • Prefer stable data-testid selectors for navigation and workflow assertions.
  • Use role/name assertions only for explicit accessibility coverage.
  • Mock backend routes fail-closed: an unmocked /backend/** call is a test failure.
  • Keep fixtures deterministic and page-shaped around v3 read models.
  • Keep browser E2E focused on real browser behavior; use Vitest for pure rendering/formatting logic.
  • Do not assert exact marketing copy or headings in workflow tests.
  • Do not call frozen v1 routes from new v3 tests unless the test explicitly verifies migration fallback.
  • V3 workflows may call stable domain APIs for dependency mutations that are not page-specific V1 surfaces, such as SSH key and project service-account creation. These must be explicitly mocked by the fail-closed harness.

Required v3 Selectors

Every production v3 page must expose:

Surface Required selector
Page root data-testid="v3-{surface}-page"
Shell root data-testid="v3-shell"
Mode switcher data-testid="v3-mode-switcher"
Tenant selector data-testid="v3-tenant-selector"
Project selector data-testid="v3-project-selector"
Primary nav group data-testid="v3-nav-{group}"
Action band data-testid="v3-action-band"
Data table data-testid="v3-data-table"
Table row data-testid="v3-row-{stable-id}"
Detail header data-testid="v3-resource-header"
Context strip data-testid="v3-context-strip"
Section tabs data-testid="v3-section-tabs"
Wizard shell data-testid="v3-wizard"
Wizard step data-testid="v3-wizard-step-{step-id}"
Inline creator data-testid="v3-inline-create-{dependency}"
Empty state data-testid="v3-empty-state"
Error state data-testid="v3-error-state"

Use semantic suffixes that survive copy changes. For example, use v3-wizard-step-access, not v3-wizard-step-add-ssh-key.

Backend Mocking Contract

V3 E2E tests must route backend requests through a shared mock harness:

  • Known v3 read-model routes return deterministic fixtures.
  • Known auth/session/bootstrap routes return deterministic session fixtures.
  • Known dependency-domain routes used by V3 launch flows return deterministic fixtures, for example /api/v1/ssh-keys and /api/v1/projects/{project_id}/service-accounts.
  • Any unmocked /backend/** route fails the test with the URL and method.
  • Tests may opt into real backend/kind mode only through an explicit environment flag.

This prevents false-positive tests where the browser silently hits an unexpected v1 route or returns a generic 200.

Initial V3 E2E Suites

Suite Purpose
v3-shell.spec.ts Shell loads, mode switcher works, tenant/project/region context renders, no v1 route calls
v3-personas.spec.ts Seeded persona modes render against /v3-prod/* surfaces with the expected shell context
v3-workloads.spec.ts Workload list, action band, detail tabs, task/evidence links
v3-launch-wizard.spec.ts Step navigation, inline dependencies, draft persistence, safe retry copy
v3-compute-apps.spec.ts Compute and apps catalog rows, app detail, launch readiness wiring (v3-compute, v3-apps)
v3-storage.spec.ts Storage workbench/detail and provider-neutral capability rendering
v3-access-account.spec.ts Access posture, credentials map, account security/session surfaces
v3-admin-platform.spec.ts Platform overview, lifecycle, ops/evidence/finance/IAM family navigation

Retirement Rule

When a v3 suite covers a workflow and the production UI no longer links to the old v1 page, retire the corresponding v1 E2E coverage. Do not keep duplicate long-term E2E suites for both v1 and v3.

The default frontend e2e CI gate should run the v3 production suites and the cutover middleware smoke. V1 Playwright specs are compatibility-only after a workflow has a covered /v3-prod/* route; run them explicitly with E2E_SPEC only when debugging a listed fallback route.

v1 Retirement Candidates

Once each v3 suite below covers its workflow against the production UI, retire the listed v1 specs:

When v3 suite is green against production UI Retire these v1 specs
v3-shell.spec.ts ui-shell.spec.ts, persona-smoke.spec.ts, persona-user.spec.ts, persona-admin.spec.ts
v3-workloads.spec.ts allocation-smoke.spec.ts, user-flows.spec.ts (workload sections)
v3-launch-wizard.spec.ts provisioning.spec.ts, user-flows.spec.ts (launch sections), admin-provisioning.spec.ts
v3-storage.spec.ts (no v1 equivalent today)
v3-access-account.spec.ts iam.spec.ts, iam-full.spec.ts
v3-admin-platform.spec.ts admin-provisioning.spec.ts (admin sections)

Specs that stay regardless (cover concerns the v3 migration does not own):

  • auth-login.spec.ts, auth-guard.spec.ts, auth-timeout.spec.ts (auth flow)
  • developer-docs.spec.ts, developer-downloads.spec.ts (developer surfaces)
  • nodesim.spec.ts (node simulator)
  • terminal-input.spec.ts (terminal session input)
  • ux-capture.spec.ts (visual regression capture)

See doc/product/V3_V1_Retirement_Guardrails_v1.md for the compatibility-only route list and the frontend e2e cutover policy.