From 3dab6901b4945c813e3fc5e71c227e900493ebec Mon Sep 17 00:00:00 2001 From: Shahed <125728402+dev-shahed@users.noreply.github.com> Date: Fri, 26 Jun 2026 22:41:48 +0600 Subject: [PATCH] ci: render Playwright results as a GitHub Step Summary Add a CI-only json reporter and .github/scripts/pw-summary.js that writes a pass/fail table plus the failing-test list to the workflow run summary page. No production code touched. Co-Authored-By: Claude Opus 4.8 (1M context) --- .github/scripts/pw-summary.js | 73 +++++++++++++++++++++++++++++++++++ .github/workflows/e2e.yml | 7 ++++ .gitignore | 1 + playwright.config.ts | 2 +- 4 files changed, 82 insertions(+), 1 deletion(-) create mode 100644 .github/scripts/pw-summary.js diff --git a/.github/scripts/pw-summary.js b/.github/scripts/pw-summary.js new file mode 100644 index 0000000..19e4b98 --- /dev/null +++ b/.github/scripts/pw-summary.js @@ -0,0 +1,73 @@ +/** + * Render a Playwright JSON report into a GitHub Actions Step Summary. + * + * Reads tests/e2e/results.json (produced by the `json` reporter in CI) and + * appends a Markdown panel — overall verdict, a counts table, and the list of + * failing tests — to $GITHUB_STEP_SUMMARY so it shows on the run page. + * + * Pure Node, no dependencies. Never throws: a missing/garbled report just + * skips the summary rather than failing the job (the test step owns pass/fail). + */ +'use strict'; + +const fs = require('fs'); + +const REPORT = 'tests/e2e/results.json'; +const wp = process.env.WP_VERSION || 'unknown'; +const summaryFile = process.env.GITHUB_STEP_SUMMARY; + +function appendSummary(md) { + if (summaryFile) { + fs.appendFileSync(summaryFile, md); + } else { + process.stdout.write(md); + } +} + +try { + if (!fs.existsSync(REPORT)) { + appendSummary(`## ⚠️ E2E — WordPress ${wp}\n\nNo \`${REPORT}\` was produced (the suite may not have started).\n`); + process.exit(0); + } + + const report = JSON.parse(fs.readFileSync(REPORT, 'utf8')); + const stats = report.stats || {}; + const passed = stats.expected || 0; + const failed = stats.unexpected || 0; + const flaky = stats.flaky || 0; + const skipped = stats.skipped || 0; + const duration = ((stats.duration || 0) / 1000).toFixed(1); + const ok = failed === 0; + + // Walk the suite tree and collect "file › test title" for every failing spec. + const failures = []; + const walk = (suite) => { + (suite.suites || []).forEach(walk); + (suite.specs || []).forEach((spec) => { + if (spec.ok === false) { + const file = spec.file || (suite && suite.file) || ''; + failures.push(`${file} › ${spec.title}`); + } + }); + }; + (report.suites || []).forEach(walk); + + let md = `## ${ok ? '✅' : '❌'} E2E — WordPress ${wp}\n\n`; + md += '| Result | ✅ Passed | ❌ Failed | ⚠️ Flaky | ⏭️ Skipped | ⏱️ Duration |\n'; + md += '|:------:|:--------:|:--------:|:-------:|:----------:|:-----------:|\n'; + md += `| ${ok ? '**Pass**' : '**Fail**'} | ${passed} | ${failed} | ${flaky} | ${skipped} | ${duration}s |\n`; + + if (failures.length) { + md += '\n
Failing tests\n\n'; + failures.forEach((t) => { + md += `- \`${t}\`\n`; + }); + md += '\n
\n'; + } + + md += `\n> 📦 Full HTML report (traces, screenshots, video) is attached as artifact **\`playwright-report-wp-${wp}\`**.\n`; + + appendSummary(md); +} catch (err) { + appendSummary(`## ⚠️ E2E — WordPress ${wp}\n\nCould not parse the Playwright report: ${err.message}\n`); +} diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml index 3186e7a..c26ee73 100644 --- a/.github/workflows/e2e.yml +++ b/.github/workflows/e2e.yml @@ -118,6 +118,13 @@ jobs: - name: Run Playwright E2E suite run: npm run test:e2e + # Render results.json into a pass/fail table on the run's summary page. + - name: Publish test summary + if: ${{ !cancelled() }} + env: + WP_VERSION: ${{ matrix.wordpress }} + run: node .github/scripts/pw-summary.js + - name: Upload Playwright HTML report if: ${{ !cancelled() }} uses: actions/upload-artifact@v4 diff --git a/.gitignore b/.gitignore index ddeff99..6a62c6b 100644 --- a/.gitignore +++ b/.gitignore @@ -13,3 +13,4 @@ bin/seed-* tests/e2e/auth/*.json tests/e2e/playwright-report/ tests/e2e/test-results/ +tests/e2e/results.json diff --git a/playwright.config.ts b/playwright.config.ts index 999c03d..c12a8bc 100644 --- a/playwright.config.ts +++ b/playwright.config.ts @@ -15,7 +15,7 @@ const reporters: ReporterDescription[] = [ ['html', { outputFolder: 'tests/e2e/playwright-report', open: 'never' }], ]; if (process.env.CI) { - reporters.splice(1, 0, ['github']); + reporters.splice(1, 0, ['github'], ['json', { outputFile: 'tests/e2e/results.json' }]); } export default defineConfig({