7 Commits

Author SHA1 Message Date
812131df4b feat: live timing waterfall with TTFB, DNS, TLS, TCP, sending, receiving
Backend:
- Track all k6 HTTP phase metrics via PHASE_MAP in ingestPoint:
  http_req_blocked (DNS+wait), http_req_connecting, http_req_tls_handshaking,
  http_req_sending, http_req_waiting (TTFB), http_req_receiving
- Compute avg + p95 per phase in computeLiveMetrics, broadcast every second
- parseSummary now captures all trend metrics with generic trendRe()

Frontend:
- Live waterfall bar chart updates every second during the test
- Each phase has a distinct colour: indigo/sky/purple/emerald/amber/blue
- Bar width = phase avg as % of total request time
- TTFB p95 + p99 shown below the waterfall
- Bars animate smoothly with CSS transitions
- Waterfall resets cleanly on new test start

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-01 20:47:03 +02:00
d3991416e8 feat: live bandwidth tracking (RX/TX MB/s + avg response size)
- Track data_received / data_sent bytes in live metric aggregation
- Compute bwInMBps, bwOutMBps, avgRespKB per second
- Bandwidth row below stats strip: ↓ RX | ↑ TX | Avg size
- RX colour: green <20 MB/s, yellow 20-50 MB/s, red >50 MB/s
- Warning banner when RX >20 MB/s: bandwidth may cause p99 spikes

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-01 20:39:16 +02:00
175ba3ec7a feat: animated live gauge circles (PageSpeed-style)
Backend:
- Re-add --out json=- but properly route: JSON lines → metric
  aggregation, non-JSON lines → text log (summary text lands in log)
- Aggregate http_req_duration / http_reqs / http_req_failed / checks
  per test into live state (capped 50k samples)
- Broadcast { metrics: {...} } SSE events every second with
  score, checksRate, httpOkRate, p90/p95/p99, req/s etc.
- computeScore() composite 0-100 based on p95 + error rate

Frontend:
- 3 animated SVG ring gauges: Score (/100), Checks OK (%), HTTP OK (%)
- Smooth CSS transition on stroke-dashoffset (0.7s cubic-bezier)
- Pulse animation while test is live, stops on completion
- Color: green ≥90/98/99, yellow mid-range, red below thresholds
- Stats strip: Requests, Req/s, Avg, p(90), p(95), p(99)
- p(95) cell color-coded green/yellow/red vs latency
- Threshold pass/fail banner at bottom of gauges panel
- Raw output collapsed in <details> by default
- History items show mini score ring gauge (44px) inline
- History detail expands 3 medium gauges + stat grid

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-01 20:24:59 +02:00
cf51a4620b feat: add desktop/mobile device toggle (User-Agent)
- Segmented Desktop / Mobile button in the form
- Desktop: Chrome 124 on Windows
- Mobile: iPhone Safari 17 (iOS 17.4)
- User-Agent injected into k6 script headers
- Stored in DB with migration for existing data
- History items show device pill alongside cache/gzip

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-01 20:13:13 +02:00
6ef7564e87 feat: add gzip toggle and cache mode (normal / no-cache / bust)
- Cache-mode selector: Normal, No-cache headers, Cache-bust URL+headers
- Cache-bust appends random ?_cb= per iteration to bypass CDN/proxy
- gzip toggle: on = k6 default (Accept-Encoding: gzip/br), off = identity
- Both options stored in DB with non-destructive migration
- History items show cache-mode and gzip pills
- Schema migration handles existing DBs gracefully

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-01 20:03:36 +02:00
0cd0f96bab fix: broadcast k6 stdout summary and show full stats
- Remove --out json=- (was flooding stdout and hiding summary)
- Broadcast both stdout (summary table) and stderr (live warnings)
- Add --summary-trend-stats with p(90)/p(95)/p(99)
- Parse checks, failed count/total, data received, all percentiles
- Strip ANSI codes before regex matching
- Add threshold pass/fail banner with per-threshold status
- Show all duration percentiles as individual cards

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-01 19:46:39 +02:00
71d3faa36c feat: k6 load testing web UI with Docker
- Multi-stage Dockerfile builds k6 from source (grafana/k6)
- Express backend with SSE live output streaming
- SQLite-backed test history with delete support
- Frontend: URL input, VUs, duration, RPS limit, custom headers
- Persisted via Docker volume, listens on port 8118

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-01 19:36:21 +02:00