AvanzaCast/scripts/capture_and_diff_playwright.mjs
Cesar Mendivil adbec08f5e feat(prejoin): refactor PreJoin UI and styles; remove mock studio feature; add visual test scripts and update dependencies
- Redesign PreJoin component and CSS for improved template compatibility and deterministic rendering
- Remove mock studio toggle and related runtime logic; update useStudioLauncher to always use real backend
- Add README-MOCK.md to document mock studio deprecation
- Add mock-studio.html for manual popup emulation
- Update environment variable resolution in route.ts for backend API
- Add visual regression test scripts (capture, compare, visual_test_prejoin) using Playwright, Puppeteer, pixelmatch, and pngjs
- Update package.json scripts and devDependencies for visual testing
- Simplify PreJoin.stories.tsx for robust Storybook usage
2025-11-25 09:24:44 -07:00

66 lines
2.8 KiB
JavaScript

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();