diff --git a/.github/workflows/e2e-desktop.yml b/.github/workflows/e2e-desktop.yml index 98b1444d207f..c8f68be41342 100644 --- a/.github/workflows/e2e-desktop.yml +++ b/.github/workflows/e2e-desktop.yml @@ -113,10 +113,10 @@ jobs: DIFF_COUNT=$(find test-results -name '*-diff.png' 2>/dev/null | wc -l) ACTUAL_COUNT=$(find test-results -name '*-actual.png' 2>/dev/null | wc -l) - if [ "$DIFF_COUNT" -eq 0 ] && [ "$ACTUAL_COUNT" -eq 0 ]; then - echo "✅ All screenshots matched their baselines (or no baselines existed yet)." >> "$GITHUB_STEP_SUMMARY" + if [ "$DIFF_COUNT" -eq 0 ]; then + echo "✅ All $ACTUAL_COUNT screenshot(s) matched their baselines (or no baselines existed yet)." >> "$GITHUB_STEP_SUMMARY" else - echo "📸 **$DIFF_COUNT screenshot(s) differ from baseline:**" >> "$GITHUB_STEP_SUMMARY" + echo "📸 **$DIFF_COUNT of $ACTUAL_COUNT screenshot(s) differ from baseline:**" >> "$GITHUB_STEP_SUMMARY" echo "" >> "$GITHUB_STEP_SUMMARY" echo "| Test | Diff | Actual | Expected |" >> "$GITHUB_STEP_SUMMARY" echo "|------|------|--------|----------|" >> "$GITHUB_STEP_SUMMARY" @@ -127,12 +127,17 @@ jobs: test_name=$(basename "$base") echo "| $test_name | [diff]($diff) | [actual](${base}-actual.png) | [expected](${base}-expected.png) |" >> "$GITHUB_STEP_SUMMARY" done - echo "" >> "$GITHUB_STEP_SUMMARY" - echo "Diff images are in the \`playwright-test-results\` artifact. Download and open to compare." >> "$GITHUB_STEP_SUMMARY" - echo "" >> "$GITHUB_STEP_SUMMARY" - echo "**To update baselines:** merge to main (baselines auto-update on main runs) or run \`npx playwright test --update-snapshots\` locally." >> "$GITHUB_STEP_SUMMARY" fi + echo "" >> "$GITHUB_STEP_SUMMARY" + RUN_URL="${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}/actions/runs/${GITHUB_RUN_ID}" + echo "📥 Artifacts on the [run page](${RUN_URL}/artifacts):" >> "$GITHUB_STEP_SUMMARY" + echo "" >> "$GITHUB_STEP_SUMMARY" + echo "- \`playwright-test-results\` — all screenshots (actual + expected + diff) + traces" >> "$GITHUB_STEP_SUMMARY" + echo "- \`playwright-report\` — interactive HTML report" >> "$GITHUB_STEP_SUMMARY" + echo "" >> "$GITHUB_STEP_SUMMARY" + echo "**To update baselines:** merge to main (baselines auto-update on main runs) or run \`npx playwright test --update-snapshots\` locally." >> "$GITHUB_STEP_SUMMARY" + # Also parse the JSON report for pass/fail counts if [ -f playwright-report/results.json ]; then echo "" >> "$GITHUB_STEP_SUMMARY" diff --git a/apps/desktop/e2e/visual-snapshot.ts b/apps/desktop/e2e/visual-snapshot.ts index f84864ed2ddd..df1bdc9d7e4e 100644 --- a/apps/desktop/e2e/visual-snapshot.ts +++ b/apps/desktop/e2e/visual-snapshot.ts @@ -7,10 +7,10 @@ * as artifacts. This keeps visual regressions visible without gating PRs * on pixel-perfect matches. * - * When a screenshot matches the baseline, nothing happens. When it - * differs, this helper writes three images to the test's output dir: + * The actual screenshot is always written to the test output dir so CI + * artifacts include every screenshot — not just the ones that diffed. + * When it differs, this helper also writes expected and diff images: * -actual.png, -expected.png, -diff.png - * These are picked up by the "Upload test results" artifact step. */ import fs from 'node:fs' import path from 'node:path' @@ -83,6 +83,8 @@ export async function expectVisualSnapshot( if (info.config.updateSnapshots === 'all' || info.config.updateSnapshots === 'changed') { fs.mkdirSync(path.dirname(baselinePath), { recursive: true }) fs.writeFileSync(baselinePath, actual) + // Also write to the output dir so CI artifacts include the screenshot. + fs.writeFileSync(info.outputPath(`${outputName}-actual.png`), actual) console.log(`[visual-baseline] updated ${baselinePath}`) return } @@ -132,11 +134,14 @@ export async function expectVisualSnapshot( { actual: actual.toString('base64'), expected: expected.toString('base64') }, ) + // Always write the actual screenshot to the output dir so CI artifacts + // include every screenshot — not just the ones that diffed. + fs.writeFileSync(info.outputPath(`${outputName}-actual.png`), actual) + if (comparison.mismatchRatio <= 0.01) { return } - fs.writeFileSync(info.outputPath(`${outputName}-actual.png`), actual) fs.writeFileSync(info.outputPath(`${outputName}-expected.png`), expected) fs.writeFileSync(info.outputPath(`${outputName}-diff.png`), Buffer.from(comparison.diff, 'base64')) console.log(