web/scripts: a probe fails on any knot read a prerendered page makes
Signed-off-by: dawn <90008@klbr.net>
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748// loads prerendered pages and fails on any read of the knot's xrpc: the prerender inlined// every answer the page's first load asks for, so hydrating it, and hovering the board's kind// chips (which filter in place), reads nothing.// same env as icon-align.ts: node scripts/hydration-reads.tsimport { chromium, type Page } from "playwright";import { app, at, pull, repo, tickets, user, type ProbePage } from "./probePages.ts";
const hoverKinds = async (page: Page) => { for (const chip of await page .getByRole("group", { name: "ticket kind" }) .getByRole("link") .all()) await chip.hover(); await page.waitForTimeout(1000);};
const pages: ProbePage[] = [ { name: "repo front", url: at(app, repo) }, { name: "board", url: tickets }, { name: "board, kinds hovered", url: tickets, open: hoverKinds }, { name: "pull", url: pull }, { name: "user", url: user }];
const browser = await chromium.launch();const page = await browser.newPage({ viewport: { width: 1280, height: 900 } });let failed = 0;for (const { name, url, open } of pages) { if (!url) continue; const reads: string[] = []; // the knot's own reads, not a spindle's live pipelines const listen = (request: { url: () => string }) => { const { origin, pathname } = new URL(request.url()); if (origin === new URL(url).origin && pathname.startsWith("/xrpc/")) reads.push(pathname.slice("/xrpc/".length)); }; page.on("request", listen); await page.goto(url, { waitUntil: "networkidle" }); await open?.(page); page.off("request", listen); failed += Number(reads.length > 0); console.log(`${reads.length ? "FAIL" : "ok "} ${name.padEnd(22)} ${reads.join(" ")}`);}await browser.close();if (failed) { console.error(`${failed} page(s) read the knot after their html`); process.exit(1);}