- /stammbaum/+page.server.ts loads GET /api/network (already filtered
to family members on the backend) and returns nodes + edges.
- +page.svelte holds the page shell, manages selectedId (with
?focus={id} deep-link support) and zoom state, renders the empty
state when nodes.length === 0 (icon + heading + body + link to
/persons), or the tree + side panel otherwise.
- StammbaumTree.svelte: BFS-based generation assignment from roots,
spouses promoted to the deeper generation so couples sit on the same
row, alphabetical sort within row, simple grid layout. SVG nodes are
role="button" + aria-label="{name}, {birth}–{death}" +
aria-expanded={selected}, with click + Enter/Space activation. Solid
parent→child connectors; mint spouse line with midpoint circle, dashed
if SPOUSE_OF.toYear is set (former spouse). Zoom maps to viewBox.
- StammbaumSidePanel.svelte: lazily loads
/api/persons/{id}/relationships and /inferred-relationships when the
selection changes; shows direct chips (mint), top-5 derived chips
(grey), and a "Zur Personenseite →" link. Escape closes the panel.
Refs #358.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
142 lines
5.1 KiB
Markdown
142 lines
5.1 KiB
Markdown
# E2E Tests — Familienarchiv
|
|
|
|
## Overview
|
|
|
|
End-to-end tests for the Familienarchiv frontend using Playwright. These tests verify complete user flows across the full stack (SvelteKit frontend + Spring Boot backend + PostgreSQL + MinIO).
|
|
|
|
## Tech Stack
|
|
|
|
- **Test Runner**: Playwright (`@playwright/test`)
|
|
- **Browser**: Chromium (desktop)
|
|
- **Locale**: `de-DE` (ensures German language detection)
|
|
- **Auth**: Shared session cookie stored after setup
|
|
|
|
## Project Structure
|
|
|
|
```
|
|
frontend/e2e/
|
|
├── auth.setup.ts # Authentication setup — logs in and saves session
|
|
├── auth.spec.ts # Authentication flows (login, logout, register)
|
|
├── admin.spec.ts # Admin panel CRUD operations
|
|
├── annotations.spec.ts # Document annotation features
|
|
├── bottom-panel.spec.ts # Bottom panel / transcription panel
|
|
├── dashboard-*.spec.ts # Dashboard variants and screenshots
|
|
├── documents.spec.ts # Document upload, edit, search
|
|
├── focus-rings.spec.ts # Accessibility focus ring tests
|
|
├── header.spec.ts # Navigation header
|
|
├── history.spec.ts # Chronik / activity feed
|
|
├── korrespondenz.spec.ts # Correspondence timeline
|
|
├── lang.spec.ts # Language switching
|
|
├── password-reset.spec.ts # Password reset flow
|
|
├── permissions.spec.ts # Role-based access control
|
|
├── persons.spec.ts # Person directory CRUD
|
|
├── profile.spec.ts # User profile
|
|
├── theme.spec.ts # Dark/light mode
|
|
├── transcription.spec.ts # Transcription workflows
|
|
├── accessibility.spec.ts # Axe accessibility scans
|
|
├── fixtures/ # Test data fixtures
|
|
└── helpers/ # Test helper utilities
|
|
```
|
|
|
|
## Authentication Strategy
|
|
|
|
Tests share auth state via a stored session cookie:
|
|
|
|
1. **Setup** (`auth.setup.ts`): Logs in with test credentials and saves `storageState` to `e2e/.auth/user.json`
|
|
2. **Tests**: All test projects depend on `setup` and reuse the stored session
|
|
|
|
This avoids re-logging in for every test, but means tests **must run sequentially** (`fullyParallel: false`, `workers: 1`).
|
|
|
|
## Configuration
|
|
|
|
Config lives in `frontend/playwright.config.ts`:
|
|
|
|
| Setting | Value | Notes |
|
|
| --------------- | ----------------------- | ------------------------------ |
|
|
| `testDir` | `./e2e` | Test file location |
|
|
| `fullyParallel` | `false` | Shared auth state |
|
|
| `workers` | `1` | Sequential execution |
|
|
| `screenshot` | `'on'` | Always capture |
|
|
| `video` | `'retain-on-failure'` | Keep on failure |
|
|
| `trace` | `'retain-on-failure'` | Keep on failure |
|
|
| `baseURL` | `http://localhost:3000` | Overridable via `E2E_BASE_URL` |
|
|
|
|
The `webServer` config auto-starts `npm run dev -- --port 3000` if no server is detected at the base URL.
|
|
|
|
## How to Run
|
|
|
|
### Prerequisites
|
|
|
|
The full stack must be running (or the `webServer` config will start the frontend dev server):
|
|
|
|
```bash
|
|
# Start infrastructure
|
|
docker-compose up -d
|
|
|
|
# Ensure backend is healthy
|
|
curl http://localhost:8080/actuator/health
|
|
```
|
|
|
|
### Run E2E Tests
|
|
|
|
```bash
|
|
cd frontend
|
|
|
|
# Headless (CI mode)
|
|
npm run test:e2e
|
|
|
|
# With visible browser
|
|
npm run test:e2e:headed
|
|
|
|
# Interactive UI mode
|
|
npm run test:e2e:ui
|
|
|
|
# Run a specific test file
|
|
npx playwright test documents.spec.ts
|
|
|
|
# Run with a different base URL (e.g., docker frontend on 5173)
|
|
E2E_BASE_URL=http://localhost:5173 npx playwright test
|
|
```
|
|
|
|
## Writing New E2E Tests
|
|
|
|
1. Create a new `.spec.ts` file in `frontend/e2e/`
|
|
2. Use the shared auth state (no manual login needed)
|
|
3. Use page object patterns or helper functions from `helpers/`
|
|
4. Add `test-data-id` attributes to components for stable selectors
|
|
5. Run with `--debug` or `--ui` to troubleshoot
|
|
|
|
### Example Test Pattern
|
|
|
|
```typescript
|
|
import { test, expect } from '@playwright/test';
|
|
|
|
test('user can create a document', async ({ page }) => {
|
|
await page.goto('/documents/new');
|
|
await page.getByTestId('document-title').fill('Test Document');
|
|
await page.getByTestId('save-button').click();
|
|
await expect(page).toHaveURL(/\/documents\/[^/]+$/);
|
|
});
|
|
```
|
|
|
|
## Accessibility Testing
|
|
|
|
`accessibility.spec.ts` runs Axe scans on key pages. Violations fail the test.
|
|
|
|
```bash
|
|
npx playwright test accessibility.spec.ts
|
|
```
|
|
|
|
## Troubleshooting
|
|
|
|
| Issue | Solution |
|
|
| --------------------- | ---------------------------------------- |
|
|
| Auth failures | Delete `e2e/.auth/user.json` and re-run |
|
|
| Backend not reachable | Ensure `docker-compose up -d` is running |
|
|
| Flaky tests | Increase timeout or add explicit waits |
|
|
| Screenshots missing | Check `test-results/e2e/` |
|
|
|
|
## CI Integration
|
|
|
|
E2E tests are **not** currently run in CI (the pipeline stops at unit/component tests). To add them, extend `infra/gitea/workflows/ci.yml` with a Playwright job that starts the full Docker Compose stack first.
|