Skip to content

Testing Runtime And CI

Use this page when browser runtime setup, Playwright source imports, CI jobs, i18n verification lanes, manifest-backed checks, deployed-dev smoke, or docs smoke behavior is the concern.

Local browser debugging uses next dev by default. CI smoke uses a built front-end runtime so timing reflects built artifacts instead of on-demand development compilation.

Default local sequence:

Terminal window
pnpm install
pnpm dev:docker:up
pnpm test:e2e:prepare
pnpm -C apps/wavemap-front-end exec playwright install chromium

Start the frontend in its own shell:

Terminal window
pnpm -C apps/wavemap-front-end dev

Then run the smoke suite from another shell once http://localhost:3000 is serving:

Terminal window
pnpm -C apps/wavemap-front-end test:e2e:smoke

CI-style built-runtime sequence:

Terminal window
pnpm -C packages/i18n build-and-validate:i18n-assets
pnpm -C apps/wavemap-front-end build

Start the built runtime in its own shell:

Terminal window
PLAYWRIGHT_FRONTEND_RUNTIME=build pnpm -C apps/wavemap-front-end start

Then run smoke against that built runtime from another shell:

Terminal window
pnpm -C apps/wavemap-front-end test:e2e:smoke -- --project=chromium

The app runtime must already be running before Playwright starts; apps/wavemap-front-end/playwright.config.ts does not own a webServer today.

Required local availability:

  • Docker Engine and Docker Compose.
  • Backend dev stack reachable through the expected local URL.
  • Front-end runtime at http://localhost:3000.
  • Playwright Chromium installed.
  • App-level .env.shared / .env.dev files or equivalent exported variables for both front end and back end.
  • Seeded Sorsari artist route at /en/artist/ef839db3-ae41-4af9-9078-a8d211089962.

Keep future browser tests package-scoped and anchored on implemented routes. Placeholder pages should not be the first browser journey for a new surface.

The front-end Playwright suite lives in source form, but several imports resolve through workspace package exports that point at built dist outputs. A fresh checkout, CI worker, or package-boundary change can therefore fail before a browser ever opens if the package outputs are missing or stale.

Use these root commands when the browser suite, package exports, package build outputs, TypeScript config, or Playwright runtime wiring changes:

Terminal window
pnpm test:e2e:prepare
pnpm test:e2e:verify-source-runtime

pnpm test:e2e:prepare builds the shared package outputs needed by front-end Playwright source imports. pnpm test:e2e:verify-source-runtime runs that preparation, then asks Playwright to discover specs in build mode. This is a cheap contract check for import and discovery drift; it does not replace a browser smoke run against a live app runtime.

The continuous_integration workflow separates broad repo confidence into diagnosable jobs:

  • verify_tooling_and_code
  • docs_build
  • i18n_verification
  • fe_unit_tests
  • fe_e2e_smoke
  • docker_builds

CI answers whether a commit is healthy enough to merge. Deployed-dev CD answers whether the selected ref, credentials, cloud state, runtime config, artifacts, and smoke target can deploy together.

The CI jobs mostly depend on verify_tooling_and_code rather than each other so failures stay attributable to one layer.

The verify_tooling_and_code job is the first gate and the dependency for the other CI jobs.

It:

  1. Checks out the repo with full history for tooling checks that inspect git state.
  2. Uses the shared pnpm setup action.
  3. Installs actionlint.
  4. Runs pnpm verify:github-actions.
  5. Runs pnpm verify:tooling.

pnpm verify:tooling deliberately starts with the broad consumer checks:

  • pnpm format:check
  • pnpm lint
  • pnpm typecheck

Those commands make the shared formatting, ESLint, TypeScript, and related tooling presets prove themselves through the monorepo packages and apps that consume them, rather than only checking the preset files in isolation. After the full consumer pass, the script also performs targeted config-resolution checks from the front-end and back-end apps: Stylelint prints the resolved SCSS config, TypeScript prints each app’s resolved tsconfig.json, and ESLint prints the resolved config for stable source files.

This job proves the workflow files and monorepo tooling contracts before CI spends time on app, package, browser, docs, or Docker work.

The docs_build job proves that the docs site still compiles after the tooling gate passes.

It:

  1. Checks out the repo.
  2. Uses the shared pnpm setup action.
  3. Runs pnpm build:docs.

Use this lane for Starlight content, routing, sidebar, MDX, import, and docs build regressions. Runtime publication and public docs smoke are covered outside this CI job.

The i18n_verification job validates source localization contracts without running the app.

The YAML surface is intentionally short, but the verifier behind pnpm verify:i18n walks the source localization model in several phases.

The job:

  1. Checks out the repo.
  2. Uses the shared pnpm setup action.
  3. Runs pnpm verify:i18n, which delegates to packages/i18n/scripts/i18n/verifyI18n.js.

The verifier then:

  1. Discovers locale directories and parses every source translation sheet under packages/i18n/locales.
  2. Confirms every locale has the same namespace files.
  3. Expands the TypeScript namespace registry from source constants and compares it with the locale JSON files.
  4. Uses English as the reference key tree for all other locales.
  5. Validates key naming, root _meta shape, and deterministic sheet ordering.
  6. Checks domain-code translation contracts and backend base-seed source wiring.
  7. Parses ICU strings and compares interpolation, plural, and select contracts across locales.

This job catches translation-source drift before browser smoke or deployed runtime checks. See i18n Verification for the source-level contract details.

The fe_unit_tests job is the root Vitest confidence lane, despite the front-end-oriented job name.

It:

  1. Checks out the repo.
  2. Uses the shared pnpm setup action.
  3. Builds the shared workspace packages needed by the test runner: @wavemap/shared-utils, @wavemap/api-contracts, and @wavemap/i18n.
  4. Runs pnpm test:ci.

This job covers the shared-package Vitest suites and the front-end Vitest suite. Browser E2E stays outside this root aggregate.

The fe_e2e_smoke job proves the narrow browser smoke suite against a built front-end runtime and a Docker-backed local backend.

It:

  1. Checks out the repo.
  2. Uses the shared pnpm setup action.
  3. Prepares the front-end Playwright source runtime through pnpm test:e2e:prepare.
  4. Installs Playwright Chromium and its runner dependencies.
  5. Validates required CI secrets.
  6. Materializes ephemeral front-end and back-end app env files for the runner.
  7. Exports the front-end runtime env used by the built smoke runtime.
  8. Generates and validates static i18n assets.
  9. Starts the backend through pnpm dev:docker:up.
  10. Builds the front end.
  11. Starts the built runtime.
  12. Waits for http://localhost:3000/en/ping.
  13. Runs the Chromium smoke suite.
  14. Uploads Playwright artifacts and prints the front-end runtime log on failure.
  15. Stops the front-end runtime and tears down the backend Docker stack.

The built runtime currently uses next start. Matching the deployed Docker standalone node server.js runtime exactly is a later deployment-parity refinement, not the current CI contract.

The docker_builds job is a path-filtered Docker verification lane.

It:

  1. Checks out the repo.
  2. Detects whether Docker-relevant paths changed.
  3. Skips the job body when no Docker-relevant changes are detected.
  4. Uses the shared pnpm setup action when Docker verification is needed.
  5. Sets up Docker Buildx.
  6. Runs pnpm verify:docker-builds.

This job keeps Docker build verification out of unrelated pull requests while still checking package, app, lockfile, workspace, Turborepo, and Docker-related changes when they can affect image builds.

i18n has a dedicated source-level verification lane because localization regressions often come from string identity drift, key-tree drift, ICU contract drift, or generated-resource drift rather than TypeScript failures.

At the CI layer, the i18n_verification job runs the read-only source verifier. For local work, pair the formatter and verifier so translation sheet ordering and contract failures stay easy to diagnose:

Terminal window
pnpm format:i18n
pnpm verify:i18n

pnpm format:i18n rewrites source translation sheets into canonical ordering. pnpm verify:i18n performs the same source checks that CI enforces: source translation JSON parsing, locale parity, namespace registry parity, English-baselined key shape, key spelling, _meta shape, deterministic ordering of translation keys, domain-code translation contracts, backend base-seed source wiring, and ICU message contracts.

CI runs this through the i18n_verification job in .github/workflows/ci.yml, separate from front-end browser smoke tests. The FE E2E smoke lane also runs pnpm -C packages/i18n build-and-validate:i18n-assets before building the frontend runtime, so the built app proves the generated static i18n snapshot it will actually serve.

See i18n Guardrails for the source contract details and how they are verified in depth.

Several deployment checks validate generated or Pulumi-shaped outputs against explicit manifests before live mutation paths run.

Examples include:

  • pnpm deploy:dev:frontend-build-inputs, which validates frontend image build inputs against Pulumi-shaped i18n delivery outputs, deploy Dockerfile wiring, Compose args, and local Docker build verifier expectations.
  • pnpm deploy:dev:runtime-parameters, which validates deployed-dev runtime parameter references against the workflow manifest boundary and Pulumi-shaped outputs.
  • pnpm deploy:dev:validate-env, which validates infra/environments/deployed-dev/workflow-env.contract.json in safe skeleton mode by default and in GitHub cloud mode only when explicitly requested.

These checks are part of the current “fail before touching cloud” posture for deployed-dev automation.

When adding or changing environment variables, runtime config, build inputs, secrets, Pulumi outputs, or runtime parameters, use Configuration And Secrets to choose the source of truth and the smallest useful verification surface.

Deployed smoke checks are layered by cost, destructiveness, and operator value:

LaneDefault PostureNotes
Endpoint smokeRoutine branch-CD gate.Checks readiness, app entrypoint, backend health/ready routes, and i18n manifest availability.
Wake smokeManual/add-on.Cheap control-plane health check.
Browser routing smokeManual/add-on candidate.Non-destructive browser route proof.
Reset and seeded smokeRecipe-scoped.Requires deliberate destructive database reset.
Browser smokeRecipe-scoped.Depends on seeded data and uploads browser artifacts on failure.
Media and browser-media smokeRecipe-scoped.Mutates one temporary media fixture against real S3/CloudFront.
Cold-start browser smokeManual lifecycle proof.Deliberately stops the shared runtime host before proving browser recovery.

Use Media Workflow And Validation when deciding whether a media change needs mocked storage, emulator proof, deployed-dev media smoke, browser media smoke, or a discrepancy report.

Broader E2E should stay out of the default deployed-dev gate until auth/session setup, seed ownership, cleanup, and runtime timing controls are stable.

Promote deployed smoke lanes cautiously:

  • Routine branch CD should stay on non-destructive endpoint smoke until a higher-cost lane repeatedly proves useful.
  • Add-on browser routing smoke can graduate only if it remains non-destructive and has stable wake/readiness behavior.
  • Seeded, browser, media, browser-media, and cold-start lanes should stay recipe- or profile-scoped while they require destructive reset, shared seeded data, uploaded artifacts, real media mutation, or deliberate runtime host state.
  • A promoted lane needs clear operator value, bounded runtime cost, predictable artifacts, and a cleanup or discrepancy story that does not surprise the next deploy.

The docs app has both CI and deployed smoke coverage:

Terminal window
pnpm build:docs
pnpm smoke:docs

pnpm build:docs validates the Starlight build in CI. pnpm smoke:docs runs after static docs publication and should stay read-only; it must not wake or call the deployed app/API runtime.