import fs from 'fs'; import path from 'path'; import { chromium } from 'playwright'; import { PNG } from 'pngjs'; import pixelmatch from 'pixelmatch'; async function capture(url, outPath, width = 1280, height = 720) { const browser = await chromium.launch({ headless: true, args: ['--no-sandbox'] }); const page = await browser.newPage({ viewport: { width, height } }); await page.goto(url, { waitUntil: 'networkidle' }); await page.waitForTimeout(500); await page.screenshot({ path: outPath, fullPage: false }); await browser.close(); } function compare(imgAPath, imgBPath, diffOut) { const imgA = PNG.sync.read(fs.readFileSync(imgAPath)); const imgB = PNG.sync.read(fs.readFileSync(imgBPath)); if (imgA.width !== imgB.width || imgA.height !== imgB.height) { throw new Error('Images must have same dimensions'); } const { width, height } = imgA; const diff = new PNG({ width, height }); const mismatched = pixelmatch(imgA.data, imgB.data, diff.data, width, height, { threshold: 0.1 }); fs.writeFileSync(diffOut, PNG.sync.write(diff)); return { mismatched, total: width * height, ratio: mismatched / (width * height) }; } async function main() { try { const arg = process.argv[2] || `file://${path.resolve(process.cwd(), 'docs/prejoin_template.html')}`; const outDir = '/tmp'; const outFile = path.join(outDir, 'prejoin_playwright_1280x720.png'); console.log('Capturing', arg, '->', outFile); await capture(arg, outFile, 1280, 720); console.log('Saved capture to', outFile); const baselineA = path.resolve(process.cwd(), 'baselines/prejoin_regen_1280x720.png'); const baselineB = path.resolve(process.cwd(), 'baselines/prejoin_browserless_1280x720.png'); const report = { captured: outFile, compared: false }; if (fs.existsSync(baselineA)) { const diffOut = path.join(outDir, 'prejoin_diff_1280x720.png'); const metrics = compare(outFile, baselineA, diffOut); report.compared = true; report.baseline = baselineA; report.diff = diffOut; report.metrics = metrics; console.log('Compared with', baselineA, 'metrics=', metrics); } else if (fs.existsSync(baselineB)) { const diffOut = path.join(outDir, 'prejoin_diff_1280x720.png'); const metrics = compare(outFile, baselineB, diffOut); report.compared = true; report.baseline = baselineB; report.diff = diffOut; report.metrics = metrics; console.log('Compared with', baselineB, 'metrics=', metrics); } else { console.log('No baseline found (checked baselines/prejoin_regen_1280x720.png and baselines/prejoin_browserless_1280x720.png)'); } fs.writeFileSync(path.join(outDir, 'prejoin_playwright_report.json'), JSON.stringify(report, null, 2)); console.log('Report written to /tmp/prejoin_playwright_report.json'); } catch (e) { console.error('Error:', e); process.exit(2); } } main();