Slice 2 of 3 from #277. Depends on the harness from #385 (the E2E smoke slice) — this reuses its project, its cast fixture and its browser resolution.
What this measures, and why k6 cannot
#243 gives server-side percentiles at the protocol level, with no browser in the loop. This slice runs 1–2 Playwright browsers concurrently with the k6 load and captures what only a real browser can see:
- Core Web Vitals — LCP, INP, CLS.
- Page-load timing under a saturated backend.
- Asset loading (the hashed bundles, fonts, icons — anything the SW precaches).
- Visual correctness while the backend is saturated — a screen that renders an error state, an empty table, or a spinner that never resolves is a real regression even when the server's own percentiles look healthy.
Playwright is never the load generator. 1–2 browsers is a canary, not a crowd; k6 stays the crowd. A canary that adds meaningful load would change the number it exists to observe.
Metrics sink (settled with the owner: both)
Acceptance
Tracked in epic #15, under #277.
Slice 2 of 3 from #277. Depends on the harness from #385 (the E2E smoke slice) — this reuses its project, its cast fixture and its browser resolution.
What this measures, and why k6 cannot
#243 gives server-side percentiles at the protocol level, with no browser in the loop. This slice runs 1–2 Playwright browsers concurrently with the k6 load and captures what only a real browser can see:
Playwright is never the load generator. 1–2 browsers is a canary, not a crowd; k6 stays the crowd. A canary that adds meaningful load would change the number it exists to observe.
Metrics sink (settled with the owner: both)
tools/simulation/findings/(rendered fromTEMPLATE.mdbyrun-baseline.sh), so the browser experience sits beside the server percentiles from the same run. That adjacency is the entire point of running them concurrently; two separate documents would leave the correlation to the reader.Acceptance
Tracked in epic #15, under #277.