Files
redefined-designs/scripts/summarize-playwright.js
T
bermudalambandClaude Opus 5 ec63b9cdb0 fix: unset NODE_ENV in e2e job so devDependencies install
npm treats NODE_ENV=production as --omit=dev, so `npm install` in the
frontend-e2e job skipped typescript and the build died on `tsc: not found`.
The same env var would have stripped vite and @playwright/test from the
frontend install, and flipped the session cookie to Secure on a run served
over plain http.

The reported summarize crash was a symptom: the job aborted before Playwright
ran, but Summarize is `if: always()` and threw ENOENT on the missing JSON,
burying the real failure. Both summarize scripts now report the missing file
and exit 0 -- the job still fails via its own step.

Also split build from start, replaced `sleep 3` with a readiness poll against
/api/config, and dump the backend log when e2e fails.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-15 08:56:25 -05:00

67 lines
2.1 KiB
JavaScript

#!/usr/bin/env node
const fs = require('fs');
const [, , resultsPath] = process.argv;
// This runs with `if: always()`, so it also fires when an earlier step failed and
// no results file was ever written. Report that plainly and exit 0 — the job still
// fails on the real step, and a stack trace here would only bury it.
if (!fs.existsSync(resultsPath)) {
report([`## Playwright E2E Results`, '', `No results file at \`${resultsPath}\` — the test step failed before writing one.`, '']);
process.exit(0);
}
const raw = fs.readFileSync(resultsPath, 'utf-8');
const data = JSON.parse(raw);
const stats = data.stats || {};
const lines = [];
lines.push('## Playwright E2E Results');
lines.push('');
lines.push('| | Count |');
lines.push('|---|---|');
lines.push(`| ✅ Passed | ${stats.expected || 0} |`);
lines.push(`| ❌ Failed | ${stats.unexpected || 0} |`);
lines.push(`| ⚠️ Flaky | ${stats.flaky || 0} |`);
lines.push(`| ⏭️ Skipped | ${stats.skipped || 0} |`);
lines.push('');
function collectFailures(suites, path) {
path = path || [];
let failures = [];
for (const suite of suites || []) {
const currentPath = path.concat(suite.title).filter(Boolean);
for (const spec of suite.specs || []) {
for (const test of spec.tests || []) {
for (const result of test.results || []) {
if (result.status !== 'passed' && result.status !== 'skipped') {
failures.push(`${currentPath.join(' > ')} > ${spec.title}: ${result.status}`);
}
}
}
}
if (suite.suites) failures = failures.concat(collectFailures(suite.suites, currentPath));
}
return failures;
}
const failures = collectFailures(data.suites);
if (failures.length) {
lines.push('### Failures');
lines.push('');
for (const f of failures) lines.push(`- ${f}`);
lines.push('');
}
report(lines);
process.exit((stats.unexpected || 0) > 0 ? 1 : 0);
function report(out) {
const summaryPath = process.env.GITEA_STEP_SUMMARY || process.env.GITHUB_STEP_SUMMARY;
if (summaryPath) {
fs.appendFileSync(summaryPath, out.join('\n') + '\n');
} else {
console.log(out.join('\n'));
}
}