diff --git a/scripts/visual-regression.js b/scripts/visual-regression.js index c39c0595..467b2918 100644 --- a/scripts/visual-regression.js +++ b/scripts/visual-regression.js @@ -11,7 +11,7 @@ const { execSync } = require('child_process'); const ART = 'artifacts'; /* ────────────────────────────────────────────────────────── * - * Parse Playwright HTML report to extract test metadata + * Parse Playwright HTML report to extract test metadata * ────────────────────────────────────────────────────────── */ function parsePlaywrightReport(reportPath) { const screenshots = new Map(); @@ -25,230 +25,49 @@ function parsePlaywrightReport(reportPath) { try { const html = fs.readFileSync(indexPath, 'utf8'); - // Method 1: Try to extract from window.playwrightReport - const reportRegex = /window\.playwrightReport\s*=\s*({[\s\S]*?});/; + // Modern Playwright reports embed data in a script tag. + // This is the most reliable method. + const reportRegex = / + `; } /* ────────────────────────────────────────────────────────── * - * Main visual regression analysis + * Main visual regression analysis * ────────────────────────────────────────────────────────── */ async function generateVisualReport() { console.log('🔍 Starting visual regression analysis...'); - console.log('📁 Working directory:', process.cwd()); - console.log('📁 Artifacts directory:', ART); - // Find screenshots in both reports const prReportPath = path.join(ART, 'pr-report'); const mainReportPath = path.join(ART, 'main-report'); - console.log('\n📊 Checking report paths:'); - console.log(` PR Report: ${prReportPath} (exists: ${fs.existsSync(prReportPath)})`); - console.log(` Main Report: ${mainReportPath} (exists: ${fs.existsSync(mainReportPath)})`); - if (!fs.existsSync(prReportPath) || !fs.existsSync(mainReportPath)) { - console.error('❌ One or both report directories not found'); - return { - timestamp: new Date().toISOString(), - totalScreenshots: 0, - totalComparisons: 0, - identical: 0, - negligible: 0, - minor: 0, - major: 0, - new: 0, - removed: 0, - comparisons: [] - }; + console.error('❌ One or both report directories not found. Cannot perform visual comparison.'); + return; } - // Find all screenshots - console.log('\n🔍 Finding screenshots...'); - const prScreenshots = findAllScreenshots(prReportPath); - const mainScreenshots = findAllScreenshots(mainReportPath); + const prScreenshots = parsePlaywrightReport(prReportPath); + const mainScreenshots = parsePlaywrightReport(mainReportPath); - console.log(`\n📸 Screenshots found:`); - console.log(` PR: ${prScreenshots.size} total`); - console.log(` Main: ${mainScreenshots.size} total`); - - if (prScreenshots.size === 0 && mainScreenshots.size === 0) { - console.error('❌ No screenshots found in either report'); - console.log('\n💡 Tips:'); - console.log(' - Make sure your Playwright config has: screenshot: "on"'); - console.log(' - Or add explicit screenshots in your tests: await page.screenshot()'); - console.log(' - Check that tests are actually running and not skipped'); - } - - // Match and compare screenshots const comparisons = await matchAndCompareScreenshots(prScreenshots, mainScreenshots); + comparisons.sort((a, b) => (b.diffPercent || 0) - (a.diffPercent || 0)); - // Sort by difference percentage (highest first) - comparisons.sort((a, b) => b.diffPercent - a.diffPercent); - - // Create summary const summary = { - timestamp: new Date().toISOString(), - totalScreenshots: prScreenshots.size, totalComparisons: comparisons.length, identical: comparisons.filter(c => c.status === 'identical').length, - negligible: comparisons.filter(c => c.status === 'negligible').length, minor: comparisons.filter(c => c.status === 'minor').length, major: comparisons.filter(c => c.status === 'major').length, new: comparisons.filter(c => c.status === 'new').length, @@ -1216,41 +609,17 @@ async function generateVisualReport() { comparisons }; - console.log('\n📊 Final summary:'); - console.log(` Total comparisons: ${summary.totalComparisons}`); - console.log(` Identical: ${summary.identical}`); - console.log(` Negligible: ${summary.negligible}`); - console.log(` Minor: ${summary.minor}`); - console.log(` Major: ${summary.major}`); - console.log(` New: ${summary.new}`); - console.log(` Removed: ${summary.removed}`); - - // Save results - fs.writeFileSync( - path.join(ART, 'visual-regression-report.json'), - JSON.stringify(summary, null, 2) - ); - - // Generate HTML report - fs.writeFileSync( - path.join(ART, 'visual-regression.html'), - generateHTMLReport(summary) - ); + fs.writeFileSync(path.join(ART, 'visual-regression-report.json'), JSON.stringify(summary, null, 2)); + fs.writeFileSync(path.join(ART, 'visual-regression.html'), generateHTMLReport(summary)); - // Generate markdown summary - const markdownSummary = generateMarkdownSummary(summary); - fs.writeFileSync( - path.join(ART, 'visual-regression-summary.md'), - markdownSummary - ); - - console.log('\n✅ Visual regression report generated'); - console.log('📄 Files created:'); - console.log(' - artifacts/visual-regression-report.json'); - console.log(' - artifacts/visual-regression.html'); - console.log(' - artifacts/visual-regression-summary.md'); - - return summary; + console.log('✅ Visual regression report generated successfully.'); +} + +if (require.main === module) { + generateVisualReport().catch(error => { + console.error('❌ Error during visual regression analysis:', error); + process.exit(1); + }); } /* ────────────────────────────────────────────────────────── *