const { chromium } = require('playwright'); const path = require('path'); const fs = require('fs'); const VIEWPORTS = { mobile: { width: 375, height: 667 }, tablet: { width: 768, height: 1024 }, desktop: { width: 1280, height: 720 }, }; function slugify(pagePath) { return pagePath.replace(/^\//, '').replace(/[^a-zA-Z0-9_-]/g, '_') || 'home'; } async function capturePage(page, pagePath, viewportName, outputDir) { const fullUrl = `${process.env.TARGET_URL}${pagePath}`; const filename = `${slugify(pagePath)}_${viewportName}.png`; const filepath = path.join(outputDir, filename); await page.setViewportSize(VIEWPORTS[viewportName]); await page.goto(fullUrl, { waitUntil: 'networkidle', timeout: 30000 }); await page.waitForTimeout(500); await page.screenshot({ path: filepath, fullPage: false }); return { pagePath, viewport: viewportName, file: filename, saved: true }; } async function main() { const mode = process.argv[2]; if (!['baseline', 'current'].includes(mode)) { console.error('Usage: node capture-screenshots.js '); process.exit(1); } const targetUrl = process.env.TARGET_URL; const pages = (process.env.PAGES || '/').split(',').map(p => p.trim()).filter(p => /^\/[A-Za-z0-9._\/-]*$/.test(p)); if (pages.length === 0) { console.error('No valid pages in PAGES environment variable'); process.exit(1); } const outputDir = mode === 'baseline' ? (process.env.BASELINE_DIR || './screenshots/baseline') : (process.env.CURRENT_DIR || './screenshots/current'); if (!targetUrl) { console.error('TARGET_URL environment variable is required'); process.exit(1); } fs.mkdirSync(outputDir, { recursive: true }); const browser = await chromium.launch({ headless: true }); const context = await browser.newContext(); const page = await context.newPage(); const results = []; try { for (const pagePath of pages) { for (const vpName of Object.keys(VIEWPORTS)) { try { const result = await capturePage(page, pagePath, vpName, outputDir); results.push(result); console.log(`Captured ${pagePath} @ ${vpName} -> ${result.file}`); } catch (err) { results.push({ pagePath, viewport: vpName, error: err.message, saved: false }); console.error(`Failed ${pagePath} @ ${vpName}: ${err.message}`); } } } } finally { await browser.close(); } const report = { mode, targetUrl, pages, outputDir, results }; const reportPath = path.join(outputDir, '..', `${mode}-capture-report.json`); fs.mkdirSync(path.dirname(reportPath), { recursive: true }); fs.writeFileSync(reportPath, JSON.stringify(report, null, 2)); console.log(`Report saved to ${reportPath}`); } main().catch(err => { console.error('Fatal error:', err); process.exit(1); });