# Dashboard E2E tests

Browser-driven tests for the PiCloud dashboard, powered by [Playwright].

## Prerequisites

The tests drive a real dashboard against a real backend. Bring up both
before running:

```sh
# 1. Postgres
docker compose up -d postgres

# 2. Backend (port 18080 matches dashboard/vite.config.ts dev proxy)
PICLOUD_BIND=127.0.0.1:18080 \
PICLOUD_ADMIN_USERNAME=admin \
PICLOUD_ADMIN_PASSWORD=admin \
DATABASE_URL=postgres://picloud:picloud@127.0.0.1:15432/picloud \
cargo run -p picloud

# 3. Browser binaries (one-time, ~200 MB)
cd dashboard && npm run test:e2e:install
```

The Vite dev server is started automatically by Playwright's `webServer`
config — you do not need to run `npm run dev` yourself.

## Running

```sh
cd dashboard
npm run test:e2e          # headless, full suite
npm run test:e2e:ui       # interactive UI runner
npx playwright test smoke # run a single spec
npx playwright show-report
```

## Env vars

| Var                      | Default                  | Notes                                                             |
| ------------------------ | ------------------------ | ----------------------------------------------------------------- |
| `E2E_BASE_URL`           | `http://localhost:5173`  | Origin tests navigate against (dashboard is mounted at `/admin`). |
| `E2E_API_BASE`           | `http://127.0.0.1:18080` | Backend used by globalSetup health probe + admin login.           |
| `E2E_DASHBOARD_ORIGIN`   | `http://localhost:5173`  | Used to seed `localStorage` during globalSetup.                   |
| `E2E_ADMIN_USERNAME`     | `admin`                  | Bootstrap admin to log in as.                                     |
| `E2E_ADMIN_PASSWORD`     | `admin`                  | Match `PICLOUD_ADMIN_PASSWORD` above.                             |
| `PICLOUD_DASHBOARD_PORT` | `5173`                   | Dev server port — picked up by both Vite and Playwright.          |

## How isolation works

Tests share one backend + one Postgres. To avoid cross-test interference:

- A shared bootstrap admin session is captured once in
  `tests/e2e/.auth/admin.json` (gitignored) and reused by every test via
  `storageState`.
- Each test creates resources with a unique slug / username produced by
  `fixtures/ids.ts` (`e2e-<prefix>-w<worker>-<random>`).
- Each test registers cleanup via `fixtures/cleanup.ts` and tears down
  in `afterEach`. Cleanup is best-effort: a missing resource doesn't
  fail the suite, so a test can pre-delete and still register the entry.

## Layout

```
tests/e2e/
  global-setup.ts          # health probe + admin login + storageState seed
  smoke.spec.ts            # A.5 smoke
  fixtures/
    auth.ts                # UI login/logout helpers (for login-flow specs)
    api.ts                 # bearer-token-backed APIRequestContext
    ids.ts                 # unique slug/username generators (test-fixture)
    cleanup.ts             # afterEach resource teardown
```

[Playwright]: https://playwright.dev
