Vetrix Docs

Running E2E specs offline (no shared dev-stack)

Most src/__tests__/e2e/*.spec.ts specs authenticate via a real /login form post against the shared dev-stack at https://www.gitvetrix.test (see playwright-stack-target.md and the loginAsSuperAdmin / kcoder helpers in src/__tests__/e2e/_helpers.ts (vetrix-frontend repo)). That couples those specs to dev-stack availability.

repo-pipelines-bare-array.spec.ts is different: it mocks the pipelines list call with page.route and asserts pure render behaviour, so it has no live data dependency — only an auth-gate dependency. Removing that last dependency makes the spec drivable in a mocked / CI-isolated environment with nothing but the bundled npm run dev server.

The auth-gate problem

The repo route is gated by src/middleware.ts (vetrix-frontend repo), which 307-redirects to /login unless the vetrix_access_token cookie is present (server-side route gate). The client API (src/lib/auth.ts, vetrix-frontend repo, getAccessToken) reads the same key from sessionStorage to attach the Bearer header. With no live auth backend to mint a token, both slots are empty, the middleware bounces the page to /login, and pipelines-table never renders.

How the spec solves it

The spec seeds both slots in test.beforeEach:

  • context.addCookies(...) with name vetrix_access_token → satisfies the server-side middleware gate.
  • page.addInitScript(() => sessionStorage.setItem('vetrix_access_token', …)) → satisfies the client apiFetch Bearer attach.

The token value is process.env.E2E_ACCESS_TOKEN when set (e.g. a real dev-stack session), and otherwise falls back to a deterministic, test-only local token (LOCAL_E2E_TOKEN) defined at the top of the spec.

LOCAL_E2E_TOKEN is a structurally-valid JWT (header.payload.signature) with:

  • a far-future exp (so decodeAccessToken never treats it as expired),
  • adm: false (grants no admin scope), and
  • a deliberately fake signature segment (e2e-local-harness-not-a-real-signature).

It is not a forgery of a production-signed token. The Go backend verifies the JWT signature on every request and rejects it. It only carries the page past the FE middleware because that middleware is a presence/decode gate that does not verify signatures (the Go server does that). The mocked page.route fulfills the list call, so the page never actually reaches the network. No production auth behaviour is changed and no real credential is committed.

Run it offline

From the repo root, with no dev-stack and no env vars:

npm ci
npx playwright install --with-deps chromium
npx playwright test --project=chromium repo-pipelines-bare-array

Playwright's webServer stanza in playwright.config.ts (vetrix-frontend repo root) spins up npm run dev on http://localhost:3001 automatically (it sets E2E_HARNESS=1, which is unrelated to this auth seed and only unlocks the /__e2e__/* harness pages). The spec reaches pipelines-table with no /login 307 and asserts the running push pipeline (ee977bdd-…) renders from the mocked bare-array response.

Because the spec is tagged @slow, the default CI gate does not run it; use the explicit invocation above (or the scheduled slow-chromium-e2e job) to exercise it.

Targeting the live dev-stack instead

The offline fallback is opt-out: set both E2E_BASE_URL and a real E2E_ACCESS_TOKEN (sourced from a runner secret, never hardcoded — see playwright-stack-target.md §Credentials) and the spec seeds the real token instead of LOCAL_E2E_TOKEN.