fix(tests): keep test-results across CI suites; loud pipeline alert
The screenshot report went silent on green CI runs. CI runs four sequential
`playwright test` invocations (wx, asyncify, kicad, perf) that all default their
outputDir to `test-results`; Playwright clears the whole outputDir at the start
of every run, so each suite wiped the previous suite's screenshots. By the time
`compare` ran, only perf-*.json remained -> all 354 baselines read as "removed"
-> the no-render guard stayed silent.
- Gate Playwright's outputDir off test-results/ in CI only
(process.env.CI ? 'pw-artifacts/<suite>' : 'test-results') in the wx / asyncify
/ kicad configs, so the committed-baseline screenshots (page.screenshot to
'test-results/...') accumulate in test-results/ across the suites for compare.
Local single-suite behavior is unchanged.
- post-discord: replace the silent no-render guard with a loud, image-less
pipeline alert ("No screenshots produced this run") when 0 render; genuine
partial removals still post as the normal capped REMOVED list.
- gitignore pw-artifacts/; upload tests/pw-artifacts/** as a CI artifact.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
9b41d7321f
commit
b270507505
6 changed files with 31 additions and 4 deletions
1
.github/workflows/wasm-build.yml
vendored
1
.github/workflows/wasm-build.yml
vendored
|
|
@ -368,5 +368,6 @@ jobs:
|
||||||
path: |
|
path: |
|
||||||
tests/logs/**
|
tests/logs/**
|
||||||
tests/test-results/**
|
tests/test-results/**
|
||||||
|
tests/pw-artifacts/**
|
||||||
tests/playwright-report/**
|
tests/playwright-report/**
|
||||||
if-no-files-found: ignore
|
if-no-files-found: ignore
|
||||||
|
|
|
||||||
1
.gitignore
vendored
1
.gitignore
vendored
|
|
@ -40,6 +40,7 @@ wxwidgets-clean/
|
||||||
/tests/node_modules/
|
/tests/node_modules/
|
||||||
/tests/playwright-report/
|
/tests/playwright-report/
|
||||||
/tests/test-results/
|
/tests/test-results/
|
||||||
|
/tests/pw-artifacts/
|
||||||
/tests/.test-port
|
/tests/.test-port
|
||||||
/test-results/
|
/test-results/
|
||||||
/tests/apps/*.js
|
/tests/apps/*.js
|
||||||
|
|
|
||||||
|
|
@ -42,6 +42,9 @@ export default defineConfig({
|
||||||
globalSetup: './global-setup.ts',
|
globalSetup: './global-setup.ts',
|
||||||
testDir: './asyncify',
|
testDir: './asyncify',
|
||||||
testMatch: /asyncify-races.*\.spec\.ts$/,
|
testMatch: /asyncify-races.*\.spec\.ts$/,
|
||||||
|
// See playwright.config.ts: keep CI's outputDir cleanup off test-results/ (this run is
|
||||||
|
// what would otherwise wipe the wx screenshots inside `npm run test`).
|
||||||
|
outputDir: process.env.CI ? 'pw-artifacts/asyncify' : 'test-results',
|
||||||
fullyParallel: false, // one heavy WASM app at a time
|
fullyParallel: false, // one heavy WASM app at a time
|
||||||
forbidOnly: !!process.env.CI,
|
forbidOnly: !!process.env.CI,
|
||||||
retries: 0,
|
retries: 0,
|
||||||
|
|
|
||||||
|
|
@ -102,6 +102,9 @@ const appsDir = 'apps';
|
||||||
export default defineConfig({
|
export default defineConfig({
|
||||||
globalSetup: './global-setup.ts',
|
globalSetup: './global-setup.ts',
|
||||||
testDir: './kicad',
|
testDir: './kicad',
|
||||||
|
// See playwright.config.ts: keep CI's outputDir cleanup off test-results/ so the kicad +
|
||||||
|
// perf runs don't wipe the accumulated screenshots.
|
||||||
|
outputDir: process.env.CI ? 'pw-artifacts/kicad' : 'test-results',
|
||||||
fullyParallel: true,
|
fullyParallel: true,
|
||||||
forbidOnly: !!process.env.CI,
|
forbidOnly: !!process.env.CI,
|
||||||
// 1 local retry absorbs the known under-parallel-load flakes (same rationale
|
// 1 local retry absorbs the known under-parallel-load flakes (same rationale
|
||||||
|
|
|
||||||
|
|
@ -67,6 +67,11 @@ const appsDir = 'apps';
|
||||||
export default defineConfig({
|
export default defineConfig({
|
||||||
globalSetup: './global-setup.ts',
|
globalSetup: './global-setup.ts',
|
||||||
testDir: './e2e',
|
testDir: './e2e',
|
||||||
|
// In CI, redirect Playwright's start-of-run outputDir cleanup to a throwaway dir so it
|
||||||
|
// never wipes test-results/ — the committed-baseline screenshots (page.screenshot to
|
||||||
|
// 'test-results/…') must survive across the sequential wx/asyncify/kicad/perf runs for the
|
||||||
|
// screenshot compare. Local dev keeps the default (test-results cleaned each single run).
|
||||||
|
outputDir: process.env.CI ? 'pw-artifacts/wx' : 'test-results',
|
||||||
fullyParallel: true,
|
fullyParallel: true,
|
||||||
forbidOnly: !!process.env.CI,
|
forbidOnly: !!process.env.CI,
|
||||||
// 1 local retry absorbs transient `npx serve` connection refusals under heavy
|
// 1 local retry absorbs transient `npx serve` connection refusals under heavy
|
||||||
|
|
|
||||||
|
|
@ -217,11 +217,25 @@ async function main(): Promise<void> {
|
||||||
|
|
||||||
const sha = process.env.GITHUB_SHA;
|
const sha = process.env.GITHUB_SHA;
|
||||||
const report = readReport(root);
|
const report = readReport(root);
|
||||||
// Defensive: if the run produced no screenshots at all (renders missing), don't
|
// Loud pipeline alert: if the run produced ZERO screenshots (every baseline shows as
|
||||||
// post a bogus "everything removed" report. (The workflow already gates this step
|
// "removed"), that's almost always a build/pipeline failure — not a real mass removal.
|
||||||
// to successful runs, where renders exist.)
|
// Post a distinct, image-less alert instead of dumping a giant REMOVED list.
|
||||||
if (report && report.changed.length + report.added.length + report.unchangedCount === 0) {
|
if (report && report.changed.length + report.added.length + report.unchangedCount === 0) {
|
||||||
console.log('[discord] no screenshots rendered — nothing to report');
|
const shortSha = sha ? sha.slice(0, 7) : 'local';
|
||||||
|
const runUrl =
|
||||||
|
process.env.GITHUB_SERVER_URL && process.env.GITHUB_REPOSITORY && process.env.GITHUB_RUN_ID
|
||||||
|
? `${process.env.GITHUB_SERVER_URL}/${process.env.GITHUB_REPOSITORY}/actions/runs/${process.env.GITHUB_RUN_ID}`
|
||||||
|
: '';
|
||||||
|
const alert =
|
||||||
|
`⚠️ **No screenshots produced this run** · \`${shortSha}\` — compare saw 0 rendered ` +
|
||||||
|
`vs ${report.removed.length} baselines. Likely a build/pipeline failure, not a mass removal.` +
|
||||||
|
(runUrl ? `\n${runUrl}` : '');
|
||||||
|
if (args.dryRun) {
|
||||||
|
console.log('--- message 1/1 (0 files) ---\n' + alert);
|
||||||
|
} else {
|
||||||
|
await postMessage(webhook!, { content: alert, files: [] });
|
||||||
|
console.log('[discord] posted pipeline alert (0 screenshots rendered)');
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const prevDir = fetchPreviousPerf((args.repo as string) || process.env.GITHUB_REPOSITORY, sha);
|
const prevDir = fetchPreviousPerf((args.repo as string) || process.env.GITHUB_REPOSITORY, sha);
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue