test: Add E2E test framework with Playwright

feat: Basic Homepage elements
This commit is contained in:
2026-04-20 07:11:56 -04:00
parent 5c830443f3
commit d07a02c9dc
13 changed files with 625 additions and 32 deletions

View File

@@ -0,0 +1,66 @@
# Session Handoff: Playwright E2E Setup
**Date:** 2026-04-19
**Session Focus:** Set up Playwright E2E testing; write and pass auth flow tests
## What Was Accomplished
1. **Installed `@playwright/test` 1.59.1** + Chromium headless shell binary
2. **Created `playwright.config.ts`** — Pixel 5 viewport, `reuseExistingServer` for local dev, `github` reporter in CI, 30s timeout, 1 worker (serial)
3. **Created `tests/e2e/helpers/mailpit.ts`**`deleteAllMail()` and `getMagicLink(email)` against Mailpit at `http://127.0.0.1:54324`
4. **Created `tests/e2e/auth.spec.ts`** — 2 tests: full magic link flow + protected route redirect
5. **Fixed `supabase/config.toml`**`site_url` changed from `http://127.0.0.1:3000` to `http://localhost:3000`; `additional_redirect_urls` updated to include `http://localhost:3000/auth/callback` and `http://127.0.0.1:3000/auth/callback`
6. **Added scripts to `package.json`**: `test:e2e`, `test:e2e:ui`, `test:e2e:headed`
7. **Both tests pass: 2/2**
## Key Debugging Discoveries
| Problem | Root Cause | Fix |
|---------|-----------|-----|
| `getByRole('button', { name: 'Log In' })` not found | `IonButton` with `router-link` renders as `<a>` (role=`link`) | Changed to `getByRole('link', { name: 'Log In' })` |
| `getByLabel('Email address')` not found | `IonLabel` is not associated via `for`/`id` with `IonInput` | Changed to `getByPlaceholder('you@example.com')` |
| `page.goto(magicLink)``ERR_CONNECTION_REFUSED` to `127.0.0.1:54321` | Playwright's Chromium headless shell cannot reach Supabase local auth server directly | Use Node.js `fetch(magicLink, { redirect: 'manual' })` to follow redirect server-side; navigate browser to the resulting app callback URL |
| Callback URL was `/?code=` instead of `/auth/callback?code=` | `emailRedirectTo` not whitelisted in `supabase/config.toml`; Supabase fell back to `site_url` | Fixed `config.toml` redirect URLs; required `supabase stop && supabase start` |
## Ionic-Specific Playwright Patterns (confirmed working)
- `IonButton` with `router-link` → use `getByRole('link', { name: '...' })`
- `IonButton` without `router-link` → use `getByRole('button', { name: '...' })`
- `IonInput` → use `getByPlaceholder(...)` (label association not standard HTML)
- Never navigate browser directly to Supabase local auth URL — follow redirect server-side first
## Files Created or Modified
| File | Action |
|------|--------|
| `playwright.config.ts` | Created |
| `tests/e2e/helpers/mailpit.ts` | Created |
| `tests/e2e/auth.spec.ts` | Created |
| `supabase/config.toml` | Modified — site_url and redirect URLs |
| `package.json` | Modified — added test:e2e scripts |
## What the NEXT Session Should Do
**Option A — CI pipeline:**
1. Create `.gitea/workflows/build.yaml` — unit tests + build + E2E (read bab-app pipeline as reference)
2. Note: E2E in CI requires local Supabase running in the pipeline — confirm if feasible or skip E2E in CI for now
**Option B — Home page content:**
1. Implement authenticated home content in `app/pages/index.vue` (currently "Welcome to OYS Borrow a Boat" placeholder)
2. Likely a boat list or dashboard — check `docs/planning/` for persona requirements
## Open Questions
- [ ] Should E2E tests run in CI (requires Supabase in pipeline) or local-only? — OPEN
- [ ] What is the authenticated home content? Boat list, dashboard, or something else? — check planning docs
## Dev Environment Reference
```bash
# Required before running E2E:
DOCKER_HOST=unix:///run/user/1000/podman/podman.sock npx supabase start
# Run E2E:
yarn test:e2e # headless
yarn test:e2e:headed # visible browser
yarn test:e2e:ui # Playwright UI mode
```