import { chromium, type Page, type Locator } from 'playwright'; import { mkdir } from 'node:fs/promises'; import { resolve, dirname } from 'node:path'; import { fileURLToPath } from 'node:url'; import { DEFAULT_MASK, shots, type Shot } from './shots.config.js'; const __dirname = dirname(fileURLToPath(import.meta.url)); const OUT_DIR = resolve(__dirname, '../../src/assets/screenshots/whp'); function envOrDie(name: string): string { const v = process.env[name]; if (!v) { throw new Error( `Missing env var: ${name}. Put it in tools/screenshots/.env (gitignored).`, ); } return v; } const WHP_BASE = envOrDie('WHP_BASE'); // e.g., https://whp01.cloud-hosting.io:8443 const WHP_USER = envOrDie('WHP_USER'); const WHP_PASS = envOrDie('WHP_PASS'); async function login(page: Page): Promise { await page.goto(`${WHP_BASE}/login`); await page.fill('input[name="username"]', WHP_USER); await page.fill('input[name="password"]', WHP_PASS); await page.click('button[type="submit"]'); await page.waitForLoadState('networkidle'); } async function captureShot(page: Page, shot: Shot): Promise { const viewport = shot.viewport ?? { width: 1440, height: 900 }; await page.setViewportSize(viewport); await page.goto(`${WHP_BASE}${shot.path}`); await page.waitForLoadState('networkidle'); if (shot.waitFor) await page.waitForSelector(shot.waitFor); const maskSelectors = [...DEFAULT_MASK, ...(shot.mask ?? [])]; const maskLocators: Locator[] = maskSelectors.map((sel) => page.locator(sel)); const outPath = resolve(OUT_DIR, `${shot.id}.png`); if (shot.selector) { await page.locator(shot.selector).screenshot({ path: outPath, mask: maskLocators, }); } else { // Viewport-only — Playwright never includes browser chrome await page.screenshot({ path: outPath, fullPage: false, mask: maskLocators, }); } console.log(`captured ${shot.id} -> ${outPath}`); } async function main(): Promise { await mkdir(OUT_DIR, { recursive: true }); const browser = await chromium.launch({ headless: true }); const ctx = await browser.newContext({ ignoreHTTPSErrors: true, viewport: { width: 1440, height: 900 }, deviceScaleFactor: 2, }); const page = await ctx.newPage(); try { await login(page); for (const shot of shots) { await captureShot(page, shot); } } finally { await browser.close(); } } main().catch((err) => { console.error(err); process.exit(1); });