// Screenshots of the drafts popover preview harness (`/?popover`, see // src/popover/preview/popoverHarness.tsx) against a running `vite dev`. // Usage: node scripts/popover-shots.mjs [baseUrl] [outDir] import { chromium } from 'playwright'; import { mkdirSync } from 'node:fs'; import { join } from 'node:path'; const base = process.argv[2] ?? 'http://127.0.0.1:1420'; const out = process.argv[3] ?? join(import.meta.dirname, '..', '..', '..', 'verification', 'drafts-popover'); mkdirSync(out, { recursive: true }); const WIDE = { width: 1280, height: 860 }; const NARROW = { width: 720, height: 760 }; const shots = [ ['popover-open', WIDE, ''], ['popover-hover-preview', WIDE, 'sel=2'], ['popover-search', WIDE, 'q=webview'], ['popover-no-match', WIDE, 'q=zzzz'], ['popover-empty', WIDE, 'state=empty'], ['popover-loading', WIDE, 'state=loading'], ['popover-error', WIDE, 'state=error'], ['popover-above', WIDE, 'above'], ['popover-narrow', NARROW, ''], ['composer-hint-chip', WIDE, 'hint&closed'], ['composer-button', WIDE, 'closed', async page => { await page.hover('[data-bt-drafts-button]'); }], ['after-insert', WIDE, '', async page => { await page.keyboard.press('Enter'); }], ]; const only = process.env.ONLY?.split(','); const browser = await chromium.launch(); const errors = []; for (const [name, viewport, query, act] of shots) { if (only && !only.includes(name)) continue; const page = await browser.newPage({ viewport, deviceScaleFactor: 2 }); page.on('pageerror', error => errors.push(`${name}: ${error.message}`)); page.on('console', message => { if (message.type() === 'error') errors.push(`${name}: ${message.text()}`); }); await page.goto(`${base}/?popover&${query}`); await page.waitForSelector('[data-bt-drafts-button]'); await page.waitForTimeout(900); if (act) { await act(page); await page.waitForTimeout(400); } await page.screenshot({ path: join(out, `${name}.png`) }); await page.close(); } await browser.close(); console.log(errors.length ? errors.join('\n') : 'no page errors');