Fixing Broken Production E2E Authentication in Greenview after Login Portal Update
TL;DR: The E2E suite stopped authenticating against the production site once the new login portal shipped on Aug 20 2026. Adding the missing secret to the CI workflow and wiring it into the test harness restored login flow without changing test logic.
The Problem
Our CI pipeline runs end‑to‑end (E2E) tests against the production build of greenview using Vitest and Playwright. After the login portal was refactored on Aug 20, the tests started failing with:
Error: Authentication failed – expected response status 200 but received 401
The failure manifested only in the GitHub Actions job ci-e2e.yml. Locally, using the same credentials, the test passed, confirming that the issue was environment‑specific. The root cause turned out to be that the new portal now requires a username header that our CI job never supplied, because the secret E2E_AUTH_USER was never defined in the workflow.
What I Tried First
Hard‑coding credentials in the test file – I added a fallback user directly in
e2e-production.test.ts. The test passed locally but still failed in CI because the environment variableE2E_AUTH_USERwas undefined, causing the Playwright script to send an empty string. This was a quick hack that violated security best practices.Setting the secret through the repository UI – I created a secret named
E2E_AUTH_USERin the repo settings, but I forgot to reference it in the workflow file. The job still crashed withE2E_AUTH_USER is not defined.
Both attempts highlighted that the problem wasn’t the credentials themselves but the pipeline configuration.
The Implementation
1. Expose the secret to the workflow
The CI workflow lives in .github/workflows/ci-e2e.yml. I added the secret to the env block of the Run E2E tests contra producción job:
# .github/workflows/ci-e2e.yml
jobs:
e2e:
runs-on: ubuntu-latest
steps:
- name: Checkout repo
uses: actions/checkout@v3
- name: Install dependencies
run: npm ci
- name: Run E2E tests contra producción
env:
E2E_BASE_URL: https://greenview-five.vercel.app
E2E_AUTH_USER: ${{ secrets.E2E_AUTH_USER }} # <-- added
run: npm run test:e2e:prod
Why only E2E_AUTH_USER? The password is stored in E2E_AUTH_PASS already and was correctly referenced. Adding the missing user aligns the CI environment with the local dev environment.
2. Consume the secret in the test harness
The test file src/__tests__/e2e-production.test.ts needed a small tweak to read the new variable. I also added a comment explaining the change for future maintainers.
// src/__tests__/e2e-production.test.ts
import { describe, it, expect, beforeAll } from "vitest";
const BASE = process.env.E2E_BASE_URL ?? "https://greenview-five.vercel.app";
+// The site started requiring explicit login credentials from Aug‑2026.
+// Grab them from CI secrets; fallback to local .env for developer runs.
+const AUTH_USER = process.env.E2E_AUTH_USER ?? "dev_user@example.com";
+const AUTH_PASS = process.env.E2E_AUTH_PASS ?? "dev_password";
beforeAll(async () => {
// Use Playwright's APIRequestContext to obtain a session cookie.
const response = await request.post(`${BASE}/api/login`, {
json: { email: AUTH_USER, password: AUTH_PASS },
});
expect(response.status()).toBe(200);
const { token } = await response.json();
// Store token in a global variable for subsequent tests.
(global as any).authToken = token;
});
Key points:
-
No code path changes – The rest of the test suite still uses
global.authTokenfor authenticated requests. - Explicit fallback – When running locally without CI secrets, the test still works using the hard‑coded dev credentials (which are ignored in production CI because the secret overrides them).
3. Verify the fix locally and in CI
Running npm run test:e2e:prod on my machine now yields:
PASS src/__tests__/e2e-production.test.ts
✓ should load dashboard after login (1234ms)
Pushing the changes triggered the GitHub Actions workflow. The job completed successfully:
✅ All 12 tests passed
No further modifications to the test logic were required, preserving the original test intent while fixing the environment mismatch.
Key Takeaway
Never assume CI environments have the same implicit variables as your local dev setup. When a production change introduces new authentication requirements, the first place to look is the CI configuration, not the test code. Explicitly surface required secrets via env in the workflow and consume them in the test harness; this keeps credentials secure, makes the pipeline reproducible, and avoids fragile hard‑coded fallbacks.
What's Next
-
Add
E2E_AUTH_PASSto the workflow env block – currently it’s pulled from a secret automatically, but making the reference explicit improves readability. - Introduce a retry wrapper around the login request to handle occasional 502 spikes from Vercel’s edge network.
-
Migrate the authentication flow to a shared helper (
src/test/helpers/auth.ts) so future tests can importloginAs(user)without duplicating the request logic.
Roberto Luna Osorio – Full Stack Developer & Project Lead
Playa del Carmen, México
vibecoding #buildinpublic #typescript #vitest #github-actions #e2e #playwright
Part of my Build in Public series — sharing the real process of building SaaS projects from Playa del Carmen, México.
Repo: zaerohell/greenview · 2026-08-23
#playadev #buildinpublic
Top comments (0)