// usage: node shoot.mjs OUT_DIR QUERY_ID import { chromium } from "playwright"; const [outDir, queryId] = process.argv.slice(2); const BASE = "http://127.0.0.1:18080"; const PAGES = [ ["overview", "/overview?period=24h"], ["activity", "/activity"], ["query-detail", `/activity/queries/${queryId}`], ["clients", "/clients"], ["diagnostics", "/diagnostics"], ]; async function settle(page) { await page.waitForLoadState("networkidle").catch(() => {}); await page.waitForFunction( () => !document.querySelector('[aria-busy="true"], [role="progressbar"]'), null, { timeout: 15000 }, ).catch(() => console.log(" still busy after 15s")); await page.waitForTimeout(2500); } const browser = await chromium.launch(); for (const scheme of ["light", "dark"]) { const context = await browser.newContext({ viewport: { width: 1440, height: 900 }, deviceScaleFactor: 2, colorScheme: scheme, timezoneId: "Europe/Paris", locale: "en-GB", }); const page = await context.newPage(); page.on("console", (m) => m.type() === "error" && console.log(` console error: ${m.text()}`)); await page.goto(`${BASE}/login`); await page.locator("#password").fill("nxdns-demo"); await page.locator('button[type="submit"]').click(); await page.waitForURL((u) => !u.pathname.startsWith("/login")); for (const [name, path] of PAGES) { await page.goto(BASE + path); await page.mouse.move(1430, 890); await settle(page); if (name === "activity") await page.waitForTimeout(8000); const file = `${outDir}/${name}-${scheme}.png`; await page.screenshot({ path: file }); console.log(file); } await context.close(); } await browser.close();