import assert from "node:assert/strict"; import { test } from "bun:test"; import { createCloudApiServer } from "./server.ts"; import { createWebPerformanceStore, webPerformanceRouteTemplate } from "./web-performance.ts"; test("web performance store aggregates browser-perceived durations as Prometheus histograms", () => { const store = createWebPerformanceStore({ env: { HWLAB_METRICS_NAMESPACE: "hwlab-v02", HWLAB_GITOPS_TARGET: "v02" } }); const result = store.record({ schemaVersion: "hwlab-web-performance-v1", page: "/workspace", events: [ { kind: "web_vital", metric: "lcp", route: "/workspace", valueMs: 1234 }, { kind: "web_vital", metric: "cls", route: "/workspace", value: 0.08 }, { kind: "api", metric: "api_request", route: "/v1/agent/chat/result/trc_secret", method: "GET", status: 200, statusClass: "2xx", outcome: "ok", valueMs: 420 } ] }); const text = store.metricsText(); assert.deepEqual(result, { accepted: 3, dropped: 0, received: 3 }); assert.match(text, /hwlab_webui_performance_sample_total\{service="hwlab-cloud-web",namespace="hwlab-v02",gitops_target="v02",kind="web_vital",metric="lcp",route="\/workspace"/u); assert.match(text, /hwlab_webui_performance_duration_seconds_bucket\{[^}]*metric="api_request"[^}]*route="\/v1\/agent\/chat\/result\/:id"[^}]*le="0\.5"\} 1/u); assert.match(text, /hwlab_webui_layout_shift_score_bucket\{[^}]*metric="cls"[^}]*le="0\.1"\} 1/u); assert.doesNotMatch(text, /trc_secret|sessionId|conversationId|threadId|prompt|api key/iu); }); test("web performance route templates keep metrics low-cardinality", () => { assert.equal(webPerformanceRouteTemplate("/v1/workbench/workspace/cnv_abcdef/select-conversation?traceId=trc_secret"), "/v1/workbench/workspace/:id/select-conversation"); assert.equal(webPerformanceRouteTemplate("#/skills"), "/skills"); }); test("cloud api ingests WebUI performance samples and exposes metrics only on loopback host", async () => { const server = createCloudApiServer({ env: { HWLAB_METRICS_NAMESPACE: "hwlab-v02", HWLAB_GITOPS_TARGET: "v02" } }); await new Promise((resolve) => server.listen(0, "127.0.0.1", resolve)); try { const address = server.address(); assert.ok(address && typeof address === "object"); const baseUrl = `http://127.0.0.1:${address.port}`; const ingest = await fetch(`${baseUrl}/v1/web-performance`, { method: "POST", headers: { "content-type": "application/json" }, body: JSON.stringify({ schemaVersion: "hwlab-web-performance-v1", page: "/workspace", events: [{ kind: "web_vital", metric: "lcp", route: "/workspace", valueMs: 900 }] }) }); assert.equal(ingest.status, 202); const metrics = await fetch(`${baseUrl}/v1/web-performance/metrics`); const text = await metrics.text(); assert.equal(metrics.status, 200); assert.match(text, /hwlab_webui_performance_duration_seconds_bucket\{[^}]*metric="lcp"/u); const publicHost = await fetch(`${baseUrl}/v1/web-performance/metrics`, { headers: { host: "74.48.78.17:19667" } }); assert.equal(publicHost.status, 404); } finally { await new Promise((resolve, reject) => server.close((error) => error ? reject(error) : resolve())); } });