Skip to content

E2E scaffold + port-band convention (30xx dev / 31xx e2e) #3

Description

@denkasyanov

Bake the Playwright E2E setup + the devsite port-band convention into the template, so new projects inherit it with zero per-project design.

Port-band convention (from devsite)

  • 30xx = dev servers — one per project via package.json#devSite.port (3000–3099).
  • 31xx = e2e web server — derived, never stored: devSite.port + 100 (3100–3199).

Properties: dev + e2e coexist (different bands); no cross-project collision (uniqueness inherited from dev port); nothing beyond the dev port is ever tracked. Optional devSite.e2ePort override for a rare clash. 100 project slots.

E2E harness shape (proven in muxa-io)

  • Convex preview deployment per run (convex deploy --preview-create, seeded via reset) — no separate project, fresh DB per CI run.
  • Public _testing.reset mutation hard-guarded by E2E_TEST_MODE=true (a default preview env var) — fails closed on dev/prod.
  • Real WorkOS sign-in in globalSetup → saved storageState; authenticated + unauthenticated Playwright projects.
  • Web server: CLOUDFLARE_ENV=e2e loads .dev.vars.e2e (localhost redirect at dev+100), VITE_CONVEX_URL from the preview URL file.
  • WorkOS requires the exact callback port allowlisted (no port wildcards), so the derived port is registered once per project: http://localhost:<devPort+100>/api/auth/callback.

Reference implementation

Landing in the muxa-io repo — copy apps/web/e2e/, the _testing.ts mutation, the docs/e2e-testing.md convention doc, and the devsite README port-band section. (Once @dendotai/devsite is extracted, the +100 derivation belongs in it.)

Capture-only issue — do the actual template port in the template repo, not from muxa-io.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions