# Test — Bundle Size, FCP, & Annotation Session Memory Soak

**Task**: AZ-479_test_bundle_fcp_soak
**Name**: Bundle ≤ 2 MB gzipped + mission-planner excluded + FCP ≤ 3 s + 30-min annotation soak
**Description**: Implement the 4 blackbox tests covering the production-bundle budget, the mission-planner exclusion canary, the First-Contentful-Paint budget on `/flights`, and the 30-minute annotation-session memory soak.
**Complexity**: 3 points
**Dependencies**: AZ-456_test_infrastructure
**Component**: 00_foundation (build) + 10_app-shell (FCP) + 06_annotations (memory) (Blackbox Tests)
**Tracker**: AZ-479
**Epic**: AZ-455

## Problem

The 2 MB gzipped budget (NFT-PERF-01 / NFT-RES-LIM-01) bounds first-load on edge hardware. The mission-planner workspace is intentionally excluded from the prod bundle (NFT-RES-LIM-04) — a regression that re-includes it doubles the bundle. FCP ≤ 3 s on `/flights` (NFT-PERF-10) is the user-perceived latency target. The 30-minute annotation soak (NFT-RES-LIM-05) catches slow heap creep that 1-hour live-GPS soak (T08) does not catch on the annotation surface.

## Outcome

- 4 scenarios pass.

## Scope

### Included

| Scenario | Profile | Source file | results_report row |
|----------|---------|-------------|--------------------|
| NFT-PERF-01 — Initial JS bundle ≤ 2 MB gzipped | static | performance-tests.md | per NFT-PERF-01 |
| NFT-RES-LIM-04 — `mission-planner/` is excluded from production bundle | static | resource-limit-tests.md | per NFT-RES-LIM-04 |
| NFT-PERF-10 — FCP on `/flights` ≤ 3 s | e2e | performance-tests.md | 98 |
| NFT-RES-LIM-05 — SPA memory stable across 30-minute annotation session | e2e (long-running) | resource-limit-tests.md | per NFT-RES-LIM-05 |

### Excluded

- Per-route lazy-chunk budgets (out of scope for the baseline).
- Live-GPS 1-hour soak + 100-flight-selection soak (covered in 08_test_flight_selection_persistence).

## Acceptance Criteria

**AC-1: Bundle budget**
NFT-PERF-01 / NFT-RES-LIM-01 — `bun run build` produces `dist/`; sum of gzipped JS in initial chunks ≤ 2 MB. Static check runs after build.

**AC-2: Mission-planner exclusion**
NFT-RES-LIM-04 — no chunk in `dist/` references `mission-planner/` source; ripgrep static check returns no hits in built JS.

**AC-3: FCP budget**
NFT-PERF-10 — Playwright `performance.getEntriesByName('first-contentful-paint')` on `/flights` reports ≤ 3000 ms median over 5 runs on the configured mid-range CPU throttle (4x slowdown per the test env).

**AC-4: Annotation memory soak**
NFT-RES-LIM-05 — 30-minute annotation session: load 50 media items, annotate each, navigate dataset; heap at t=1800 s within 10% of heap at t=60 s.

## System Under Test Boundary

- System under test: built `dist/` artefacts (AC-1 / AC-2); the running SPA in Chromium (AC-3 / AC-4).
- Allowed stubs: MSW / suite services as needed for the e2e tests.
- Disallowed: hand-tuning the bundle to "fit" or excluding files from build for the test.

## Constraints

- AC-3 / AC-4 require Chromium-only (Firefox lacks `performance.memory`); soak tagged `@long-running`.
- Bundle measurement uses the gzip size, not the raw bytes — matches NFT-PERF-01 contract.

## Risks & Mitigation

**Risk 1 — FCP flakiness from cold-cache state**
- *Risk*: First navigation to `/flights` includes auth handshake and SSE setup, inflating FCP.
- *Mitigation*: the test issues a warmup navigation, then measures FCP on the second navigation; warmup is recorded in the CSV but does not gate.
