E2E Testing with Playwright

The panel ships with a Playwright test harness that gives every test a real, pre-authenticated session for a specific role — no OAuth, no login page, no browser cookies to manage manually.

How It Works

The test-session endpoint is guarded by NODE_ENV !== 'production' — it is never reachable in production.

Roles Available


Writing a Test

1. Create the spec file

Place all E2E specs in frontend/solidstart/tests/e2e/. Follow the naming convention:
  • Single-role: <feature>.<role>.spec.ts — e.g. dashboard.superadmin.spec.ts
  • Multi-role: <feature>.multirole.spec.ts — when one test verifies permission differences across roles
You do not need any login code inside the test. The session is injected automatically by Playwright’s storageState for the project you select at run time.

2. Run the test as a specific role

The --project flag selects which stored auth state (and which role) Playwright loads. No auth code is needed in the test itself.

The [data-testid="api-error-toast"] Contract

In dev mode the panel wraps globalThis.fetch and appends a visible <div data-testid="api-error-toast"> to the DOM whenever any request returns a status ≥ 400. Every happy-path test MUST assert this element has count 0:
This ensures silent 4xx/5xx errors — which would normally be invisible — are caught by Playwright screenshots and fail the test explicitly.
Omitting this assertion means broken API calls can go undetected even on a green test run.

Before You Start: One-Time Setup

Seed test users

This upserts the three test users with the correct platform roles and credential accounts. Safe to re-run — it uses upsert.

Set environment variables

Copy .env.test.example from the monorepo root to .env.test and fill in your local values:

Running Smoke Tests First

Before running Playwright, run the API smoke test to catch any broken endpoints early:
Expected output:
If any endpoint fails here, fix it before running Playwright — E2E tests will fail for the same reason.

Agent Definition of Done

Before handing off any frontend feature, complete all steps and paste terminal output as proof:
  1. Smoke tests passpnpm smoke:api exits 0
  2. Playwright spec passesnubx playwright test <spec> --project=<role> exits 0
  3. No API error toasts → final assertion in spec confirms count 0
Do not hand off if any step fails.

Troubleshooting

Global setup fails: “Test user not found”

The test users haven’t been seeded yet. Run:

Global setup fails: “Sign-in failed”

The credential account for the test user is missing or has a stale password. Re-run the seed — it deletes and recreates credential accounts:

Session returns 401 on protected endpoints

The cookie set by test-session needs to match the backend that the panel talks to. Make sure TEST_SESSION_ENDPOINT in .env.test points to the same Bun backend that the panel’s VITE_BETTER_AUTH_URL points to.

Auth state files are stale

Delete the auth directory and let global setup recreate it:

  • Adding Features
  • Build Scripts
  • Backend: backend/bun/AGENTS.md — Definition of Done for backend changes
  • Frontend: frontend/solidstart/AGENTS.md — Naming convention and Definition of Done