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 namevetrix_access_token→ satisfies the server-side middleware gate.page.addInitScript(() => sessionStorage.setItem('vetrix_access_token', …))→ satisfies the clientapiFetchBearer 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(sodecodeAccessTokennever 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.