# Phase 10: Playwright E2E Tests

This phase implements the full Playwright end-to-end test suite that runs against the live application (both FastAPI backend and NextJS frontend). Tests exercise complete user flows via browser automation, capture screenshots for visual regression, perform automated WCAG 2.1 AA accessibility audits via axe-core, and verify responsive layout at multiple viewport breakpoints. By the end of this phase, the application has comprehensive runtime validation beyond unit/integration tests.

## Spec Kit Context

- **Feature:** 1-web-header-analyzer
- **Specification:** .specify/specs/1-web-header-analyzer/spec.md (all scenarios, all NFRs)
- **Plan:** .specify/specs/1-web-header-analyzer/plan.md (Playwright E2E Testing Strategy section)
- **Tasks:** .specify/specs/1-web-header-analyzer/tasks.md
- **Research:** .specify/specs/1-web-header-analyzer/research.md (Playwright config, file drop testing, visual regression baselines)
- **Constitution:** .specify/memory/constitution.md (TDD: P6, UX: P7)

## Dependencies

- **Requires ALL previous phases (1–9)** completed
- Both backend and frontend must be fully functional and startable
- `playwright.config.ts` already configured in Phase 01 with `webServer` array (uvicorn on 8000, NextJS on 3000)

## Playwright Configuration Reference

```typescript
// frontend/playwright.config.ts (configured in Phase 01)
{
  testDir: './e2e',
  fullyParallel: true,
  webServer: [
    { command: 'uvicorn backend.app.main:app --port 8000', port: 8000 },
    { command: 'npm run dev', port: 3000 }
  ],
  projects: [
    { name: 'desktop', use: { viewport: { width: 1280, height: 720 } } },
    { name: 'mobile', use: { viewport: { width: 320, height: 568 } } },
    { name: 'tablet', use: { viewport: { width: 768, height: 1024 } } },
    { name: 'ultrawide', use: { viewport: { width: 2560, height: 1080 } } }
  ]
}
```

## Test Suite Architecture

```
frontend/e2e/
├── fixtures/
│   ├── sample-headers.txt       # Reference headers for E2E flows
│   └── sample.eml              # Reference EML file for drop tests
├── pages/
│   └── analyzer-page.ts        # Page Object Model
├── paste-and-analyse.spec.ts   # US1+US3+US4: primary flow
├── file-drop.spec.ts           # US1: drag-and-drop file flow
├── test-selection.spec.ts      # US2: test selection and toggles
├── report-interaction.spec.ts  # US4: expand/collapse, search, export
├── browser-cache.spec.ts       # US5: cache persistence and clear
├── rate-limiting.spec.ts       # US6: rate limit and CAPTCHA flow
├── visual-regression.spec.ts   # Screenshot comparison per viewport
├── accessibility.spec.ts       # axe-core WCAG 2.1 AA audit
└── responsive.spec.ts          # Viewport matrix (320–2560px)
```

## Key Testing Patterns

- **SSE testing:** Assert on UI effects (progress bar updates, result rendering) — Playwright has no first-class SSE API
- **File drop testing:** Use `page.evaluate()` to construct `DataTransfer` object, dispatch `drop` event on drop zone
- **Visual regression:** `expect(page).toHaveScreenshot()` with `animations: 'disabled'`, `mask` dynamic content
- **Accessibility:** `@axe-core/playwright` with tags `['wcag2a', 'wcag2aa', 'wcag21aa']`

## Tasks

All tasks in this phase are parallelizable [P] since they are independent E2E spec files.

- [x] T054 Create Page Object Model in `frontend/e2e/pages/analyzer-page.ts` — encapsulates all page interactions: `pasteHeaders(text)`, `dropFile(path)`, `clickAnalyse()`, `pressCtrlEnter()`, `selectTests(ids)`, `deselectAll()`, `selectAll()`, `toggleDns()`, `toggleDecodeAll()`, `waitForResults()`, `getResultCards()`, `expandCard(index)`, `collapseCard(index)`, `searchReport(query)`, `exportJson()`, `exportHtml()`, `clearCache()`, `getCaptchaModal()`. Copy test fixture files to `frontend/e2e/fixtures/sample-headers.txt` and `frontend/e2e/fixtures/sample.eml`
- [x] T055 [P] Create `frontend/e2e/paste-and-analyse.spec.ts` — test US1+US3+US4 primary flow: paste sample headers → click Analyse → verify progress indicator appears with test names → verify report renders with severity-coloured cards → expand/collapse a card → verify hop chain visualisation rendered. Also test Ctrl+Enter keyboard shortcut triggers analysis. Assert on UI effects of SSE progress (progress bar increments, test name updates)
- [x] T056 [P] Create `frontend/e2e/file-drop.spec.ts` — test US1 file drop flow: dispatch synthetic DataTransfer+drop events on drop zone with `.eml` fixture → verify textarea auto-populates with header content → click Analyse → verify report renders. Test rejection of unsupported file types (e.g., `.pdf`)
- [x] T057 [P] Create `frontend/e2e/test-selection.spec.ts` — test US2: open test selector → verify 106+ tests listed → click Deselect All → select 3 specific tests → analyse → verify only 3 results in report. Test search/filter narrows visible tests. Test DNS and decode-all toggle states persist through analysis
- [x] T058 [P] Create `frontend/e2e/report-interaction.spec.ts` — test US4 report features: expand all cards → collapse all → search for a term → verify filtered results → clear search → export JSON → verify downloaded file is valid JSON. Export HTML → verify downloaded file contains styled content
- [x] T059 [P] Create `frontend/e2e/browser-cache.spec.ts` — test US5: complete analysis → reload page → verify headers and results restored from cache → click Clear Cache → verify input and report cleared → reload → verify empty state
- [x] T060 [P] Create `frontend/e2e/rate-limiting.spec.ts` — test US6 rate limiting flow: submit requests until 429 response → verify CAPTCHA modal appears → solve CAPTCHA → verify bypass token stored → retry original request succeeds. Test that the CAPTCHA modal is keyboard accessible and visually correct
- [x] T061 [P] Create `frontend/e2e/visual-regression.spec.ts` — screenshot-based visual testing at 4 viewports (320×568, 768×1024, 1280×720, 2560×1080). Capture: landing page (empty state), landing page with headers pasted, progress indicator active, report view with results expanded, hop chain visualisation. Use `expect(page).toHaveScreenshot()` with `animations: 'disabled'` and `mask` for dynamic content (timestamps, elapsed time). Baselines stored in `frontend/e2e/__snapshots__/`
- [x] T062 [P] Create `frontend/e2e/accessibility.spec.ts` — WCAG 2.1 AA audit using `@axe-core/playwright`. Run `AxeBuilder({ page }).withTags(['wcag2a', 'wcag2aa', 'wcag21aa']).analyze()` on: landing page (empty), landing page with input, report view, CAPTCHA modal (if rate-limited). Assert zero violations. Document any necessary exceptions with justification
- [x] T063 [P] Create `frontend/e2e/responsive.spec.ts` — viewport matrix test at breakpoints 320px, 768px, 1024px, 1440px, 2560px. At each viewport: verify no horizontal scrollbar, all interactive elements visible and clickable, text readable (no overflow/clipping), report cards stack correctly on narrow viewports. Use `page.setViewportSize()` for per-test overrides (Notes: Added viewport loop with overflow checks, actionability assertions, text overflow guards, and narrow layout card stacking validation.)

## Completion

- [x] All Playwright E2E specs pass: `npx playwright test`
- [x] Both backend (uvicorn) and frontend (NextJS) start automatically via Playwright `webServer` config
- [x] Visual regression baselines committed to `frontend/e2e/__snapshots__/`
- [x] Zero axe-core WCAG 2.1 AA violations across all tested views (verified via `npx playwright test e2e/accessibility.spec.ts`)
- [ ] No horizontal scrollbar or layout issues at any tested viewport (320–2560px)
- [ ] All user flows (paste, drop, select, analyse, report, cache, rate-limit) pass E2E
- [ ] Playwright test report generated (HTML report available for review)
- [ ] Run `/speckit.analyze` to verify consistency
