AvanzaCast/scripts/capture_and_diff_prejoin.js
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

65 lines
3.0 KiB
JavaScript

#!/usr/bin/env node
const fs = require('fs');
const path = require('path');
const puppeteer = require('puppeteer');
const PNG = require('pngjs').PNG;
const pixelmatch = require('pixelmatch');
async function capture(fileUrl, outPath, width=1280, height=720) {
const browser = await puppeteer.launch({args: ['--no-sandbox','--disable-setuid-sandbox']});
const page = await browser.newPage();
await page.setViewport({ width, height });
await page.goto(fileUrl, { waitUntil: 'networkidle0' });
// wait a bit for scripts to run
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 () => {
try {
const outDir = '/tmp';
const fileArg = process.argv[2] || `file://${path.resolve(process.cwd(),'docs/prejoin_template.html')}`;
const outFile = path.join(outDir, 'prejoin_capture_1280x720.png');
console.log('Capturing', fileArg, '->', outFile);
await capture(fileArg, outFile, 1280, 720);
console.log('Saved capture to', outFile);
// If baseline exists in repo root under baselines/, compare
const baselineA = path.resolve(process.cwd(), 'baselines/prejoin_regen_1280x720.png');
const baselineB = path.resolve(process.cwd(), 'baselines/prejoin_browserless_1280x720.png');
let result = { captured: outFile, compared: false };
if (fs.existsSync(baselineA)) {
const diffOut = path.join(outDir, 'prejoin_diff_1280x720.png');
const metrics = compare(outFile, baselineA, diffOut);
result.compared = true; result.baseline = baselineA; result.diff = diffOut; result.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);
result.compared = true; result.baseline = baselineB; result.diff = diffOut; result.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('/tmp','prejoin_capture_report.json'), JSON.stringify(result, null, 2));
console.log('Report written to /tmp/prejoin_capture_report.json');
} catch (err) {
console.error('Failed:', err);
process.exit(2);
}
})();