// Idle-poll audit. User explicitly complained "way too many GETs / non-stop". // For each scene: visit, settle, then watch network for 30s with no user input. // Pass if total requests in that 30s window is reasonable (<= 5). // The topbar identity-hydration + chat/queue badge polls at 60s, so a 30s // window should see at most 1 such fire. import { chromium } from "playwright"; const URL = "https://canvas.flow-master.ai/"; const args = ["--host-resolver-rules=MAP canvas.flow-master.ai 65.21.71.186", "--ignore-certificate-errors"]; const SCENES = [ { chip: null, label: "landing" }, { chip: /Approvals queue/, label: "approvals" }, { chip: /^Documents$/, label: "documents" }, { chip: /Procurement Hub/, label: "procurement_hub" }, { chip: /Attendance Map/, label: "geo" }, { chip: /Command Assistant/, label: "assistant" }, { chip: /Team Chat/, label: "chat" }, { chip: /What is FlowMaster/, label: "explainer" }, ]; const IDLE_WINDOW_MS = 30_000; const MAX_REQ_PER_WINDOW = 5; const results = []; function record(name, ok, detail = "") { results.push({ name, ok, detail }); console.log(`${ok ? "PASS" : "FAIL"} ${name}${detail ? " — " + detail : ""}`); } const b = await chromium.launch({ headless: true, args }); const ctx = await b.newContext({ viewport: { width: 1440, height: 900 } }); const p = await ctx.newPage(); await p.goto(URL, { waitUntil: "networkidle" }); await p.waitForTimeout(800); await p.locator(".persona-chip", { hasText: /Mariana/ }).click(); await p.locator(".dev-login-btn").click(); await p.waitForSelector(".hero-actions", { timeout: 15000 }); await p.waitForFunction(() => document.querySelectorAll(".hub-chip").length >= 8, undefined, { timeout: 15000 }).catch(() => {}); for (const s of SCENES) { if (s.chip) { await p.goto(URL, { waitUntil: "networkidle" }).catch(() => {}); await p.waitForSelector(".hub-chip", { timeout: 15000 }).catch(() => {}); await p.locator(".hub-chip", { hasText: s.chip }).click().catch(() => {}); await p.waitForTimeout(2500); } // Settle period — the scene's initial fetch burst should complete here. await p.waitForLoadState("networkidle").catch(() => {}); await p.waitForTimeout(1500); // Now record every request fired for the next IDLE_WINDOW_MS. const requests = []; const onReq = (req) => { const u = req.url(); if (/\/api\/|\/internal\//.test(u)) { requests.push({ method: req.method(), url: u.replace("https://canvas.flow-master.ai", "") }); } }; p.on("request", onReq); await p.waitForTimeout(IDLE_WINDOW_MS); p.off("request", onReq); const ok = requests.length <= MAX_REQ_PER_WINDOW; const summary = requests.length ? `${requests.length} reqs · ${requests.slice(0, 3).map((r) => `${r.method} ${r.url.slice(0, 50)}`).join(", ")}${requests.length > 3 ? "…" : ""}` : "0 reqs · quiet"; record(`idle_${s.label}_quiet_at_30s`, ok, summary); } await b.close(); const fails = results.filter((r) => !r.ok); console.log(`\n=== idle audit: ${results.length - fails.length}/${results.length} passed ===`); if (fails.length) { console.log("FAILED:"); fails.forEach((f) => console.log(` - ${f.name}: ${f.detail}`)); process.exit(1); }