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>
- 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>
- 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>
- 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>
- 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>