/** * __shot — the 2× capture of PLAN-theming §7.2.6 / §7.4.13. * * node scripts/__shot.ts [url] [--open[=selector]] * * The URL is an ARGUMENT, not a constant: the port lived hard-coded at 5173 * here while the probe and the guard already took it, so every call from a * 5180 session died with ERR_EMPTY_RESPONSE — which is why the step was easy * to skip (measured 2026-08-23). `--open` clicks the component's trigger * first, for the components whose surface only exists open. */ import { chromium } from 'playwright'; const args = process.argv.slice(2); const flags = args.filter((a) => a.startsWith('--')); const [component, out, urlArg] = args.filter((a) => !a.startsWith('--')); if (!component || !out) throw new Error('usage: [url] [--open[=selector]]'); const url = urlArg ?? `http://localhost:5180/uix/components/${component}`; const openFlag = flags.find((f) => f.startsWith('--open')); const b = await chromium.launch(); const p = await b.newPage({ viewport: { width: 1280, height: 900 }, deviceScaleFactor: 2 }); try { await p.goto(url, { waitUntil: 'networkidle', timeout: 20000 }); } catch { await p.goto(url, { waitUntil: 'load', timeout: 20000 }); } await p.waitForTimeout(900); if (openFlag) { const sel = openFlag.includes('=') ? openFlag.split('=').slice(1).join('=') : `[data-${component}-trigger]`; const el = p.locator(sel).first(); if (await el.count()) { await el.click({ timeout: 4000 }).catch(() => {}); await p.waitForTimeout(700); } } const stage = p.locator('[data-uix-stage]').first(); await ((await stage.count()) ? stage : p.locator('body')).screenshot({ path: out }); console.log('shot ->', out); await b.close();