#!/usr/bin/env node /** * Creates an index page for Playwright test reports with test statistics * Reads JSON reports from each browser and creates a landing page with cards */ import fs from 'fs' import path from 'path' import { fileURLToPath } from 'url' const __filename = fileURLToPath(import.meta.url) const __dirname = path.dirname(__filename) const reportsDir = path.join(__dirname, '..', '.pages', 'playwright-reports') function getTestStats(reportPath) { try { const reportJsonPath = path.join(reportPath, 'report.json') if (!fs.existsSync(reportJsonPath)) { console.warn(`No report.json found at ${reportJsonPath}`) return null } const reportData = JSON.parse(fs.readFileSync(reportJsonPath, 'utf-8')) let passed = 0 let failed = 0 let skipped = 0 let flaky = 0 // Parse Playwright JSON report format if (reportData.suites) { const countResults = (suites) => { for (const suite of suites) { if (suite.specs) { for (const spec of suite.specs) { if (!spec.tests || spec.tests.length === 0) continue const test = spec.tests[0] const results = test.results || [] // Check if test is flaky (has both pass and fail results) const hasPass = results.some((r) => r.status === 'passed') const hasFail = results.some((r) => r.status === 'failed') if (hasPass && hasFail) { flaky++ } else if (results.some((r) => r.status === 'passed')) { passed++ } else if (results.some((r) => r.status === 'failed')) { failed++ } else if (results.some((r) => r.status === 'skipped')) { skipped++ } } } if (suite.suites) { countResults(suite.suites) } } } countResults(reportData.suites) } return { passed, failed, skipped, flaky } } catch (error) { console.error(`Error reading report at ${reportPath}:`, error.message) return null } } function generateIndexHtml(browsers) { const cards = browsers .map((browser) => { const { name, stats } = browser if (!stats) return '' const total = stats.passed + stats.failed + stats.skipped + stats.flaky const passRate = total > 0 ? ((stats.passed / total) * 100).toFixed(1) : 0 return `

${name}

${passRate}%
Passed ${stats.passed}
Failed ${stats.failed}
Skipped ${stats.skipped}
Flaky ${stats.flaky}
` }) .join('') return ` Playwright E2E Test Reports

🎭 Playwright E2E Test Reports

${cards}
` } function main() { if (!fs.existsSync(reportsDir)) { console.log( 'No playwright reports directory found, skipping index creation' ) return } const browsers = [] const browserDirs = fs.readdirSync(reportsDir, { withFileTypes: true }) for (const dirent of browserDirs) { if (dirent.isDirectory()) { const browserName = dirent.name const browserPath = path.join(reportsDir, browserName) const stats = getTestStats(browserPath) if (stats) { browsers.push({ name: browserName, stats }) console.log(`✓ Found report for ${browserName}:`, stats) } } } if (browsers.length === 0) { console.warn('No valid browser reports found') return } const html = generateIndexHtml(browsers) const indexPath = path.join(reportsDir, 'index.html') fs.writeFileSync(indexPath, html, 'utf-8') console.log(`✓ Created index page at ${indexPath}`) } main()