DEV Community

Roberto Luna
Roberto Luna

Posted on

Fixing Broken Production E2E Authentication in Greenview after Login Portal Update

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
Enter fullscreen mode Exit fullscreen mode

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

  1. 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 variable E2E_AUTH_USER was undefined, causing the Playwright script to send an empty string. This was a quick hack that violated security best practices.

  2. Setting the secret through the repository UI – I created a secret named E2E_AUTH_USER in the repo settings, but I forgot to reference it in the workflow file. The job still crashed with E2E_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
Enter fullscreen mode Exit fullscreen mode

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;
});
Enter fullscreen mode Exit fullscreen mode

Key points:

  • No code path changes – The rest of the test suite still uses global.authToken for 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)
Enter fullscreen mode Exit fullscreen mode

Pushing the changes triggered the GitHub Actions workflow. The job completed successfully:

✅  All 12 tests passed
Enter fullscreen mode Exit fullscreen mode

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

  1. Add E2E_AUTH_PASS to the workflow env block – currently it’s pulled from a secret automatically, but making the reference explicit improves readability.
  2. Introduce a retry wrapper around the login request to handle occasional 502 spikes from Vercel’s edge network.
  3. Migrate the authentication flow to a shared helper (src/test/helpers/auth.ts) so future tests can import loginAs(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)