From 0345520cf2a490dc25ad1ac65d7d405e32a708c1 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+copilot@users.noreply.github.com> Date: 2025年8月23日 15:51:58 +0000 Subject: [PATCH 01/11] Initial plan From bb926263f4cbe7b92474a320d0ad3f3acad5375a Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+copilot@users.noreply.github.com> Date: 2025年8月23日 16:03:36 +0000 Subject: [PATCH 02/11] Implement complete HTML reporter for CodeceptJS Co-authored-by: kobenguyent <7845001+kobenguyent@users.noreply.github.com> --- lib/plugin/htmlReporter.js | 639 ++++++++++++++++++ output/report.html | 528 +++++++++++++++ .../html-reporter-plugin/artifacts_test.js | 14 + .../html-reporter-plugin/codecept.conf.js | 21 + .../html-reporter_test.js | 16 + .../html-reporter-plugin/output/report.html | 528 +++++++++++++++ test/runner/html-reporter-plugin_test.js | 49 ++ 7 files changed, 1795 insertions(+) create mode 100644 lib/plugin/htmlReporter.js create mode 100644 output/report.html create mode 100644 test/data/sandbox/configs/html-reporter-plugin/artifacts_test.js create mode 100644 test/data/sandbox/configs/html-reporter-plugin/codecept.conf.js create mode 100644 test/data/sandbox/configs/html-reporter-plugin/html-reporter_test.js create mode 100644 test/data/sandbox/configs/html-reporter-plugin/output/report.html create mode 100644 test/runner/html-reporter-plugin_test.js diff --git a/lib/plugin/htmlReporter.js b/lib/plugin/htmlReporter.js new file mode 100644 index 000000000..737a65c7c --- /dev/null +++ b/lib/plugin/htmlReporter.js @@ -0,0 +1,639 @@ +const fs = require('fs') +const path = require('path') +const mkdirp = require('mkdirp') +const crypto = require('crypto') +const { template } = require('../utils') + +const event = require('../event') +const output = require('../output') + +const defaultConfig = { + output: global.output_dir || './output', + reportFileName: 'report.html', + includeArtifacts: true, + showSteps: true, + showSkipped: true, +} + +/** + * HTML Reporter Plugin for CodeceptJS + * + * Generates comprehensive HTML reports showing: + * - Test statistics + * - Feature/Scenario details + * - Individual step results + * - Test artifacts (screenshots, etc.) + * + * ## Configuration + * + * ```js + * "plugins": { + * "htmlReporter": { + * "enabled": true, + * "output": "./output", + * "reportFileName": "report.html", + * "includeArtifacts": true, + * "showSteps": true, + * "showSkipped": true + * } + * } + * ``` + */ +module.exports = function (config) { + const options = { ...defaultConfig, ...config } + let reportData = { + stats: {}, + tests: [], + failures: [], + startTime: null, + endTime: null, + } + let currentTestSteps = [] + + // Initialize report directory + const reportDir = path.resolve(options.output) + mkdirp.sync(reportDir) + + // Track overall test execution + event.dispatcher.on(event.all.before, () => { + reportData.startTime = new Date() + output.plugin('htmlReporter', 'Starting HTML report generation...') + }) + + // Track test start to initialize steps collection + event.dispatcher.on(event.test.before, test => { + currentTestSteps = [] + }) + + // Collect step information + event.dispatcher.on(event.step.started, step => { + step.htmlReporterStartTime = Date.now() + }) + + event.dispatcher.on(event.step.finished, step => { + if (step.htmlReporterStartTime) { + step.duration = Date.now() - step.htmlReporterStartTime + } + currentTestSteps.push({ + name: step.name, + actor: step.actor, + args: step.args || [], + status: step.failed ? 'failed' : 'success', + duration: step.duration || 0, + }) + }) + + // Collect test results + event.dispatcher.on(event.test.finished, test => { + reportData.tests.push({ + ...test, + id: generateTestId(test), + duration: test.duration || 0, + steps: [...currentTestSteps], // Copy the steps + artifacts: test.artifacts || [], + }) + }) + + // Generate final report + event.dispatcher.on(event.all.result, result => { + reportData.endTime = new Date() + reportData.stats = result.stats + reportData.failures = result.failures || [] + reportData.duration = reportData.endTime - reportData.startTime + + generateHtmlReport(reportData, options) + }) + + function generateTestId(test) { + return crypto + .createHash('sha256') + .update(`${test.parent?.title || 'unknown'}_${test.title}`) + .digest('hex') + .substring(0, 8) + } + + function generateHtmlReport(data, config) { + const reportPath = path.join(reportDir, config.reportFileName) + + const html = template(getHtmlTemplate(), { + title: 'CodeceptJS Test Report', + timestamp: data.endTime.toISOString(), + duration: formatDuration(data.duration), + stats: JSON.stringify(data.stats), + statsHtml: generateStatsHtml(data.stats), + testsHtml: generateTestsHtml(data.tests, config), + failuresHtml: generateFailuresHtml(data.failures), + cssStyles: getCssStyles(), + jsScripts: getJsScripts(), + }) + + fs.writeFileSync(reportPath, html) + output.print(`HTML Report saved to: ${reportPath}`) + } + + function generateStatsHtml(stats) { + const passed = stats.passes || 0 + const failed = stats.failures || 0 + const pending = stats.pending || 0 + const total = stats.tests || 0 + + return ` +
+
+

Total

+ ${total} +
+
+

Passed

+ ${passed} +
+
+

Failed

+ ${failed} +
+
+

Pending

+ ${pending} +
+
+ ` + } + + function generateTestsHtml(tests, config) { + if (!tests || tests.length === 0) { + return '

No tests found.

' + } + + return tests.map(test => { + const statusClass = test.state || 'unknown' + const feature = test.parent?.title || 'Unknown Feature' + const steps = config.showSteps && test.steps ? generateStepsHtml(test.steps) : '' + const artifacts = config.includeArtifacts && test.artifacts ? generateArtifactsHtml(test.artifacts) : '' + + return ` +
+
+ くろまる +

${test.title}

+ ${feature} + ${formatDuration(test.duration)} +
+
+ ${test.err ? `
${escapeHtml(test.err.message || '').replace(/\x1b\[[0-9;]*m/g, '')}
` : ''} + ${steps} + ${artifacts} +
+
+ ` + }).join('') + } + + function generateStepsHtml(steps) { + if (!steps || steps.length === 0) return '' + + const stepsHtml = steps.map(step => { + const statusClass = step.status || 'unknown' + const args = step.args ? step.args.map(arg => JSON.stringify(arg)).join(', ') : '' + const stepName = step.name || 'unknown step' + const actor = step.actor || 'I' + + return ` +
+ くろまる + ${actor}.${stepName}(${args}) + ${formatDuration(step.duration)} +
+ ` + }).join('') + + return ` +
+

Steps:

+
${stepsHtml}
+
+ ` + } + + function generateArtifactsHtml(artifacts) { + if (!artifacts || artifacts.length === 0) return '' + + const artifactsHtml = artifacts.map(artifact => { + if (typeof artifact === 'string' && artifact.match(/\.(png|jpg|jpeg|gif)$/i)) { + const relativePath = path.relative(reportDir, artifact) + return `Screenshot` + } + return `
${escapeHtml(artifact.toString())}
` + }).join('') + + return ` +
+

Artifacts:

+
${artifactsHtml}
+
+ ` + } + + function generateFailuresHtml(failures) { + if (!failures || failures.length === 0) { + return '

No failures.

' + } + + return failures.map((failure, index) => { + const failureText = failure.toString().replace(/\x1b\[[0-9;]*m/g, '') // Remove ANSI escape codes + return ` +
+

Failure ${index + 1}

+
${escapeHtml(failureText)}
+
+ ` + }).join('') + } + + function formatDuration(duration) { + if (!duration) return '0ms' + if (duration < 1000) return `${duration}ms` + return `${(duration / 1000).toFixed(2)}s` + } + + function escapeHtml(unsafe) { + return unsafe + .replace(/&/g, '&') + .replace(//g, '>') + .replace(/"/g, '"') + .replace(/'/g, ''') + } + + function getHtmlTemplate() { + return ` + + + + + + {{title}} + + +
+
+

{{title}}

+
+ Generated: {{timestamp}} + Duration: {{duration}} +
+
+ +
+
+

Test Statistics

+ {{statsHtml}} +
+ +
+

Test Results

+
+ {{testsHtml}} +
+
+ +
+

Failures

+
+ {{failuresHtml}} +
+
+
+ + +
+ +
+ + +

AltStyle によって変換されたページ (->オリジナル) /

+ + ` + } + + function getCssStyles() { + return ` +* { + margin: 0; + padding: 0; + box-sizing: border-box; +} + +body { + font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; + line-height: 1.6; + color: #333; + background-color: #f5f5f5; +} + +.report-header { + background: #2c3e50; + color: white; + padding: 2rem 1rem; + text-align: center; +} + +.report-header h1 { + margin-bottom: 0.5rem; + font-size: 2.5rem; +} + +.report-meta { + font-size: 0.9rem; + opacity: 0.8; +} + +.report-meta span { + margin: 0 1rem; +} + +.report-content { + max-width: 1200px; + margin: 2rem auto; + padding: 0 1rem; +} + +.stats-section, .tests-section, .failures-section { + background: white; + margin-bottom: 2rem; + border-radius: 8px; + box-shadow: 0 2px 4px rgba(0,0,0,0.1); + overflow: hidden; +} + +.stats-section h2, .tests-section h2, .failures-section h2 { + background: #34495e; + color: white; + padding: 1rem; + margin: 0; +} + +.stats-cards { + display: flex; + flex-wrap: wrap; + gap: 1rem; + padding: 1rem; +} + +.stat-card { + flex: 1; + min-width: 150px; + padding: 1rem; + text-align: center; + border-radius: 4px; + color: white; +} + +.stat-card.total { background: #3498db; } +.stat-card.passed { background: #27ae60; } +.stat-card.failed { background: #e74c3c; } +.stat-card.pending { background: #f39c12; } + +.stat-card h3 { + font-size: 0.9rem; + margin-bottom: 0.5rem; +} + +.stat-number { + font-size: 2rem; + font-weight: bold; +} + +.test-item { + border-bottom: 1px solid #eee; + margin: 0; +} + +.test-item:last-child { + border-bottom: none; +} + +.test-header { + display: flex; + align-items: center; + padding: 1rem; + cursor: pointer; + transition: background-color 0.2s; +} + +.test-header:hover { + background-color: #f8f9fa; +} + +.test-status { + font-size: 1.2rem; + margin-right: 0.5rem; +} + +.test-status.passed { color: #27ae60; } +.test-status.failed { color: #e74c3c; } +.test-status.pending { color: #f39c12; } +.test-status.skipped { color: #95a5a6; } + +.test-title { + flex: 1; + font-size: 1.1rem; + font-weight: 500; +} + +.test-feature { + background: #ecf0f1; + padding: 0.25rem 0.5rem; + border-radius: 4px; + font-size: 0.8rem; + color: #34495e; + margin-right: 0.5rem; +} + +.test-duration { + font-size: 0.8rem; + color: #7f8c8d; +} + +.test-details { + display: none; + padding: 1rem; + background: #f8f9fa; + border-top: 1px solid #e9ecef; +} + +.error-message { + background: #fee; + border: 1px solid #fcc; + border-radius: 4px; + padding: 1rem; + margin-bottom: 1rem; +} + +.error-message pre { + color: #c0392b; + font-family: 'Courier New', monospace; + font-size: 0.9rem; + white-space: pre-wrap; + word-wrap: break-word; +} + +.steps-section, .artifacts-section { + margin-top: 1rem; +} + +.steps-section h4, .artifacts-section h4 { + color: #34495e; + margin-bottom: 0.5rem; + font-size: 1rem; +} + +.step-item { + display: flex; + align-items: center; + padding: 0.5rem 0; + border-bottom: 1px solid #ecf0f1; +} + +.step-item:last-child { + border-bottom: none; +} + +.step-status { + margin-right: 0.5rem; +} + +.step-status.success { color: #27ae60; } +.step-status.failed { color: #e74c3c; } + +.step-title { + flex: 1; + font-family: 'Courier New', monospace; + font-size: 0.9rem; +} + +.step-duration { + font-size: 0.8rem; + color: #7f8c8d; +} + +.artifacts-list { + display: flex; + flex-wrap: wrap; + gap: 0.5rem; +} + +.artifact-image { + max-width: 200px; + max-height: 150px; + border: 1px solid #ddd; + border-radius: 4px; + cursor: pointer; + transition: transform 0.2s; +} + +.artifact-image:hover { + transform: scale(1.05); +} + +.artifact-item { + background: #ecf0f1; + padding: 0.5rem; + border-radius: 4px; + font-size: 0.9rem; +} + +.modal { + display: none; + position: fixed; + z-index: 1000; + left: 0; + top: 0; + width: 100%; + height: 100%; + background-color: rgba(0,0,0,0.8); + cursor: pointer; +} + +.modal img { + position: absolute; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + max-width: 90%; + max-height: 90%; + border-radius: 4px; +} + +.failure-item { + padding: 1rem; + margin-bottom: 1rem; + border: 1px solid #fcc; + border-radius: 4px; + background: #fee; +} + +.failure-item h4 { + color: #c0392b; + margin-bottom: 0.5rem; +} + +.failure-details { + color: #333; + font-family: 'Courier New', monospace; + font-size: 0.9rem; + white-space: pre-wrap; + word-wrap: break-word; +} + +@media (max-width: 768px) { + .stats-cards { + flex-direction: column; + } + + .test-header { + flex-direction: column; + align-items: stretch; + gap: 0.5rem; + } + + .test-feature, .test-duration { + align-self: flex-start; + } +} + ` + } + + function getJsScripts() { + return ` +function toggleTestDetails(testId) { + const details = document.getElementById('details-' + testId); + if (details.style.display === 'none' || details.style.display === '') { + details.style.display = 'block'; + } else { + details.style.display = 'none'; + } +} + +function openImageModal(src) { + const modal = document.getElementById('imageModal'); + const modalImg = document.getElementById('modalImage'); + modalImg.src = src; + modal.style.display = 'block'; +} + +function closeImageModal() { + const modal = document.getElementById('imageModal'); + modal.style.display = 'none'; +} + +// Initialize - hide failures section if no failures +document.addEventListener('DOMContentLoaded', function() { + const failuresSection = document.querySelector('.failures-section'); + const failureItems = document.querySelectorAll('.failure-item'); + if (failureItems.length === 0) { + failuresSection.style.display = 'none'; + } +}); + ` + } +} \ No newline at end of file diff --git a/output/report.html b/output/report.html new file mode 100644 index 000000000..5c17c9401 --- /dev/null +++ b/output/report.html @@ -0,0 +1,528 @@ + + + + + + + CodeceptJS Test Report + + + +
+

CodeceptJS Test Report

+
+ Generated: 2025年08月23日T16:02:47.301Z + Duration: 27ms +
+
+ +
+
+

Test Statistics

+ +
+
+

Total

+ 3 +
+
+

Passed

+ 1 +
+
+

Failed

+ 2 +
+
+

Pending

+ 0 +
+
+ +
+ +
+

Test Results

+
+ +
+
+ くろまる +

test with multiple steps

+ HTML Reporter Test + 0ms +
+
+
+ File package.json not found in /home/runner/work/CodeceptJS/CodeceptJS/test/data/sandbox/configs/html-reporter-plugin
+ +
+

Steps:

+
+
+ くろまる + I.amInPath(".") + 1ms +
+ +
+ くろまる + I.seeFile("package.json") + 1ms +
+
+
+ + +
+
+ +
+
+ くろまる +

test that will fail

+ HTML Reporter Test + 0ms +
+
+
+ File this-file-should-not-exist.txt not found in /home/runner/work/CodeceptJS/CodeceptJS/test/data/sandbox/configs/html-reporter-plugin
+ +
+

Steps:

+
+
+ くろまる + I.amInPath(".") + 0ms +
+ +
+ くろまる + I.seeFile("this-file-should-not-exist.txt") + 0ms +
+
+
+ + +
+
+ +
+
+ くろまる +

test that will pass

+ HTML Reporter Test + 0ms +
+
+ + +
+

Steps:

+
+
+ くろまる + I.amInPath(".") + 0ms +
+ +
+ くろまる + I.seeFile("codecept.conf.js") + 0ms +
+
+
+ + +
+
+ +
+
+ +
+

Failures

+
+ +
+

Failure 1

+
 %s) %s:
+%s
+%s
+,1,HTML Reporter Test
+ test with multiple steps,
+ 
+ File package.json not found in /home/runner/work/CodeceptJS/CodeceptJS/test/data/sandbox/configs/html-reporter-plugin
+ + expected - actual
+
+ -false
+ +true
+ , AssertionError [ERR_ASSERTION]: 
+ at FileSystem.seeFile (lib/helper/FileSystem.js:70:12)
+ at HelperStep.run (lib/step/helper.js:28:49)
+ 
+ 
+ ◯ File: file:///home/runner/work/CodeceptJS/CodeceptJS/test/data/sandbox/configs/html-reporter-plugin/html-reporter_test.js
+ 
+ ◯ Scenario Steps:
+ ✖ I.seeFile("package.json") at Test.<anonymous> (./html-reporter_test.js:5:5)
+ ✔ I.amInPath(".") at Test.<anonymous> (./html-reporter_test.js:4:5)
+ 
+
+ +
+

Failure 2

+
 %s) %s:
+%s
+%s
+,2,HTML Reporter Test
+ test that will fail,
+ 
+ File this-file-should-not-exist.txt not found in /home/runner/work/CodeceptJS/CodeceptJS/test/data/sandbox/configs/html-reporter-plugin
+ + expected - actual
+
+ -false
+ +true
+ , AssertionError [ERR_ASSERTION]: 
+ at FileSystem.seeFile (lib/helper/FileSystem.js:70:12)
+ at HelperStep.run (lib/step/helper.js:28:49)
+ 
+ 
+ ◯ File: file:///home/runner/work/CodeceptJS/CodeceptJS/test/data/sandbox/configs/html-reporter-plugin/html-reporter_test.js
+ 
+ ◯ Scenario Steps:
+ ✖ I.seeFile("this-file-should-not-exist.txt") at Test.<anonymous> (./html-reporter_test.js:10:5)
+ ✔ I.amInPath(".") at Test.<anonymous> (./html-reporter_test.js:9:5)
+ 
+
+ +
+
+
+ + +
+ +
+ + + + + \ No newline at end of file diff --git a/test/data/sandbox/configs/html-reporter-plugin/artifacts_test.js b/test/data/sandbox/configs/html-reporter-plugin/artifacts_test.js new file mode 100644 index 000000000..e0de9d354 --- /dev/null +++ b/test/data/sandbox/configs/html-reporter-plugin/artifacts_test.js @@ -0,0 +1,14 @@ +Feature('HTML Reporter with Artifacts Test') + +Scenario('test with artifacts', async ({ I }) => { + I.amInPath('.') + I.seeFile('codecept.conf.js') + + // Simulate adding test artifacts + const currentTest = global.codecept_dir ? require('../../../../lib/container').get('mocha') : null + if (currentTest && currentTest.currentTest) { + currentTest.currentTest.artifacts = currentTest.currentTest.artifacts || [] + currentTest.currentTest.artifacts.push('fake-screenshot-1.png') + currentTest.currentTest.artifacts.push('fake-screenshot-2.png') + } +}) \ No newline at end of file diff --git a/test/data/sandbox/configs/html-reporter-plugin/codecept.conf.js b/test/data/sandbox/configs/html-reporter-plugin/codecept.conf.js new file mode 100644 index 000000000..61e085e6c --- /dev/null +++ b/test/data/sandbox/configs/html-reporter-plugin/codecept.conf.js @@ -0,0 +1,21 @@ +exports.config = { + tests: './*_test.js', + output: './output', + helpers: { + FileSystem: {}, + }, + include: {}, + bootstrap: false, + plugins: { + htmlReporter: { + enabled: true, + output: './output', + reportFileName: 'report.html', + includeArtifacts: true, + showSteps: true, + showSkipped: true, + }, + }, + mocha: {}, + name: 'html-reporter-plugin tests', +} \ No newline at end of file diff --git a/test/data/sandbox/configs/html-reporter-plugin/html-reporter_test.js b/test/data/sandbox/configs/html-reporter-plugin/html-reporter_test.js new file mode 100644 index 000000000..1ec50a97d --- /dev/null +++ b/test/data/sandbox/configs/html-reporter-plugin/html-reporter_test.js @@ -0,0 +1,16 @@ +Feature('HTML Reporter Test') + +Scenario('test with multiple steps', ({ I }) => { + I.amInPath('.') + I.seeFile('package.json') +}) + +Scenario('test that will fail', ({ I }) => { + I.amInPath('.') + I.seeFile('this-file-should-not-exist.txt') +}) + +Scenario('test that will pass', ({ I }) => { + I.amInPath('.') + I.seeFile('codecept.conf.js') +}) \ No newline at end of file diff --git a/test/data/sandbox/configs/html-reporter-plugin/output/report.html b/test/data/sandbox/configs/html-reporter-plugin/output/report.html new file mode 100644 index 000000000..d894b3ca9 --- /dev/null +++ b/test/data/sandbox/configs/html-reporter-plugin/output/report.html @@ -0,0 +1,528 @@ + + + + + + + CodeceptJS Test Report + + + +
+

CodeceptJS Test Report

+
+ Generated: 2025年08月23日T16:02:38.627Z + Duration: 27ms +
+
+ +
+
+

Test Statistics

+ +
+
+

Total

+ 3 +
+
+

Passed

+ 1 +
+
+

Failed

+ 2 +
+
+

Pending

+ 0 +
+
+ +
+ +
+

Test Results

+
+ +
+
+ くろまる +

test with multiple steps

+ HTML Reporter Test + 0ms +
+
+
+ File package.json not found in /home/runner/work/CodeceptJS/CodeceptJS/test/data/sandbox/configs/html-reporter-plugin
+ +
+

Steps:

+
+
+ くろまる + I.amInPath(".") + 0ms +
+ +
+ くろまる + I.seeFile("package.json") + 1ms +
+
+
+ + +
+
+ +
+
+ くろまる +

test that will fail

+ HTML Reporter Test + 0ms +
+
+
+ File this-file-should-not-exist.txt not found in /home/runner/work/CodeceptJS/CodeceptJS/test/data/sandbox/configs/html-reporter-plugin
+ +
+

Steps:

+
+
+ くろまる + I.amInPath(".") + 0ms +
+ +
+ くろまる + I.seeFile("this-file-should-not-exist.txt") + 0ms +
+
+
+ + +
+
+ +
+
+ くろまる +

test that will pass

+ HTML Reporter Test + 0ms +
+
+ + +
+

Steps:

+
+
+ くろまる + I.amInPath(".") + 0ms +
+ +
+ くろまる + I.seeFile("codecept.conf.js") + 0ms +
+
+
+ + +
+
+ +
+
+ +
+

Failures

+
+ +
+

Failure 1

+
 %s) %s:
+%s
+%s
+,1,HTML Reporter Test
+ test with multiple steps,
+ 
+ File package.json not found in /home/runner/work/CodeceptJS/CodeceptJS/test/data/sandbox/configs/html-reporter-plugin
+ + expected - actual
+
+ -false
+ +true
+ , AssertionError [ERR_ASSERTION]: 
+ at FileSystem.seeFile (/home/runner/work/CodeceptJS/CodeceptJS/lib/helper/FileSystem.js:70:12)
+ at HelperStep.run (/home/runner/work/CodeceptJS/CodeceptJS/lib/step/helper.js:28:49)
+ 
+ 
+ ◯ File: file:///home/runner/work/CodeceptJS/CodeceptJS/test/data/sandbox/configs/html-reporter-plugin/html-reporter_test.js
+ 
+ ◯ Scenario Steps:
+ ✖ I.seeFile("package.json") at Test.<anonymous> (./html-reporter_test.js:5:5)
+ ✔ I.amInPath(".") at Test.<anonymous> (./html-reporter_test.js:4:5)
+ 
+
+ +
+

Failure 2

+
 %s) %s:
+%s
+%s
+,2,HTML Reporter Test
+ test that will fail,
+ 
+ File this-file-should-not-exist.txt not found in /home/runner/work/CodeceptJS/CodeceptJS/test/data/sandbox/configs/html-reporter-plugin
+ + expected - actual
+
+ -false
+ +true
+ , AssertionError [ERR_ASSERTION]: 
+ at FileSystem.seeFile (/home/runner/work/CodeceptJS/CodeceptJS/lib/helper/FileSystem.js:70:12)
+ at HelperStep.run (/home/runner/work/CodeceptJS/CodeceptJS/lib/step/helper.js:28:49)
+ 
+ 
+ ◯ File: file:///home/runner/work/CodeceptJS/CodeceptJS/test/data/sandbox/configs/html-reporter-plugin/html-reporter_test.js
+ 
+ ◯ Scenario Steps:
+ ✖ I.seeFile("this-file-should-not-exist.txt") at Test.<anonymous> (./html-reporter_test.js:10:5)
+ ✔ I.amInPath(".") at Test.<anonymous> (./html-reporter_test.js:9:5)
+ 
+
+ +
+
+
+ + +
+ +
+ + + + + \ No newline at end of file diff --git a/test/runner/html-reporter-plugin_test.js b/test/runner/html-reporter-plugin_test.js new file mode 100644 index 000000000..bda8c8b8f --- /dev/null +++ b/test/runner/html-reporter-plugin_test.js @@ -0,0 +1,49 @@ +const { expect } = require('expect') +const exec = require('child_process').exec +const { codecept_dir, codecept_run } = require('./consts') +const debug = require('debug')('codeceptjs:tests') +const fs = require('fs') +const path = require('path') + +const config_run_config = (config, grep, verbose = false) => `${codecept_run} ${verbose ? '--verbose' : ''} --config ${codecept_dir}/configs/html-reporter-plugin/${config} ${grep ? `--grep "${grep}"` : ''}` + +describe('CodeceptJS html-reporter-plugin', function () { + this.timeout(10000) + + it('should generate HTML report', done => { + exec(config_run_config('codecept.conf.js'), (err, stdout) => { + debug(stdout) + + // Check if HTML report file exists + const reportFile = path.join(`${codecept_dir}/configs/html-reporter-plugin`, 'output', 'report.html') + expect(fs.existsSync(reportFile)).toBe(true) + + // Read and validate HTML report content + const reportContent = fs.readFileSync(reportFile, 'utf8') + expect(reportContent).toContain('CodeceptJS Test Report') + expect(reportContent).toContain('Test Statistics') + expect(reportContent).toContain('Test Results') + + // Check for specific test features + expect(reportContent).toContain('HTML Reporter Test') // Feature name + expect(reportContent).toContain('test with multiple steps') // Scenario name + expect(reportContent).toContain('test that will fail') // Another scenario + expect(reportContent).toContain('test that will pass') // Another scenario + + // Validate that stats are included + expect(reportContent).toMatch(/Total.*Passed.*Failed/s) + + // Check basic HTML structure + expect(reportContent).toContain('') + expect(reportContent).toContain('') + expect(reportContent).toContain('') + expect(reportContent).toContain('') + + // Should contain CSS and JS + expect(reportContent).toContain(' - - + +
-

CodeceptJS Test Report

-
- Generated: 2025年08月23日T16:04:41.601Z - Duration: 29ms -
+

CodeceptJS Test Report

+
+ Generated: 2025年08月23日T16:28:10.912Z + Duration: 28ms +
-
-

Test Statistics

- -
-
-

Total

- 4 -
-
-

Passed

- 1 -
-
-

Failed

- 3 -
-
-

Pending

- 0 -
-
- -
- -
-

Test Results

-
- -
-
- くろまる -

test with multiple steps

- HTML Reporter Test - 0ms -
-
-
- File package.json not found in /home/runner/work/CodeceptJS/CodeceptJS/test/data/sandbox/configs/html-reporter-plugin
- -
-

Steps:

-
-
- くろまる - I.amInPath(".") - 0ms -
- -
- くろまる - I.seeFile("package.json") - 1ms -
-
-
- - +
+

Test Statistics

+ +
+
+

Total

+ 4
-
- -
-
- くろまる -

test that will fail

- HTML Reporter Test - 0ms +
+

Passed

+ 1
-
-
- File this-file-should-not-exist.txt not found in /home/runner/work/CodeceptJS/CodeceptJS/test/data/sandbox/configs/html-reporter-plugin
- -
-

Steps:

-
-
- くろまる - I.amInPath(".") - 0ms -
- -
- くろまる - I.seeFile("this-file-should-not-exist.txt") - 0ms -
-
-
- - +
+

Failed

+ 3
-
- -
-
- くろまる -

test that will pass

- HTML Reporter Test - 0ms +
+

Pending

+ 0
-
- - -
-

Steps:

-
-
- くろまる - I.amInPath(".") - 0ms
- -
- くろまる - I.seeFile("codecept.conf.js") - 0ms +
+ +
-
-
- - +
+ +
+

Test Results

+
+
+
+ くろまる +

test with multiple steps

+ HTML Reporter Test + 0ms +
+
+
 File package.json not found in /home/runner/work/CodeceptJS/CodeceptJS/test/data/sandbox/configs/html-reporter-plugin
+ +
+

Steps:

+
+
+ くろまる + I.amInPath(".") + 1ms +
+ +
+ くろまる + I.seeFile("package.json") + 1ms +
+
+
+
-
- -
-
- くろまる -

test with artifacts

- HTML Reporter with Artifacts Test - 0ms + +
+
+ くろまる +

test that will fail

+ HTML Reporter Test + 0ms +
+
+
 File this-file-should-not-exist.txt not found in /home/runner/work/CodeceptJS/CodeceptJS/test/data/sandbox/configs/html-reporter-plugin
+ +
+

Steps:

+
+
+ くろまる + I.amInPath(".") + 0ms +
+ +
+ くろまる + I.seeFile("this-file-should-not-exist.txt") + 1ms +
+
+
+
+
+ +
+
+ くろまる +

test that will pass

+ HTML Reporter Test + 0ms +
+
+
+

Steps:

+
+
+ くろまる + I.amInPath(".") + 0ms +
+ +
+ くろまる + I.seeFile("codecept.conf.js") + 0ms +
+
+
+
-
-
+
+ 
+
+ くろまる +

test with artifacts

+ HTML Reporter with Artifacts Test + 0ms +
+
+
+
 Cannot find module '../../../../lib/container'
 Require stack:
 - /home/runner/work/CodeceptJS/CodeceptJS/test/data/sandbox/configs/html-reporter-plugin/artifacts_test.js
 - /home/runner/work/CodeceptJS/CodeceptJS/node_modules/mocha/lib/mocha.js
 - /home/runner/work/CodeceptJS/CodeceptJS/node_modules/mocha/index.js
- ...
- -
-

Steps:

-
-
- くろまる - I.amInPath(".") - 0ms -
- -
- くろまる - I.seeFile("codecept.conf.js") - 0ms -
-
-
- - + ...
+
+ +
+

Steps:

+
+
+ くろまる + I.amInPath(".") + 0ms +
+ +
+ くろまる + I.seeFile("codecept.conf.js") + 0ms +
+
+
+
- -
-
- -
-

Failures

-
- -
-

Failure 1

-
 %s) %s:
+ 
+ +
+

Failures

+
+
+

Failure 1

+
+ %s) %s:
 %s
 %s
 ,1,HTML Reporter Test
@@ -491,12 +579,14 @@ 

Failure 1

◯ Scenario Steps: ✖ I.seeFile("package.json") at Test.<anonymous> (./html-reporter_test.js:5:5) ✔ I.amInPath(".") at Test.<anonymous> (./html-reporter_test.js:4:5) -
-
- -
-

Failure 2

-
 %s) %s:
+ 
+
+ +
+

Failure 2

+
+ %s) %s:
 %s
 %s
 ,2,HTML Reporter Test
@@ -517,12 +607,14 @@ 

Failure 2

◯ Scenario Steps: ✖ I.seeFile("this-file-should-not-exist.txt") at Test.<anonymous> (./html-reporter_test.js:10:5) ✔ I.amInPath(".") at Test.<anonymous> (./html-reporter_test.js:9:5) -
-
- -
-

Failure 3

-
 %s) %s:
+ 
+
+ +
+

Failure 3

+
+ %s) %s:
 %s
 %s
 ,3,HTML Reporter with Artifacts Test
@@ -538,49 +630,147 @@ 

Failure 3

◯ File: file:///home/runner/work/CodeceptJS/CodeceptJS/test/data/sandbox/configs/html-reporter-plugin/artifacts_test.js -
+ +
- - -
+
- +
- + - \ No newline at end of file diff --git a/test/data/sandbox/configs/html-reporter-plugin/output/report.html b/test/data/sandbox/configs/html-reporter-plugin/output/report.html index d894b3ca9..8b6ac651f 100644 --- a/test/data/sandbox/configs/html-reporter-plugin/output/report.html +++ b/test/data/sandbox/configs/html-reporter-plugin/output/report.html @@ -1,439 +1,564 @@ - - + - - - + + + CodeceptJS Test Report - - + +
-

CodeceptJS Test Report

-
- Generated: 2025年08月23日T16:02:38.627Z - Duration: 27ms -
+

CodeceptJS Test Report

+
+ Generated: 2025年08月23日T16:27:27.727Z + Duration: 30ms +
-
-

Test Statistics

- -
-
-

Total

- 3 -
-
-

Passed

- 1 -
-
-

Failed

- 2 -
-
-

Pending

- 0 -
-
- -
- -
-

Test Results

-
- -
-
- くろまる -

test with multiple steps

- HTML Reporter Test - 0ms +
+

Test Statistics

+ +
+
+

Total

+ 4
-
-
- File package.json not found in /home/runner/work/CodeceptJS/CodeceptJS/test/data/sandbox/configs/html-reporter-plugin
- -
-

Steps:

-
-
- くろまる - I.amInPath(".") - 0ms -
- -
- くろまる - I.seeFile("package.json") - 1ms -
-
-
- - +
+

Passed

+ 1
-
- -
-
- くろまる -

test that will fail

- HTML Reporter Test - 0ms +
+

Failed

+ 3 +
+
+

Pending

+ 0
-
-
- File this-file-should-not-exist.txt not found in /home/runner/work/CodeceptJS/CodeceptJS/test/data/sandbox/configs/html-reporter-plugin
- -
-

Steps:

-
-
- くろまる - I.amInPath(".") - 0ms
- -
- くろまる - I.seeFile("this-file-should-not-exist.txt") - 0ms +
+ +
-
-
- - +
+ +
+

Test Results

+
+
+
+ くろまる +

test with multiple steps

+ HTML Reporter Test + 0ms +
+
+
 File package.json not found in /home/runner/work/CodeceptJS/CodeceptJS/test/data/sandbox/configs/html-reporter-plugin
+ +
+

Steps:

+
+
+ くろまる + I.amInPath(".") + 1ms +
+ +
+ くろまる + I.seeFile("package.json") + 1ms +
+
+
+
-
- -
-
- くろまる -

test that will pass

- HTML Reporter Test - 0ms + +
+
+ くろまる +

test that will fail

+ HTML Reporter Test + 0ms +
+
+
 File this-file-should-not-exist.txt not found in /home/runner/work/CodeceptJS/CodeceptJS/test/data/sandbox/configs/html-reporter-plugin
+ +
+

Steps:

+
+
+ くろまる + I.amInPath(".") + 1ms +
+ +
+ くろまる + I.seeFile("this-file-should-not-exist.txt") + 0ms +
+
+
+
-
- - -
-

Steps:

-
-
- くろまる - I.amInPath(".") - 0ms -
- -
- くろまる - I.seeFile("codecept.conf.js") - 0ms -
-
-
- - + +
+
+ くろまる +

test that will pass

+ HTML Reporter Test + 0ms +
+
+
+

Steps:

+
+
+ くろまる + I.amInPath(".") + 0ms +
+ +
+ くろまる + I.seeFile("codecept.conf.js") + 0ms +
+
+
+
-
- + +
+
+ くろまる +

test with artifacts

+ HTML Reporter with Artifacts Test + 0ms +
+
+
+
+ Cannot find module '../../../../lib/container'
+ Require stack:
+ - /home/runner/work/CodeceptJS/CodeceptJS/test/data/sandbox/configs/html-reporter-plugin/artifacts_test.js
+ - /home/runner/work/CodeceptJS/CodeceptJS/node_modules/mocha/lib/mocha.js
+ - /home/runner/work/CodeceptJS/CodeceptJS/node_modules/mocha/index.js
+ ...
+
+ +
+

Steps:

+
+
+ くろまる + I.amInPath(".") + 0ms +
+ +
+ くろまる + I.seeFile("codecept.conf.js") + 0ms +
+
+
-
- -
-

Failures

-
- -
-

Failure 1

-
 %s) %s:
+ 
+
+
+ +
+

Failures

+
+
+

Failure 1

+
+ %s) %s:
 %s
 %s
 ,1,HTML Reporter Test
@@ -454,12 +579,14 @@ 

Failure 1

◯ Scenario Steps: ✖ I.seeFile("package.json") at Test.<anonymous> (./html-reporter_test.js:5:5) ✔ I.amInPath(".") at Test.<anonymous> (./html-reporter_test.js:4:5) -
-
- -
-

Failure 2

-
 %s) %s:
+ 
+
+ +
+

Failure 2

+
+ %s) %s:
 %s
 %s
 ,2,HTML Reporter Test
@@ -480,49 +607,170 @@ 

Failure 2

◯ Scenario Steps: ✖ I.seeFile("this-file-should-not-exist.txt") at Test.<anonymous> (./html-reporter_test.js:10:5) ✔ I.amInPath(".") at Test.<anonymous> (./html-reporter_test.js:9:5) -
+ +
+ +
+

Failure 3

+
+ %s) %s:
+ %s
+%s
+,3,HTML Reporter with Artifacts Test
+ test with artifacts,
+ Cannot find module '../../../../lib/container'
+ Require stack:
+ - /home/runner/work/CodeceptJS/CodeceptJS/test/data/sandbox/configs/html-reporter-plugin/artifacts_test.js
+ - /home/runner/work/CodeceptJS/CodeceptJS/node_modules/mocha/lib/mocha.js
+ - /home/runner/work/CodeceptJS/CodeceptJS/node_modules/mocha/index.js
+ ..., Error: Cannot find module '../../../../lib/container'
+ Require stack:
+ - /home/runner/work/CodeceptJS/CodeceptJS/test/data/sandbox/configs/html-reporter-plugin/artifacts_test.js
+ 
+ 
+ ◯ File: file:///home/runner/work/CodeceptJS/CodeceptJS/test/data/sandbox/configs/html-reporter-plugin/artifacts_test.js
+ 
+
- -
-
+
- +
- + - \ No newline at end of file diff --git a/test/runner/html-reporter-plugin_test.js b/test/runner/html-reporter-plugin_test.js index bda8c8b8f..707f95f6b 100644 --- a/test/runner/html-reporter-plugin_test.js +++ b/test/runner/html-reporter-plugin_test.js @@ -23,7 +23,7 @@ describe('CodeceptJS html-reporter-plugin', function () { expect(reportContent).toContain('CodeceptJS Test Report') expect(reportContent).toContain('Test Statistics') expect(reportContent).toContain('Test Results') - + // Check for specific test features expect(reportContent).toContain('HTML Reporter Test') // Feature name expect(reportContent).toContain('test with multiple steps') // Scenario name @@ -32,13 +32,23 @@ describe('CodeceptJS html-reporter-plugin', function () { // Validate that stats are included expect(reportContent).toMatch(/Total.*Passed.*Failed/s) - + + // Check for pie chart functionality + expect(reportContent).toContain('pie-chart-container') + expect(reportContent).toContain('statsChart') + expect(reportContent).toContain('drawPieChart') + expect(reportContent).toMatch(/window\.chartData\s*=/) + + // Check for hooks styles (even if not used in this test) + expect(reportContent).toContain('hooks-section') + expect(reportContent).toContain('hook-item') + // Check basic HTML structure expect(reportContent).toContain('') expect(reportContent).toContain('') expect(reportContent).toContain('') expect(reportContent).toContain('') - + // Should contain CSS and JS expect(reportContent).toContain(' - - -
-

CodeceptJS Test Report

-
- Generated: 2025年08月23日T17:02:58.961Z - Duration: 28ms -
-
- -
-
-

Test Statistics

- -
-
-

Total

- 4 -
-
-

Passed

- 1 -
-
-

Failed

- 3 -
-
-

Pending

- 0 -
-
-
- - -
-
- -
-

Test Results

-
-
-
- くろまる -

test with multiple steps

- HTML Reporter Test - 0ms -
-
-
 File package.json not found in /home/runner/work/CodeceptJS/CodeceptJS/test/data/sandbox/configs/html-reporter-plugin
- -
-

Steps:

-
-
- くろまる - I.amInPath(".") - 0ms -
- -
- くろまる - I.seeFile("package.json") - 1ms -
-
-
-
-
- -
-
- くろまる -

test that will fail

- HTML Reporter Test - 0ms -
-
-
 File this-file-should-not-exist.txt not found in /home/runner/work/CodeceptJS/CodeceptJS/test/data/sandbox/configs/html-reporter-plugin
- -
-

Steps:

-
-
- くろまる - I.amInPath(".") - 0ms -
- -
- くろまる - I.seeFile("this-file-should-not-exist.txt") - 0ms -
-
-
-
-
- -
-
- くろまる -

test that will pass

- HTML Reporter Test - 0ms -
-
-
-

Steps:

-
-
- くろまる - I.amInPath(".") - 0ms -
- -
- くろまる - I.seeFile("codecept.conf.js") - 0ms -
-
-
-
-
- -
-
- くろまる -

test with artifacts

- HTML Reporter with Artifacts Test - 0ms -
-
-
-
- Cannot find module '../../../../lib/container'
- Require stack:
- - /home/runner/work/CodeceptJS/CodeceptJS/test/data/sandbox/configs/html-reporter-plugin/artifacts_test.js
- - /home/runner/work/CodeceptJS/CodeceptJS/node_modules/mocha/lib/mocha.js
- - /home/runner/work/CodeceptJS/CodeceptJS/node_modules/mocha/index.js
- ...
-
- -
-

Steps:

-
-
- くろまる - I.amInPath(".") - 0ms -
- -
- くろまる - I.seeFile("codecept.conf.js") - 0ms -
-
-
-
-
-
-
- -
-

Failures

-
-
-

Failure 1

-
- %s) %s:
-%s
-%s
-,1,HTML Reporter Test
- test with multiple steps,
- 
- File package.json not found in /home/runner/work/CodeceptJS/CodeceptJS/test/data/sandbox/configs/html-reporter-plugin
- + expected - actual
-
- -false
- +true
- , AssertionError [ERR_ASSERTION]: 
- at FileSystem.seeFile (lib/helper/FileSystem.js:70:12)
- at HelperStep.run (lib/step/helper.js:28:49)
- 
- 
- ◯ File: file:///home/runner/work/CodeceptJS/CodeceptJS/test/data/sandbox/configs/html-reporter-plugin/html-reporter_test.js
- 
- ◯ Scenario Steps:
- ✖ I.seeFile("package.json") at Test.<anonymous> (./html-reporter_test.js:5:5)
- ✔ I.amInPath(".") at Test.<anonymous> (./html-reporter_test.js:4:5)
- 
-
- -
-

Failure 2

-
- %s) %s:
-%s
-%s
-,2,HTML Reporter Test
- test that will fail,
- 
- File this-file-should-not-exist.txt not found in /home/runner/work/CodeceptJS/CodeceptJS/test/data/sandbox/configs/html-reporter-plugin
- + expected - actual
-
- -false
- +true
- , AssertionError [ERR_ASSERTION]: 
- at FileSystem.seeFile (lib/helper/FileSystem.js:70:12)
- at HelperStep.run (lib/step/helper.js:28:49)
- 
- 
- ◯ File: file:///home/runner/work/CodeceptJS/CodeceptJS/test/data/sandbox/configs/html-reporter-plugin/html-reporter_test.js
- 
- ◯ Scenario Steps:
- ✖ I.seeFile("this-file-should-not-exist.txt") at Test.<anonymous> (./html-reporter_test.js:10:5)
- ✔ I.amInPath(".") at Test.<anonymous> (./html-reporter_test.js:9:5)
- 
-
- -
-

Failure 3

-
- %s) %s:
- %s
-%s
-,3,HTML Reporter with Artifacts Test
- test with artifacts,
- Cannot find module '../../../../lib/container'
- Require stack:
- - /home/runner/work/CodeceptJS/CodeceptJS/test/data/sandbox/configs/html-reporter-plugin/artifacts_test.js
- - /home/runner/work/CodeceptJS/CodeceptJS/node_modules/mocha/lib/mocha.js
- - /home/runner/work/CodeceptJS/CodeceptJS/node_modules/mocha/index.js
- ..., Error: Cannot find module '../../../../lib/container'
- Require stack:
- - /home/runner/work/CodeceptJS/CodeceptJS/test/data/sandbox/configs/html-reporter-plugin/artifacts_test.js
- 
- 
- ◯ File: file:///home/runner/work/CodeceptJS/CodeceptJS/test/data/sandbox/configs/html-reporter-plugin/artifacts_test.js
- 
-
-
-
-
- - -
- -
- - - - diff --git a/test/data/sandbox/configs/html-reporter-plugin/output/test-history.json b/test/data/sandbox/configs/html-reporter-plugin/output/test-history.json deleted file mode 100644 index 074dfc84d..000000000 --- a/test/data/sandbox/configs/html-reporter-plugin/output/test-history.json +++ /dev/null @@ -1,18 +0,0 @@ -[ - { - "timestamp": "2025-08-24T04:44:30.328Z", - "duration": 31, - "stats": { - "passes": 1, - "failures": 3, - "tests": 4, - "pending": 0, - "failedHooks": 0, - "start": "2025-08-24T04:44:30.304Z", - "end": "2025-08-24T04:44:30.324Z", - "duration": 20 - }, - "retries": 0, - "testCount": 4 - } -] diff --git a/test/data/sandbox/configs/html-reporter-plugin/output/test-stats.json b/test/data/sandbox/configs/html-reporter-plugin/output/test-stats.json deleted file mode 100644 index 3af88d504..000000000 --- a/test/data/sandbox/configs/html-reporter-plugin/output/test-stats.json +++ /dev/null @@ -1,65 +0,0 @@ -{ - "timestamp": "2025-08-24T04:44:29.809Z", - "duration": 30, - "stats": { - "passes": 1, - "failures": 3, - "tests": 4, - "pending": 0, - "failedHooks": 0, - "start": "2025-08-24T04:44:29.785Z", - "end": "2025-08-24T04:44:29.805Z", - "duration": 20 - }, - "retries": [], - "testCount": 4, - "passedTests": 1, - "failedTests": 3, - "pendingTests": 0, - "tests": [ - { - "id": "3bed687b", - "title": "test with multiple steps", - "feature": "HTML Reporter Test", - "state": "failed", - "duration": 0, - "tags": [], - "meta": {}, - "retryAttempts": 0, - "uid": "wMUVf8gGXfvdJuFZpZLpHqWsSloUrGsfe1jkhlhi8W" - }, - { - "id": "851625f0", - "title": "test that will fail", - "feature": "HTML Reporter Test", - "state": "failed", - "duration": 0, - "tags": [], - "meta": {}, - "retryAttempts": 0, - "uid": "aSiHH58JFT47Yhs6WutjsIlCUhY9oyeAIhrj2XW3Hx" - }, - { - "id": "494d0c75", - "title": "test that will pass", - "feature": "HTML Reporter Test", - "state": "passed", - "duration": 0, - "tags": [], - "meta": {}, - "retryAttempts": 0, - "uid": "RsmmIVWoew3I96UDEDwSaCKU6ursIlnacmsslF6aWA" - }, - { - "id": "77e3208b", - "title": "test with artifacts", - "feature": "HTML Reporter with Artifacts Test", - "state": "failed", - "duration": 0, - "tags": [], - "meta": {}, - "retryAttempts": 0, - "uid": "8h8Wb2vBKAGKgtMERAsjfrSW_sV10eapYE+YhXG0uK" - } - ] -} diff --git a/test/runner/output/report.html b/test/runner/output/report.html deleted file mode 100644 index 0bb1a88e4..000000000 --- a/test/runner/output/report.html +++ /dev/null @@ -1,776 +0,0 @@ - - - - - - CodeceptJS Test Report - - - -
-

CodeceptJS Test Report

-
- Generated: 2025年08月23日T16:56:45.424Z - Duration: 29ms -
-
- -
-
-

Test Statistics

- -
-
-

Total

- 4 -
-
-

Passed

- 1 -
-
-

Failed

- 3 -
-
-

Pending

- 0 -
-
-
- - -
-
- -
-

Test Results

-
-
-
- くろまる -

test with multiple steps

- HTML Reporter Test - 0ms -
-
-
 File package.json not found in /home/runner/work/CodeceptJS/CodeceptJS/test/data/sandbox/configs/html-reporter-plugin
- -
-

Steps:

-
-
- くろまる - I.amInPath(".") - 1ms -
- -
- くろまる - I.seeFile("package.json") - 1ms -
-
-
-
-
- -
-
- くろまる -

test that will fail

- HTML Reporter Test - 0ms -
-
-
 File this-file-should-not-exist.txt not found in /home/runner/work/CodeceptJS/CodeceptJS/test/data/sandbox/configs/html-reporter-plugin
- -
-

Steps:

-
-
- くろまる - I.amInPath(".") - 0ms -
- -
- くろまる - I.seeFile("this-file-should-not-exist.txt") - 1ms -
-
-
-
-
- -
-
- くろまる -

test that will pass

- HTML Reporter Test - 0ms -
-
-
-

Steps:

-
-
- くろまる - I.amInPath(".") - 0ms -
- -
- くろまる - I.seeFile("codecept.conf.js") - 0ms -
-
-
-
-
- -
-
- くろまる -

test with artifacts

- HTML Reporter with Artifacts Test - 0ms -
-
-
-
- Cannot find module '../../../../lib/container'
- Require stack:
- - /home/runner/work/CodeceptJS/CodeceptJS/test/data/sandbox/configs/html-reporter-plugin/artifacts_test.js
- - /home/runner/work/CodeceptJS/CodeceptJS/node_modules/mocha/lib/mocha.js
- - /home/runner/work/CodeceptJS/CodeceptJS/node_modules/mocha/index.js
- ...
-
- -
-

Steps:

-
-
- くろまる - I.amInPath(".") - 0ms -
- -
- くろまる - I.seeFile("codecept.conf.js") - 0ms -
-
-
-
-
-
-
- -
-

Failures

-
-
-

Failure 1

-
- %s) %s:
-%s
-%s
-,1,HTML Reporter Test
- test with multiple steps,
- 
- File package.json not found in /home/runner/work/CodeceptJS/CodeceptJS/test/data/sandbox/configs/html-reporter-plugin
- + expected - actual
-
- -false
- +true
- , AssertionError [ERR_ASSERTION]: 
- at FileSystem.seeFile (/home/runner/work/CodeceptJS/CodeceptJS/lib/helper/FileSystem.js:70:12)
- at HelperStep.run (/home/runner/work/CodeceptJS/CodeceptJS/lib/step/helper.js:28:49)
- 
- 
- ◯ File: file:///home/runner/work/CodeceptJS/CodeceptJS/test/data/sandbox/configs/html-reporter-plugin/html-reporter_test.js
- 
- ◯ Scenario Steps:
- ✖ I.seeFile("package.json") at Test.<anonymous> (./html-reporter_test.js:5:5)
- ✔ I.amInPath(".") at Test.<anonymous> (./html-reporter_test.js:4:5)
- 
-
- -
-

Failure 2

-
- %s) %s:
-%s
-%s
-,2,HTML Reporter Test
- test that will fail,
- 
- File this-file-should-not-exist.txt not found in /home/runner/work/CodeceptJS/CodeceptJS/test/data/sandbox/configs/html-reporter-plugin
- + expected - actual
-
- -false
- +true
- , AssertionError [ERR_ASSERTION]: 
- at FileSystem.seeFile (/home/runner/work/CodeceptJS/CodeceptJS/lib/helper/FileSystem.js:70:12)
- at HelperStep.run (/home/runner/work/CodeceptJS/CodeceptJS/lib/step/helper.js:28:49)
- 
- 
- ◯ File: file:///home/runner/work/CodeceptJS/CodeceptJS/test/data/sandbox/configs/html-reporter-plugin/html-reporter_test.js
- 
- ◯ Scenario Steps:
- ✖ I.seeFile("this-file-should-not-exist.txt") at Test.<anonymous> (./html-reporter_test.js:10:5)
- ✔ I.amInPath(".") at Test.<anonymous> (./html-reporter_test.js:9:5)
- 
-
- -
-

Failure 3

-
- %s) %s:
- %s
-%s
-,3,HTML Reporter with Artifacts Test
- test with artifacts,
- Cannot find module '../../../../lib/container'
- Require stack:
- - /home/runner/work/CodeceptJS/CodeceptJS/test/data/sandbox/configs/html-reporter-plugin/artifacts_test.js
- - /home/runner/work/CodeceptJS/CodeceptJS/node_modules/mocha/lib/mocha.js
- - /home/runner/work/CodeceptJS/CodeceptJS/node_modules/mocha/index.js
- ..., Error: Cannot find module '../../../../lib/container'
- Require stack:
- - /home/runner/work/CodeceptJS/CodeceptJS/test/data/sandbox/configs/html-reporter-plugin/artifacts_test.js
- 
- 
- ◯ File: file:///home/runner/work/CodeceptJS/CodeceptJS/test/data/sandbox/configs/html-reporter-plugin/artifacts_test.js
- 
-
-
-
-
- - -
- -
- - - - From 29262b1636b442092fa2cabd6dabcf11c2884b19 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+copilot@users.noreply.github.com> Date: 2025年8月24日 10:07:42 +0000 Subject: [PATCH 09/11] Changes before error encountered Co-authored-by: kobenguyent <7845001+kobenguyent@users.noreply.github.com> --- lib/plugin/htmlReporter.js | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/lib/plugin/htmlReporter.js b/lib/plugin/htmlReporter.js index 815716039..12f06a704 100644 --- a/lib/plugin/htmlReporter.js +++ b/lib/plugin/htmlReporter.js @@ -6,6 +6,7 @@ const { template } = require('../utils') const event = require('../event') const output = require('../output') +const Codecept = require('../codecept') const defaultConfig = { output: global.output_dir || './output', @@ -311,7 +312,7 @@ module.exports = function (config) { } } - function generateHtmlReport(data, config) { + async function generateHtmlReport(data, config) { const reportPath = path.join(reportDir, config.reportFileName) // Load history if available @@ -327,6 +328,9 @@ module.exports = function (config) { } } + // Get system information + const systemInfo = await getSystemInfo() + const html = template(getHtmlTemplate(), { title: 'CodeceptJS Test Report', timestamp: data.endTime.toISOString(), @@ -342,6 +346,9 @@ module.exports = function (config) { showRetries: config.showRetries ? 'block' : 'none', showHistory: config.keepHistory && history.length> 0 ? 'block' : 'none', failuresDisplay: data.failures && data.failures.length> 0 ? 'block' : 'none', + codeceptVersion: Codecept.version(), + systemInfoHtml: generateSystemInfoHtml(systemInfo), + codeceptLogo: getCodeceptLogo(), }) fs.writeFileSync(reportPath, html) From 80406066db5ba9228d7dee1a649ee61d3f8efed6 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+copilot@users.noreply.github.com> Date: 2025年8月24日 11:33:54 +0000 Subject: [PATCH 10/11] Enable HTML reporter by default in init and update README Co-authored-by: kobenguyent <7845001+kobenguyent@users.noreply.github.com> --- README.md | 16 ++++ docs/plugins.md | 191 ++++---------------------------------------- lib/command/init.js | 5 ++ 3 files changed, 38 insertions(+), 174 deletions(-) diff --git a/README.md b/README.md index 4ca636d91..b374df5d9 100644 --- a/README.md +++ b/README.md @@ -65,6 +65,7 @@ You don't need to worry about asynchronous nature of NodeJS or about various API - Smart locators: use names, labels, matching text, CSS or XPath to locate elements. - 🌐 Interactive debugging shell: pause test at any point and try different commands in a browser. - ⚡ **Parallel testing** with dynamic test pooling for optimal load balancing and performance. +- 📊 **Built-in HTML Reporter** with interactive dashboard, step-by-step execution details, and comprehensive test analytics. - Easily create tests, pageobjects, stepobjects with CLI generators. ## Installation @@ -234,6 +235,21 @@ Scenario('test title', () => { }) ``` +## HTML Reporter + +CodeceptJS includes a powerful built-in HTML Reporter that generates comprehensive, interactive test reports with detailed information about your test runs. The HTML reporter is **enabled by default** for all new projects and provides: + +- **Interactive Dashboard**: Visual statistics, pie charts, and expandable test details +- **Step-by-Step Execution**: Shows individual test steps with timing and status indicators +- **BDD/Gherkin Support**: Full support for feature files with proper scenario formatting +- **System Information**: Comprehensive environment details including browser versions +- **Advanced Filtering**: Real-time filtering by status, tags, features, and test types +- **History Tracking**: Multi-run history with trend visualization +- **Error Details**: Clean formatting of error messages and stack traces +- **Artifacts Support**: Display screenshots and other test artifacts + +The HTML reporter generates self-contained reports that can be easily shared with your team. Learn more about configuration and features in the [HTML Reporter documentation](https://codecept.io/plugins/#htmlreporter). + ## PageObjects CodeceptJS provides the most simple way to create and use page objects in your test. diff --git a/docs/plugins.md b/docs/plugins.md index 5a2e9f0de..641c8f39d 100644 --- a/docs/plugins.md +++ b/docs/plugins.md @@ -720,23 +720,10 @@ HTML Reporter Plugin for CodeceptJS Generates comprehensive HTML reports showing: -- **Interactive Test Results**: Click-to-expand test details with comprehensive information -- **Step-by-Step Details**: Shows individual test steps with proper method names (e.g., `I.seeFile()`, `I.amInPath()`), status indicators, and timing -- **BDD/Gherkin Support**: Full support for Gherkin feature files with proper scenario formatting, step keywords, and feature information -- **Test Statistics**: Visual cards displaying totals, passed, failed, and pending test counts with interactive pie chart -- **Error Information**: Clean, formatted error messages for failed tests with ANSI color code stripping -- **Artifacts Support**: Display screenshots and other test artifacts with modal viewing capability -- **Responsive Design**: Mobile-friendly layout that works across all screen sizes -- **Professional Styling**: Modern, clean interface with color-coded status indicators -- **Enhanced Features**: - - **Metadata Display**: Shows test metadata, options, and custom properties - - **Tags Support**: Display and filter by test tags (@smoke, @critical, etc.) - - **Retry Tracking**: Shows retry attempts and final test status - - **Test Notes**: Display test notes and comments - - **Interactive Filters**: Filter tests by status, feature, tags, retry status, and test type (BDD vs Regular) - - **Test History**: Track test results across multiple runs with visual charts - - **Stats Export**: Export test statistics in JSON format for integration with external tools (Grafana, etc.) - - **Worker Support**: Compatible with run-workers and run-multiple commands +- Test statistics +- Feature/Scenario details +- Individual step results +- Test artifacts (screenshots, etc.) ## Configuration @@ -744,167 +731,23 @@ Generates comprehensive HTML reports showing: "plugins": { "htmlReporter": { "enabled": true, - "output": "./output", // Directory for the report - "reportFileName": "report.html", // Name of the HTML file - "includeArtifacts": true, // Include screenshots/artifacts - "showSteps": true, // Show individual test steps - "showSkipped": true, // Show skipped tests - "showMetadata": true, // Show test metadata and options - "showTags": true, // Show test tags - "showRetries": true, // Show retry information - "exportStats": false, // Export stats to JSON file - "exportStatsPath": "./stats.json", // Path for stats export - "keepHistory": false, // Track test history - "historyPath": "./test-history.json", // Path for history file - "maxHistoryEntries": 50 // Max history entries to keep + "output": "./output", + "reportFileName": "report.html", + "includeArtifacts": true, + "showSteps": true, + "showSkipped": true, + "showMetadata": true, + "showTags": true, + "showRetries": true, + "exportStats": false, + "exportStatsPath": "./stats.json", + "keepHistory": false, + "historyPath": "./test-history.json", + "maxHistoryEntries": 50 } } ``` -### Usage - -Run tests normally and the HTML report will be automatically generated: - -```bash -npx codeceptjs run -``` - -The generated HTML report includes: - -- **Filter Controls**: Interactive filtering by status, feature, tags, and retry status -- **Test History Chart**: Visual representation of test results over time (when history is enabled) -- **Detailed Test Information**: Expandable sections showing steps, hooks, metadata, and artifacts -- **Export Integration**: JSON stats export for external analysis tools - -### Screenshots - -#### Main Dashboard - -![HTML Reporter Main Dashboard](shared/html-reporter-main-dashboard.png) -_Interactive dashboard with test statistics, pie chart visualization, and comprehensive filtering options_ - -#### Test Details View - -![HTML Reporter Test Details](shared/html-reporter-test-details.png) -_Expandable test details showing step-by-step execution with timing, status indicators, and comprehensive test information_ - -#### Advanced Filtering - -![HTML Reporter Filtering](shared/html-reporter-filtering.png) -_Real-time filtering capabilities allowing users to filter by status, features, tags, retry status, and test type_ - -#### BDD/Gherkin Support - -![HTML Reporter BDD Details](shared/html-reporter-bdd-details.png) -_Comprehensive BDD/Gherkin support with feature information, scenario formatting, proper step keywords (Given, When, Then, And), hooks, and visual indicators_ - -### Stats Export for Grafana Integration - -Enable stats export to integrate with monitoring tools: - -```js -"htmlReporter": { - "enabled": true, - "exportStats": true, - "exportStatsPath": "./test-stats.json" -} -``` - -The exported JSON contains structured data perfect for Grafana dashboards: - -- Test execution metrics -- Pass/fail rates over time -- Individual test performance data -- Retry statistics -- Test metadata for grouping and filtering - -### History Tracking - -Track test trends across multiple runs: - -```js -"htmlReporter": { - "enabled": true, - "keepHistory": true, - "historyPath": "./test-history.json", - "maxHistoryEntries": 100 -} -``` - -History tracking provides: - -- Test result trends over time -- Performance regression detection -- Visual charts in the HTML report -- JSON data for external analysis - -### BDD/Gherkin Support - -The HTML reporter provides comprehensive support for BDD/Gherkin feature files with enhanced formatting and visualization: - -#### Key BDD Features - -- **Automatic Detection**: Automatically detects BDD/Gherkin tests based on `.feature` files and Gherkin syntax -- **Scenario Formatting**: Displays scenarios with proper "Scenario:" prefix and visual distinction from regular tests -- **Feature Information**: Shows complete feature details including name, description, and file path -- **Gherkin Steps**: Displays steps with proper keywords (Given, When, Then, And) in a BDD-friendly format -- **BDD Badge**: Visual indicator distinguishing Gherkin tests from regular CodeceptJS tests -- **Feature Tags**: Supports both feature-level and scenario-level tags with proper inheritance -- **Test Type Filtering**: Filter reports to show only BDD tests, only regular tests, or both - -#### BDD Configuration - -No special configuration required - BDD support is automatically enabled when using Gherkin feature files: - -```js -// codecept.conf.js -exports.config = { - gherkin: { - features: './features/*.feature', - steps: './step_definitions/*.js', - }, - plugins: { - htmlReporter: { - enabled: true, - output: './output', - reportFileName: 'report.html', - }, - }, -} -``` - -#### BDD Report Features - -**Feature Display:** - -- Feature name and description prominently displayed -- Feature-level tags shown with purple styling -- File path information for traceability -- Language support for internationalized Gherkin - -**Scenario Formatting:** - -- Clear "Scenario:" prefix for test titles -- "Feature:" prefix for feature grouping -- Purple "Gherkin" badge for easy identification -- Visual left border styling for BDD tests - -**Step Visualization:** - -- Proper Gherkin keywords: Given, When, Then, And -- Step text displayed with original Gherkin formatting -- Execution timing for each step -- Status indicators (pass/fail) for individual steps -- Support for data tables and docstrings in step comments - -**Enhanced Filtering:** - -- Test Type filter to show BDD-only or regular tests -- All existing filters (tags, status, feature) work with BDD tests -- Combined filtering for complex test selection - -The BDD support seamlessly integrates with all existing HTML reporter features including retry tracking, history, stats export, and artifact display. - ### Parameters - `config` diff --git a/lib/command/init.js b/lib/command/init.js index 735e16c23..ee5ba1294 100644 --- a/lib/command/init.js +++ b/lib/command/init.js @@ -18,6 +18,11 @@ const defaultConfig = { output: '', helpers: {}, include: {}, + plugins: { + htmlReporter: { + enabled: true, + }, + }, } const helpers = ['Playwright', 'WebDriver', 'Puppeteer', 'REST', 'GraphQL', 'Appium', 'TestCafe'] From 9163dca144f43f9f81df566e3daac59e965465fa Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+copilot@users.noreply.github.com> Date: 2025年8月24日 12:21:29 +0000 Subject: [PATCH 11/11] Fix HTML reporter plugin tests and enhance README with comprehensive screenshots Co-authored-by: kobenguyent <7845001+kobenguyent@users.noreply.github.com> --- README.md | 28 ++++ lib/plugin/htmlReporter.js | 146 +++++++++++++++++- .../html-reporter-plugin/artifacts_test.js | 19 ++- .../configs/html-reporter-plugin/package.json | 11 ++ 4 files changed, 190 insertions(+), 14 deletions(-) create mode 100644 test/data/sandbox/configs/html-reporter-plugin/package.json diff --git a/README.md b/README.md index b374df5d9..cbe95200b 100644 --- a/README.md +++ b/README.md @@ -239,6 +239,8 @@ Scenario('test title', () => { CodeceptJS includes a powerful built-in HTML Reporter that generates comprehensive, interactive test reports with detailed information about your test runs. The HTML reporter is **enabled by default** for all new projects and provides: +### Features + - **Interactive Dashboard**: Visual statistics, pie charts, and expandable test details - **Step-by-Step Execution**: Shows individual test steps with timing and status indicators - **BDD/Gherkin Support**: Full support for feature files with proper scenario formatting @@ -248,6 +250,32 @@ CodeceptJS includes a powerful built-in HTML Reporter that generates comprehensi - **Error Details**: Clean formatting of error messages and stack traces - **Artifacts Support**: Display screenshots and other test artifacts +### Visual Examples + +#### Interactive Test Dashboard + +The main dashboard provides a complete overview with interactive statistics and pie charts: + +![HTML Reporter Dashboard](docs/shared/html-reporter-main-dashboard.png) + +#### Detailed Test Results + +Each test shows comprehensive execution details with expandable step information: + +![HTML Reporter Test Details](docs/shared/html-reporter-test-details.png) + +#### Advanced Filtering Capabilities + +Real-time filtering allows quick navigation through test results: + +![HTML Reporter Filtering](docs/shared/html-reporter-filtering.png) + +#### BDD/Gherkin Support + +Full support for Gherkin scenarios with proper feature formatting: + +![HTML Reporter BDD Details](docs/shared/html-reporter-bdd-details.png) + The HTML reporter generates self-contained reports that can be easily shared with your team. Learn more about configuration and features in the [HTML Reporter documentation](https://codecept.io/plugins/#htmlreporter). ## PageObjects diff --git a/lib/plugin/htmlReporter.js b/lib/plugin/htmlReporter.js index 12f06a704..ec033050e 100644 --- a/lib/plugin/htmlReporter.js +++ b/lib/plugin/htmlReporter.js @@ -3,6 +3,7 @@ const path = require('path') const mkdirp = require('mkdirp') const crypto = require('crypto') const { template } = require('../utils') +const { getMachineInfo } = require('../command/info') const event = require('../event') const output = require('../output') @@ -329,10 +330,10 @@ module.exports = function (config) { } // Get system information - const systemInfo = await getSystemInfo() + const systemInfo = await getMachineInfo() const html = template(getHtmlTemplate(), { - title: 'CodeceptJS Test Report', + title: `CodeceptJS Test Report v${Codecept.version()}`, timestamp: data.endTime.toISOString(), duration: formatDuration(data.duration), stats: JSON.stringify(data.stats), @@ -348,7 +349,6 @@ module.exports = function (config) { failuresDisplay: data.failures && data.failures.length> 0 ? 'block' : 'none', codeceptVersion: Codecept.version(), systemInfoHtml: generateSystemInfoHtml(systemInfo), - codeceptLogo: getCodeceptLogo(), }) fs.writeFileSync(reportPath, html) @@ -402,7 +402,7 @@ module.exports = function (config) { return tests .map(test => { const statusClass = test.state || 'unknown' - const feature = test.isBdd && test.feature ? test.feature.name : (test.parent?.title || 'Unknown Feature') + const feature = test.isBdd && test.feature ? test.feature.name : test.parent?.title || 'Unknown Feature' const steps = config.showSteps && test.steps ? (test.isBdd ? generateBddStepsHtml(test.steps) : generateStepsHtml(test.steps)) : '' const featureDetails = test.isBdd && test.feature ? generateBddFeatureHtml(test.feature) : '' const hooks = test.hooks && test.hooks.length> 0 ? generateHooksHtml(test.hooks) : '' @@ -506,8 +506,7 @@ module.exports = function (config) { if (!feature) return '' const description = feature.description ? `
${escapeHtml(feature.description)}
` : '' - const featureTags = feature.tags && feature.tags.length> 0 ? - `
${feature.tags.map(tag => `${escapeHtml(tag)}`).join('')}
` : '' + const featureTags = feature.tags && feature.tags.length> 0 ? `
${feature.tags.map(tag => `${escapeHtml(tag)}`).join('')}
` : '' return `
@@ -677,6 +676,48 @@ module.exports = function (config) { return unsafe.replace(/&/g, '&').replace(//g, '>').replace(/"/g, '"').replace(/'/g, ''') } + function generateSystemInfoHtml(systemInfo) { + if (!systemInfo) return '' + + const formatInfo = (key, value) => { + if (Array.isArray(value) && value.length> 1) { + return `
${key}: ${escapeHtml(value[1])}
` + } else if (typeof value === 'string' && value !== 'N/A' && value !== 'undefined') { + return `
${key}: ${escapeHtml(value)}
` + } + return '' + } + + const infoItems = [ + formatInfo('Node.js', systemInfo.nodeInfo), + formatInfo('OS', systemInfo.osInfo), + formatInfo('CPU', systemInfo.cpuInfo), + formatInfo('Chrome', systemInfo.chromeInfo), + formatInfo('Edge', systemInfo.edgeInfo), + formatInfo('Firefox', systemInfo.firefoxInfo), + formatInfo('Safari', systemInfo.safariInfo), + formatInfo('Playwright Browsers', systemInfo.playwrightBrowsers), + ] + .filter(item => item) + .join('') + + if (!infoItems) return '' + + return ` +
+
+

Environment Information

+ +
+
+
+ ${infoItems} +
+
+
+ ` + } + function getHtmlTemplate() { return ` @@ -697,6 +738,8 @@ module.exports = function (config) {
+ {{systemInfoHtml}} +

Test Statistics

{{statsHtml}} @@ -830,7 +873,7 @@ body { padding: 0 1rem; } -.stats-section, .tests-section, .failures-section, .retries-section, .filters-section, .history-section { +.stats-section, .tests-section, .failures-section, .retries-section, .filters-section, .history-section, .system-info-section { background: white; margin-bottom: 2rem; border-radius: 8px; @@ -1352,6 +1395,82 @@ body { display: none !important; } +/* System Info Section */ +.system-info-section { + background: white; + margin-bottom: 2rem; + border-radius: 8px; + box-shadow: 0 2px 4px rgba(0,0,0,0.1); + overflow: hidden; +} + +.system-info-header { + background: #2c3e50; + color: white; + padding: 1rem; + cursor: pointer; + display: flex; + justify-content: space-between; + align-items: center; + transition: background-color 0.2s; +} + +.system-info-header:hover { + background: #34495e; +} + +.system-info-header h3 { + margin: 0; + font-size: 1.2rem; +} + +.toggle-icon { + font-size: 1rem; + transition: transform 0.3s ease; +} + +.toggle-icon.rotated { + transform: rotate(-180deg); +} + +.system-info-content { + display: none; + padding: 1.5rem; + background: #f8f9fa; + border-top: 1px solid #e9ecef; +} + +.system-info-content.visible { + display: block; +} + +.system-info-grid { + display: grid; + grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); + gap: 1rem; +} + +.info-item { + padding: 0.75rem; + background: white; + border-radius: 6px; + border-left: 4px solid #3498db; + box-shadow: 0 1px 3px rgba(0,0,0,0.1); +} + +.info-key { + font-weight: bold; + color: #2c3e50; + display: inline-block; + min-width: 100px; +} + +.info-value { + color: #34495e; + font-family: 'Courier New', monospace; + font-size: 0.9rem; +} + /* BDD/Gherkin specific styles */ .bdd-test { border-left: 4px solid #8e44ad; @@ -1501,6 +1620,19 @@ function closeImageModal() { modal.style.display = 'none'; } +function toggleSystemInfo() { + const content = document.getElementById('systemInfoContent'); + const icon = document.querySelector('.toggle-icon'); + + if (content.classList.contains('visible')) { + content.classList.remove('visible'); + icon.classList.remove('rotated'); + } else { + content.classList.add('visible'); + icon.classList.add('rotated'); + } +} + // Filter functionality function applyFilters() { const statusFilter = Array.from(document.getElementById('statusFilter').selectedOptions).map(opt => opt.value); diff --git a/test/data/sandbox/configs/html-reporter-plugin/artifacts_test.js b/test/data/sandbox/configs/html-reporter-plugin/artifacts_test.js index e0de9d354..ea647cbd8 100644 --- a/test/data/sandbox/configs/html-reporter-plugin/artifacts_test.js +++ b/test/data/sandbox/configs/html-reporter-plugin/artifacts_test.js @@ -3,12 +3,17 @@ Feature('HTML Reporter with Artifacts Test') Scenario('test with artifacts', async ({ I }) => { I.amInPath('.') I.seeFile('codecept.conf.js') - + // Simulate adding test artifacts - const currentTest = global.codecept_dir ? require('../../../../lib/container').get('mocha') : null - if (currentTest && currentTest.currentTest) { - currentTest.currentTest.artifacts = currentTest.currentTest.artifacts || [] - currentTest.currentTest.artifacts.push('fake-screenshot-1.png') - currentTest.currentTest.artifacts.push('fake-screenshot-2.png') + const container = require('../../../../../lib/container') + try { + const currentTest = container.mocha().currentTest + if (currentTest) { + currentTest.artifacts = currentTest.artifacts || [] + currentTest.artifacts.push('fake-screenshot-1.png') + currentTest.artifacts.push('fake-screenshot-2.png') + } + } catch (e) { + // Ignore if container not available } -}) \ No newline at end of file +}) diff --git a/test/data/sandbox/configs/html-reporter-plugin/package.json b/test/data/sandbox/configs/html-reporter-plugin/package.json new file mode 100644 index 000000000..d82476379 --- /dev/null +++ b/test/data/sandbox/configs/html-reporter-plugin/package.json @@ -0,0 +1,11 @@ +{ + "name": "html-reporter-plugin-test", + "version": "1.0.0", + "description": "Test package for HTML reporter plugin tests", + "main": "index.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "author": "", + "license": "ISC" +}