import { chromium } from "playwright"; import { mkdirSync } from "node:fs"; const BASE = process.env.QA_BASE ?? "http://localhost:3111"; const OUT = "runs/qa"; mkdirSync(OUT, { recursive: true }); const browser = await chromium.launch(); const page = await browser.newPage({ viewport: { width: 1440, height: 900 } }); async function shot(name, { fullPage = false } = {}) { await page.waitForTimeout(350); await page.screenshot({ path: `${OUT}/${name}.png`, fullPage }); console.log(`✓ ${name}`); } console.log("console errors will be collected at the end"); const errors = []; page.on("console", (msg) => { if (msg.type() === "error") errors.push(msg.text().slice(0, 200)); }); page.on("pageerror", (err) => errors.push(`PAGEERROR: ${String(err).slice(0, 200)}`)); await page.goto(`${BASE}/streams`); await shot("01-streams"); await page.keyboard.press("j"); await page.keyboard.press("j"); await page.keyboard.press("j"); await shot("02-streams-selected"); await page.keyboard.press("r"); await shot("03-streams-repost-toast"); await page.keyboard.press("q"); await shot("04-streams-quote-popover"); await page.keyboard.press("Escape"); await page.keyboard.press("j"); await page.keyboard.press("k"); await page.keyboard.press("k"); await shot("05-streams-keyboard-moved"); await page.goto(`${BASE}/compose`); await page.locator(".ProseMirror").click(); await page.keyboard.type("Shipping the visual QA pass — capability-gated amplify, keyboard-first streams."); await shot("06-compose-typed"); await page.goto(`${BASE}/connections`); await shot("07-connections"); await page.goto(`${BASE}/inbox`); await shot("08-inbox"); await page.goto(`${BASE}/team`); await shot("09-team"); await page.goto(`${BASE}/audit`); await shot("10-audit"); await page.locator("tr", { hasText: "credential.rotated" }).first().click(); await shot("11-audit-diff-open"); await page.goto(`${BASE}/onboarding`); await shot("12-onboarding-step1"); await page.getByPlaceholder("Studio, Newsroom, Acme Social…").fill("Studio"); await page.getByRole("button", { name: "Continue" }).click(); await shot("13-onboarding-step2"); await page.goto(`${BASE}/streams`); await page.keyboard.press("Meta+k"); await shot("14-command-palette"); await browser.close(); console.log(`\nconsole errors: ${errors.length}`); for (const e of errors.slice(0, 10)) console.log(` - ${e}`);