mirror of
https://github.com/utopia-os/utopia-ui.git
synced 2026-03-01 12:44:17 +00:00
refactor e2e test fail reporting process
This commit is contained in:
parent
b5966d549f
commit
3a86aac3d6
54
.github/workflows/test.e2e.yml
vendored
54
.github/workflows/test.e2e.yml
vendored
@ -138,7 +138,7 @@ jobs:
|
||||
# Disable individual cypress-split summaries to avoid conflicts
|
||||
SPLIT_SUMMARY: false
|
||||
|
||||
- name: Upload raw test artifacts on failure
|
||||
- name: Upload test artifacts on failure
|
||||
if: failure()
|
||||
uses: actions/upload-artifact@2848b2cda0e5190984587ec6bb1f36730ca78d50 # v4.6.2
|
||||
with:
|
||||
@ -146,7 +146,6 @@ jobs:
|
||||
path: |
|
||||
cypress/results/
|
||||
cypress/screenshots/
|
||||
cypress/videos/
|
||||
retention-days: 7
|
||||
if-no-files-found: warn
|
||||
|
||||
@ -176,37 +175,38 @@ jobs:
|
||||
name: cypress-test-results-${{ github.run_id }}
|
||||
path: ./cypress
|
||||
|
||||
- name: Merge test reports
|
||||
run: |
|
||||
if [ -d "results" ] && [ "$(find results/ -name "*.json" 2>/dev/null)" ]; then
|
||||
echo "Found JSON reports, merging..."
|
||||
npm run report:merge
|
||||
echo "=== Merge result ==="
|
||||
ls -la results/merged-report.json || echo "Merge failed"
|
||||
else
|
||||
echo "No JSON reports found to merge"
|
||||
echo "=== Debug: results directory ==="
|
||||
ls -la results/ || echo "Directory does not exist"
|
||||
fi
|
||||
- name: Merge JSON reports into one consolidated report
|
||||
run: ./scripts/merge-reports.sh
|
||||
working-directory: ./cypress
|
||||
|
||||
- name: Generate HTML report
|
||||
run: |
|
||||
if [ -f "results/merged-report.json" ]; then
|
||||
echo "Generating HTML report..."
|
||||
npm run report:generate
|
||||
echo "=== HTML generation result ==="
|
||||
ls -la results/html/ || echo "HTML generation failed"
|
||||
else
|
||||
echo "No merged report found, skipping HTML generation"
|
||||
fi
|
||||
- name: Generate HTML report with screenshots
|
||||
run: ./scripts/generate-html-report.sh
|
||||
working-directory: ./cypress
|
||||
|
||||
- name: Upload processed reports
|
||||
- name: Create simple index page
|
||||
run: ./scripts/create-index-page.sh
|
||||
working-directory: ./cypress
|
||||
env:
|
||||
GITHUB_RUN_ID: ${{ github.run_id }}
|
||||
GITHUB_SHA: ${{ github.sha }}
|
||||
|
||||
- name: Upload consolidated test report
|
||||
uses: actions/upload-artifact@2848b2cda0e5190984587ec6bb1f36730ca78d50 # v4.6.2
|
||||
with:
|
||||
name: e2e-test-reports-${{ github.run_id }}
|
||||
name: e2e-test-report-${{ github.run_id }}
|
||||
path: |
|
||||
cypress/results/
|
||||
cypress/results/html/
|
||||
retention-days: 14
|
||||
if-no-files-found: warn
|
||||
|
||||
- name: Upload raw test data (for debugging)
|
||||
if: failure()
|
||||
uses: actions/upload-artifact@2848b2cda0e5190984587ec6bb1f36730ca78d50 # v4.6.2
|
||||
with:
|
||||
name: e2e-raw-data-${{ github.run_id }}
|
||||
path: |
|
||||
cypress/results/
|
||||
cypress/screenshots/
|
||||
cypress/videos/
|
||||
retention-days: 7
|
||||
if-no-files-found: warn
|
||||
|
||||
3
.gitignore
vendored
3
.gitignore
vendored
@ -1,5 +1,6 @@
|
||||
.claude/
|
||||
data/
|
||||
cypress/node_modules/
|
||||
cypress/reports/
|
||||
cypress/results/
|
||||
cypress/runner-results/
|
||||
cypress/screenshots/
|
||||
|
||||
@ -16,13 +16,14 @@ export default defineConfig({
|
||||
|
||||
reporter: 'mochawesome',
|
||||
reporterOptions: {
|
||||
useInlineDiffs: true,
|
||||
embeddedScreenshots: true,
|
||||
reportDir: 'results',
|
||||
reportFilename: '[name].html',
|
||||
reportFilename: '[name]',
|
||||
overwrite: false,
|
||||
html: true,
|
||||
json: true,
|
||||
html: false, // Only generate JSON during test runs for merging
|
||||
json: true, // Generate JSON for merging
|
||||
embeddedScreenshots: true,
|
||||
useInlineDiffs: true,
|
||||
screenshotOnRunFailure: true
|
||||
},
|
||||
|
||||
defaultCommandTimeout: 10000,
|
||||
@ -49,6 +50,10 @@ export default defineConfig({
|
||||
// Load cypress-split plugin
|
||||
cypressSplit(on, config)
|
||||
|
||||
// Load parallel reporter plugin
|
||||
const parallelReporter = require('./plugins/parallel-reporter')
|
||||
config = parallelReporter(on, config)
|
||||
|
||||
on('task', {
|
||||
log(message) {
|
||||
console.log(message)
|
||||
|
||||
80
cypress/package-lock.json
generated
80
cypress/package-lock.json
generated
@ -9,13 +9,13 @@
|
||||
"version": "1.0.0",
|
||||
"devDependencies": {
|
||||
"@eslint/js": "^9.36.0",
|
||||
"@types/mochawesome": "^6.2.4",
|
||||
"@types/node": "^24.5.2",
|
||||
"cypress": "^15.3.0",
|
||||
"cypress-mochawesome-reporter": "^3.8.2",
|
||||
"cypress-split": "^1.24.23",
|
||||
"eslint": "^9.36.0",
|
||||
"eslint-plugin-cypress": "^5.1.1",
|
||||
"mochawesome": "^7.1.3",
|
||||
"mochawesome": "^7.1.4",
|
||||
"mochawesome-merge": "^4.3.0",
|
||||
"mochawesome-report-generator": "^6.2.0",
|
||||
"typescript": "^5.9.2",
|
||||
@ -737,17 +737,6 @@
|
||||
"node": ">= 8"
|
||||
}
|
||||
},
|
||||
"node_modules/@pkgjs/parseargs": {
|
||||
"version": "0.11.0",
|
||||
"resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz",
|
||||
"integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"peer": true,
|
||||
"engines": {
|
||||
"node": ">=14"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/estree": {
|
||||
"version": "1.0.8",
|
||||
"dev": true,
|
||||
@ -758,6 +747,23 @@
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@types/mocha": {
|
||||
"version": "10.0.10",
|
||||
"resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-10.0.10.tgz",
|
||||
"integrity": "sha512-xPyYSz1cMPnJQhl0CLMH68j3gprKZaTjG3s5Vi+fDgx+uhG9NOXwbVt52eFS8ECyXhyKcjDLCBEqBExKuiZb7Q==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@types/mochawesome": {
|
||||
"version": "6.2.4",
|
||||
"resolved": "https://registry.npmjs.org/@types/mochawesome/-/mochawesome-6.2.4.tgz",
|
||||
"integrity": "sha512-tWnTmoWX1bpxutRYyrrgVtLeOUvaLxmoPsO+sMw8pvVFQ90UT2TkOQwu8usUGgGbEajMOIIarSW3hpaA7AavOQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@types/mocha": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/node": {
|
||||
"version": "24.5.2",
|
||||
"dev": true,
|
||||
@ -1835,54 +1841,6 @@
|
||||
"node": "^20.1.0 || ^22.0.0 || >=24.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/cypress-mochawesome-reporter": {
|
||||
"version": "3.8.4",
|
||||
"resolved": "https://registry.npmjs.org/cypress-mochawesome-reporter/-/cypress-mochawesome-reporter-3.8.4.tgz",
|
||||
"integrity": "sha512-ytn8emXyR5nz2+uqqgwqEwpeR9oILEIFSWl2lt2eyHICb2d0s/Hu7bPPo02bEf8UkqJohwg00yZ+jDH6oUqmzw==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"commander": "^10.0.1",
|
||||
"fs-extra": "^10.0.1",
|
||||
"mochawesome": "^7.1.3",
|
||||
"mochawesome-merge": "^4.2.1",
|
||||
"mochawesome-report-generator": "^6.2.0"
|
||||
},
|
||||
"bin": {
|
||||
"generate-mochawesome-report": "cli.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/LironEr"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"cypress": ">=6.2.0"
|
||||
}
|
||||
},
|
||||
"node_modules/cypress-mochawesome-reporter/node_modules/commander": {
|
||||
"version": "10.0.1",
|
||||
"resolved": "https://registry.npmjs.org/commander/-/commander-10.0.1.tgz",
|
||||
"integrity": "sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=14"
|
||||
}
|
||||
},
|
||||
"node_modules/cypress-mochawesome-reporter/node_modules/fs-extra": {
|
||||
"version": "10.1.0",
|
||||
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz",
|
||||
"integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"graceful-fs": "^4.2.0",
|
||||
"jsonfile": "^6.0.1",
|
||||
"universalify": "^2.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/cypress-split": {
|
||||
"version": "1.24.23",
|
||||
"dev": true,
|
||||
|
||||
@ -7,9 +7,10 @@
|
||||
"test": "cypress run --e2e --browser chromium",
|
||||
"test:open": "cypress open --e2e",
|
||||
"test:split:auto": "SPEC_COUNT=$(find e2e -name '*.cy.ts' | wc -l) && echo \"Running $SPEC_COUNT chunks in parallel\" && for i in $(seq 0 $((SPEC_COUNT-1))); do SPLIT=$SPEC_COUNT SPLIT_INDEX=$i cypress run --e2e --browser chromium & done; wait",
|
||||
"report:merge": "mochawesome-merge results/*.json > results/merged-report.json",
|
||||
"report:generate": "marge results/merged-report.json --reportDir results/html --reportTitle 'Utopia Map E2E Tests' --reportPageTitle 'Utopia Map E2E Test Report' --inline --charts",
|
||||
"report:clean": "rm -rf results screenshots videos",
|
||||
"report:merge": "mochawesome-merge 'results/*.json' -o results/merged-report.json",
|
||||
"report:generate": "marge results/merged-report.json --reportDir results/html --reportTitle 'Utopia Map E2E Tests' --reportPageTitle 'Utopia Map E2E Test Report' --inline --charts --showPassed --showFailed --showPending --showSkipped",
|
||||
"report:copy-screenshots": "if [ -d screenshots ]; then cp -r screenshots results/html/ 2>/dev/null || true; fi",
|
||||
"report:full": "npm run report:merge && npm run report:generate && npm run report:copy-screenshots",
|
||||
"lint": "eslint .",
|
||||
"lint:fix": "eslint . --fix"
|
||||
},
|
||||
@ -17,18 +18,19 @@
|
||||
"cypress",
|
||||
"cypress-split",
|
||||
"e2e",
|
||||
"mochawesome",
|
||||
"testing",
|
||||
"utopia-map"
|
||||
],
|
||||
"devDependencies": {
|
||||
"@eslint/js": "^9.36.0",
|
||||
"@types/mochawesome": "^6.2.4",
|
||||
"@types/node": "^24.5.2",
|
||||
"cypress": "^15.3.0",
|
||||
"cypress-mochawesome-reporter": "^3.8.2",
|
||||
"cypress-split": "^1.24.23",
|
||||
"eslint": "^9.36.0",
|
||||
"eslint-plugin-cypress": "^5.1.1",
|
||||
"mochawesome": "^7.1.3",
|
||||
"mochawesome": "^7.1.4",
|
||||
"mochawesome-merge": "^4.3.0",
|
||||
"mochawesome-report-generator": "^6.2.0",
|
||||
"typescript": "^5.9.2",
|
||||
|
||||
71
cypress/plugins/parallel-reporter.js
Normal file
71
cypress/plugins/parallel-reporter.js
Normal file
@ -0,0 +1,71 @@
|
||||
/**
|
||||
* Cypress Plugin for Enhanced Parallel Test Reporting
|
||||
* Handles mochawesome report generation for parallel test execution
|
||||
*/
|
||||
|
||||
const path = require('path')
|
||||
const fs = require('fs')
|
||||
|
||||
module.exports = (on, config) => {
|
||||
// Ensure results directory exists
|
||||
const resultsDir = path.join(config.projectRoot, 'results')
|
||||
if (!fs.existsSync(resultsDir)) {
|
||||
fs.mkdirSync(resultsDir, { recursive: true })
|
||||
}
|
||||
|
||||
// Configure mochawesome for parallel execution - JSON only for merging
|
||||
const splitIndex = process.env.SPLIT_INDEX || '0'
|
||||
const timestamp = new Date().toISOString().replace(/[:.]/g, '-')
|
||||
|
||||
config.reporterOptions = {
|
||||
...config.reporterOptions,
|
||||
reportFilename: `split-${splitIndex}-${timestamp}-[name]`,
|
||||
reportDir: resultsDir,
|
||||
overwrite: false,
|
||||
html: false, // No individual HTML files
|
||||
json: true, // Only JSON for merging into one report
|
||||
embeddedScreenshots: true,
|
||||
useInlineDiffs: true
|
||||
}
|
||||
|
||||
// Task for logging parallel execution info
|
||||
on('task', {
|
||||
log(message) {
|
||||
console.log(`[Parallel ${splitIndex}] ${message}`)
|
||||
return null
|
||||
},
|
||||
|
||||
logReportInfo() {
|
||||
console.log(`[Parallel ${splitIndex}] Report will be saved as: report-${splitIndex}-${timestamp}.json`)
|
||||
return null
|
||||
}
|
||||
})
|
||||
|
||||
// Before run hook
|
||||
on('before:run', (details) => {
|
||||
console.log(`[Parallel ${splitIndex}] Starting test execution`)
|
||||
console.log(`[Parallel ${splitIndex}] Browser: ${details.browser.name}`)
|
||||
console.log(`[Parallel ${splitIndex}] Specs: ${details.specs.length}`)
|
||||
return details
|
||||
})
|
||||
|
||||
// After run hook
|
||||
on('after:run', (results) => {
|
||||
console.log(`[Parallel ${splitIndex}] Test execution completed`)
|
||||
console.log(`[Parallel ${splitIndex}] Total tests: ${results.totalTests}`)
|
||||
console.log(`[Parallel ${splitIndex}] Passed: ${results.totalPassed}`)
|
||||
console.log(`[Parallel ${splitIndex}] Failed: ${results.totalFailed}`)
|
||||
|
||||
// Ensure the report file was created
|
||||
const reportFile = path.join(resultsDir, `report-${splitIndex}-${timestamp}.json`)
|
||||
if (fs.existsSync(reportFile)) {
|
||||
console.log(`[Parallel ${splitIndex}] ✅ Report saved: ${reportFile}`)
|
||||
} else {
|
||||
console.log(`[Parallel ${splitIndex}] ❌ Report not found: ${reportFile}`)
|
||||
}
|
||||
|
||||
return results
|
||||
})
|
||||
|
||||
return config
|
||||
}
|
||||
71
cypress/scripts/create-index-page.sh
Executable file
71
cypress/scripts/create-index-page.sh
Executable file
@ -0,0 +1,71 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
echo "=== Creating index page for consolidated report ==="
|
||||
|
||||
cat > results/html/index.html << 'EOF'
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Utopia Map E2E Test Report</title>
|
||||
<meta charset="utf-8">
|
||||
<style>
|
||||
body { font-family: Arial, sans-serif; margin: 40px; background: #f8f9fa; }
|
||||
.header { background: white; padding: 20px; border-radius: 8px; margin-bottom: 20px; box-shadow: 0 2px 4px #00000020; }
|
||||
.report-section { background: white; padding: 20px; border-radius: 8px; margin-bottom: 20px; box-shadow: 0 2px 4px #00000020; }
|
||||
.report-link { display: block; padding: 16px 20px; margin: 12px 0; background: #e3f2fd; border-radius: 8px; text-decoration: none; color: #1976d2; border-left: 4px solid #2196f3; font-size: 18px; font-weight: 500; }
|
||||
.report-link:hover { background: #bbdefb; }
|
||||
.meta { color: #666; font-size: 14px; margin: 4px 0; }
|
||||
.status { padding: 4px 8px; border-radius: 4px; font-size: 12px; font-weight: bold; }
|
||||
.status.failed { background: #ffebee; color: #c62828; }
|
||||
.status.passed { background: #e8f5e8; color: #2e7d32; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="header">
|
||||
<h1>Utopia Map E2E Test Report</h1>
|
||||
<div class="meta">Generated: $(date)</div>
|
||||
<div class="meta">Run ID: ${GITHUB_RUN_ID:-unknown}</div>
|
||||
<div class="meta">Commit: ${GITHUB_SHA:-unknown}</div>
|
||||
<div class="meta">Status: <span class="status failed">Tests Failed</span></div>
|
||||
</div>
|
||||
|
||||
<div class="report-section">
|
||||
<h2>📊 Consolidated Test Report</h2>
|
||||
<p>This report contains all test results from the parallel test execution, merged into one comprehensive view with screenshots embedded directly in failing test cases.</p>
|
||||
<a href="merged-report.html" class="report-link">
|
||||
📈 View Complete Test Report (All Specs)
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div class="report-section">
|
||||
<h2>📸 Test Screenshots</h2>
|
||||
<p>Screenshots are automatically embedded within their respective failing test cases in the main report. No separate screenshot viewing required.</p>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
setTimeout(() => {
|
||||
window.location.href = 'merged-report.html';
|
||||
}, 3000);
|
||||
|
||||
let countdown = 3;
|
||||
const countdownEl = document.createElement('div');
|
||||
countdownEl.style.cssText = 'position: fixed; top: 20px; right: 20px; background: #2196f3; color: white; padding: 10px 15px; border-radius: 4px; font-size: 14px;';
|
||||
countdownEl.textContent = `Auto-redirecting in ${countdown}s...`;
|
||||
document.body.appendChild(countdownEl);
|
||||
|
||||
const timer = setInterval(() => {
|
||||
countdown--;
|
||||
if (countdown > 0) {
|
||||
countdownEl.textContent = `Auto-redirecting in ${countdown}s...`;
|
||||
} else {
|
||||
clearInterval(timer);
|
||||
countdownEl.textContent = 'Redirecting...';
|
||||
}
|
||||
}, 1000);
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
EOF
|
||||
|
||||
echo "✅ Simple index page created with auto-redirect to consolidated report"
|
||||
25
cypress/scripts/generate-html-report.sh
Executable file
25
cypress/scripts/generate-html-report.sh
Executable file
@ -0,0 +1,25 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
echo "=== Generating HTML report with embedded screenshots ==="
|
||||
|
||||
if [ ! -f "results/merged-report.json" ]; then
|
||||
echo "❌ No merged JSON found, cannot generate consolidated report"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Generating comprehensive HTML report from merged JSON..."
|
||||
npm run report:generate
|
||||
|
||||
if [ ! -f "results/html/merged-report.html" ]; then
|
||||
echo "❌ HTML generation failed"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "✅ Consolidated HTML report generated successfully"
|
||||
echo "Report size: $(wc -c < results/html/merged-report.html) bytes"
|
||||
|
||||
npm run report:copy-screenshots
|
||||
|
||||
echo "=== Final consolidated report ready ==="
|
||||
ls -la results/html/
|
||||
35
cypress/scripts/merge-reports.sh
Executable file
35
cypress/scripts/merge-reports.sh
Executable file
@ -0,0 +1,35 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
echo "=== Merging all JSON reports into one consolidated report ==="
|
||||
|
||||
json_count=$(find results/ -name "*.json" -type f 2>/dev/null | wc -l)
|
||||
echo "Found $json_count JSON report files from parallel test execution"
|
||||
|
||||
if [ "$json_count" -gt 0 ]; then
|
||||
echo "=== JSON files found ==="
|
||||
find results/ -name "*.json" -type f | sort
|
||||
|
||||
echo "=== Merging all reports into one ==="
|
||||
npm run report:merge
|
||||
|
||||
if [ ! -f "results/merged-report.json" ]; then
|
||||
echo "❌ Merge failed - no merged-report.json created"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "✅ Successfully merged $json_count JSON reports into one"
|
||||
echo "Merged report size: $(wc -c < results/merged-report.json) bytes"
|
||||
|
||||
report=$(cat results/merged-report.json)
|
||||
echo "Consolidated report stats:"
|
||||
echo " - Total tests: $(echo "$report" | node -pe 'JSON.parse(require("fs").readFileSync(0)).stats?.tests || 0')"
|
||||
echo " - Passed: $(echo "$report" | node -pe 'JSON.parse(require("fs").readFileSync(0)).stats?.passes || 0')"
|
||||
echo " - Failed: $(echo "$report" | node -pe 'JSON.parse(require("fs").readFileSync(0)).stats?.failures || 0')"
|
||||
echo " - Duration: $(echo "$report" | node -pe 'JSON.parse(require("fs").readFileSync(0)).stats?.duration || 0')ms"
|
||||
else
|
||||
echo "❌ No JSON reports found to merge"
|
||||
echo "Creating empty report structure..."
|
||||
mkdir -p results
|
||||
echo '{"stats":{"tests":0,"passes":0,"failures":0},"results":[]}' > results/merged-report.json
|
||||
fi
|
||||
@ -2,8 +2,8 @@
|
||||
|
||||
import './commands'
|
||||
|
||||
// This file is processed and loaded automatically before your test files.
|
||||
// This is a great place to put global configuration and behavior that modifies Cypress.
|
||||
// for screenshot embedding
|
||||
import addContext from 'mochawesome/addContext'
|
||||
|
||||
// Global exception handler
|
||||
Cypress.on('uncaught:exception', (err) => {
|
||||
@ -11,3 +11,34 @@ Cypress.on('uncaught:exception', (err) => {
|
||||
// returning false here prevents Cypress from failing the test
|
||||
return false
|
||||
})
|
||||
|
||||
// Add screenshots of failed tests to mochawesome report
|
||||
Cypress.on('test:after:run', (test, runnable) => {
|
||||
if (test.state === 'failed') {
|
||||
const adjustedSpecPath = Cypress.spec.relative.replace(/^e2e\//, '')
|
||||
|
||||
// Build the full test hierarchy title like Cypress does for screenshot naming
|
||||
const titles: string[] = []
|
||||
let current = runnable
|
||||
|
||||
while (current && current.parent) {
|
||||
if (current.title) {
|
||||
titles.unshift(current.title)
|
||||
}
|
||||
current = current.parent
|
||||
}
|
||||
|
||||
const fullTitle = titles.join(' -- ').replace(/:/g, '')
|
||||
|
||||
const screenshot = `screenshots/${adjustedSpecPath}/${fullTitle} (failed).png`
|
||||
addContext({ test }, screenshot)
|
||||
|
||||
// Also add any retry screenshots if they exist
|
||||
const screenshot2 = `screenshots/${adjustedSpecPath}/${fullTitle} (failed) (attempt 2).png`
|
||||
const screenshot3 = `screenshots/${adjustedSpecPath}/${fullTitle} (failed) (attempt 3).png`
|
||||
|
||||
// Add retry screenshots (mochawesome will handle non-existent files gracefully)
|
||||
addContext({ test }, screenshot2)
|
||||
addContext({ test }, screenshot3)
|
||||
}
|
||||
})
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user