# E2E Tests — Setup and Runbook

> Audience: vendor engineers (Adesso) and operators running the Azure port.
> Status: **scaffold only** — all tests are marked `test.fixme`. None run in CI.

---

## 1. Why Playwright

The five golden-path flows (GP-01 through GP-05) defined in the audit
(`docs/audits/07-tests-handover.md`) require a real browser, a running app, and a
seeded Supabase database. They cannot be expressed as Vitest unit tests. Playwright
is the chosen toolchain because it ships its own test runner, supports browser
download assertions, and is natively TypeScript.

---

## 2. Installing Playwright

Playwright is **not included** in the default `npm install`. The E2E scaffold
(`e2e/golden-path.spec.ts` + `playwright.config.ts`) references `@playwright/test`
which must be installed before running:

```bash
npm install --save-dev @playwright/test
npx playwright install chromium
```

Do **not** add `@playwright/test` to the default test script (`npm test`). The
`vitest.config.ts` glob only picks up `__tests__/**/*.test.ts` — Playwright files
live under `e2e/` and are excluded automatically.

---

## 3. Environment variables

Create a `.env.test.e2e` file (gitignored) in the repo root:

```bash
# Target app URL (local dev or staging deployment)
E2E_BASE_URL=http://localhost:3000

# Seeded test users — created via /api/admin/users before running
E2E_USER_EMAIL=testuser_a@test.local
E2E_USER_PASSWORD=<set during seed>
E2E_ADMIN_EMAIL=testadmin@test.local
E2E_ADMIN_PASSWORD=<set during seed>

# Second user for isolation tests (GP-04, GP-05)
E2E_USER_B_EMAIL=testuser_b@test.local
E2E_USER_B_PASSWORD=<set during seed>

# Pre-seeded project owned by user_b (for GP-04 direct-URL check)
E2E_OTHER_PROJECT_ID=<UUID from seed>
```

Source the file before running:

```bash
export $(grep -v '^#' .env.test.e2e | xargs)
npx playwright test
```

---

## 4. DB seed (staging or local Docker)

The E2E tests require a pre-seeded database. The quickest path:

```bash
# Start local Supabase (requires Supabase CLI)
supabase start

# Apply the production schema bootstrap
psql "$LOCAL_DB_URL" -f supabase/bootstrap/supabase-bootstrap-from-prod.sql

# Create two test users via the running app's API
curl -s -X POST http://localhost:3000/api/admin/users \
  -H "Authorization: Bearer $ADMIN_JWT" \
  -H "Content-Type: application/json" \
  -d '{"first_name":"User","last_name":"A","email":"testuser_a@test.local","role_id":"consultant","password":"<your-password>"}'

curl -s -X POST http://localhost:3000/api/admin/users \
  -H "Authorization: Bearer $ADMIN_JWT" \
  -H "Content-Type: application/json" \
  -d '{"first_name":"User","last_name":"B","email":"testuser_b@test.local","role_id":"consultant","password":"<your-password>"}'
```

---

## 5. Running the golden-path tests

After prerequisites are met and tests are un-fixed (`test.fixme` → `test`):

```bash
npx playwright test                     # all tests
npx playwright test e2e/golden-path.spec.ts   # golden path only
npx playwright test --reporter=list     # detailed output
npx playwright show-report              # open HTML report
```

---

## 6. Golden-path definitions

| ID    | Title                                             | Priority | Status  |
|-------|---------------------------------------------------|----------|---------|
| GP-01 | Login → Projekt → Stoppuhr → Refresh (data survives) | P0   | fixme   |
| GP-02 | LSC Workshop — OEE erfassen + Bericht konsistent  | P0       | fixme   |
| GP-03 | Agenda erstellen → PDF + Excel Export             | P1       | fixme   |
| GP-04 | Nutzer ohne Rechte sieht/ändert nichts            | P1       | fixme   |
| GP-05 | User isolation — user B cannot see user A data    | P0       | fixme   |

All skeletons live in `e2e/golden-path.spec.ts`.

---

## 6a. Multi-QAF workflow (KAR-953)

`e2e/multi-qaf-workflow.spec.ts` — the Master-Prompt §22 15-step Multi-QAF
end-to-end flow (upload baseline + current Multi-QAF files → detection →
review matches → inspect container/variant/material/profile sections →
export → switch UI language → export again → reload and confirm
persistence). Same scaffold discipline as golden-path.spec.ts: `test.fixme`,
same env vars, same "not wired into any real DOM yet" convention for most
selectors — see that file's own header comment for the two selectors that
ARE real today (`qaf-multi-qaf-status-badge` / `qaf-multi-qaf-hero`) and for
two documented deviations from a literal reading of the §22 step list (the
Multi-QAF XLSX export is bilingual-inline, not two separate DE/EN export
actions; the language switch is the app-wide `lib/i18n` locale, not a
QAF-page-local toggle).

Needs one additional env var beyond golden-path's own set:

```bash
# Pre-seeded project the E2E user owns, used as the Multi-QAF upload target
E2E_MULTI_QAF_PROJECT_ID=<UUID from seed>
```

Fixture files: `e2e/fixtures/multi-qaf-baseline-v2.xlsx` /
`multi-qaf-current.xlsx` — synthetic (FIXTURE-DATEN-REGEL, same discipline as
`lib/qaf-differences/internal/multi-qaf/__tests__/golden-fixtures.ts`),
regenerate via `node e2e/fixtures/generate-multi-qaf-fixtures.mjs`.

```bash
npx playwright test e2e/multi-qaf-workflow.spec.ts
```

---

## 7. RLS live tests

User-scoped RLS verification (`__tests__/security/rls-user-scoped.test.ts`) requires
a Docker-Postgres 17 instance with the application's RLS policies active and **two
provisioned test users**. All assertions are `it.todo()` stubs until that
infrastructure is available.

### Minimum Docker setup

```bash
docker run -d \
  --name kadi-pg \
  -e POSTGRES_PASSWORD=testpassword \
  -p 5432:5432 \
  postgres:17

psql "postgresql://postgres:testpassword@localhost:5432/postgres" \
  -f supabase/bootstrap/supabase-bootstrap-from-prod.sql
```

### Required env vars for RLS tests

```bash
STAGING_SUPABASE_URL=http://localhost:54321
STAGING_SUPABASE_PUBLISHABLE_KEY=<anon key from local Supabase>
E2E_USER_A_ACCESS_TOKEN=<JWT from /auth/v1/token for user_a>
E2E_USER_B_ACCESS_TOKEN=<JWT from /auth/v1/token for user_b>
```

### Tables in scope

All 10 user-scoped tables listed in
`__tests__/security/rls-user-scoped.test.ts` must pass four assertions each
(SELECT, UPDATE, DELETE, INSERT as the wrong user).

---

## 8. CI integration

Do **not** add `npx playwright test` to the default CI pipeline until:
1. Staging Supabase URL + test credentials are available as CI secrets.
2. At least GP-01 and GP-04 are un-fixed and green on staging.

When ready, add a separate CI job:

```yaml
- name: E2E golden path
  run: npx playwright test
  env:
    E2E_BASE_URL: ${{ secrets.E2E_STAGING_URL }}
    E2E_USER_EMAIL: ${{ secrets.E2E_USER_EMAIL }}
    E2E_USER_PASSWORD: ${{ secrets.E2E_USER_PASSWORD }}
    # … etc
```
