Skip to content

Commit 9163dca

Browse files
Copilotkobenguyent
andcommitted
Fix HTML reporter plugin tests and enhance README with comprehensive screenshots
Co-authored-by: kobenguyent <[email protected]>
1 parent 8040606 commit 9163dca

File tree

4 files changed

+190
-14
lines changed

4 files changed

+190
-14
lines changed

README.md

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -239,6 +239,8 @@ Scenario('test title', () => {
239239

240240
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:
241241

242+
### Features
243+
242244
- **Interactive Dashboard**: Visual statistics, pie charts, and expandable test details
243245
- **Step-by-Step Execution**: Shows individual test steps with timing and status indicators
244246
- **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
248250
- **Error Details**: Clean formatting of error messages and stack traces
249251
- **Artifacts Support**: Display screenshots and other test artifacts
250252

253+
### Visual Examples
254+
255+
#### Interactive Test Dashboard
256+
257+
The main dashboard provides a complete overview with interactive statistics and pie charts:
258+
259+
![HTML Reporter Dashboard](docs/shared/html-reporter-main-dashboard.png)
260+
261+
#### Detailed Test Results
262+
263+
Each test shows comprehensive execution details with expandable step information:
264+
265+
![HTML Reporter Test Details](docs/shared/html-reporter-test-details.png)
266+
267+
#### Advanced Filtering Capabilities
268+
269+
Real-time filtering allows quick navigation through test results:
270+
271+
![HTML Reporter Filtering](docs/shared/html-reporter-filtering.png)
272+
273+
#### BDD/Gherkin Support
274+
275+
Full support for Gherkin scenarios with proper feature formatting:
276+
277+
![HTML Reporter BDD Details](docs/shared/html-reporter-bdd-details.png)
278+
251279
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).
252280

253281
## PageObjects

lib/plugin/htmlReporter.js

Lines changed: 139 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ const path = require('path')
33
const mkdirp = require('mkdirp')
44
const crypto = require('crypto')
55
const { template } = require('../utils')
6+
const { getMachineInfo } = require('../command/info')
67

78
const event = require('../event')
89
const output = require('../output')
@@ -329,10 +330,10 @@ module.exports = function (config) {
329330
}
330331

331332
// Get system information
332-
const systemInfo = await getSystemInfo()
333+
const systemInfo = await getMachineInfo()
333334

334335
const html = template(getHtmlTemplate(), {
335-
title: 'CodeceptJS Test Report',
336+
title: `CodeceptJS Test Report v${Codecept.version()}`,
336337
timestamp: data.endTime.toISOString(),
337338
duration: formatDuration(data.duration),
338339
stats: JSON.stringify(data.stats),
@@ -348,7 +349,6 @@ module.exports = function (config) {
348349
failuresDisplay: data.failures && data.failures.length > 0 ? 'block' : 'none',
349350
codeceptVersion: Codecept.version(),
350351
systemInfoHtml: generateSystemInfoHtml(systemInfo),
351-
codeceptLogo: getCodeceptLogo(),
352352
})
353353

354354
fs.writeFileSync(reportPath, html)
@@ -402,7 +402,7 @@ module.exports = function (config) {
402402
return tests
403403
.map(test => {
404404
const statusClass = test.state || 'unknown'
405-
const feature = test.isBdd && test.feature ? test.feature.name : (test.parent?.title || 'Unknown Feature')
405+
const feature = test.isBdd && test.feature ? test.feature.name : test.parent?.title || 'Unknown Feature'
406406
const steps = config.showSteps && test.steps ? (test.isBdd ? generateBddStepsHtml(test.steps) : generateStepsHtml(test.steps)) : ''
407407
const featureDetails = test.isBdd && test.feature ? generateBddFeatureHtml(test.feature) : ''
408408
const hooks = test.hooks && test.hooks.length > 0 ? generateHooksHtml(test.hooks) : ''
@@ -506,8 +506,7 @@ module.exports = function (config) {
506506
if (!feature) return ''
507507

508508
const description = feature.description ? `<div class="feature-description">${escapeHtml(feature.description)}</div>` : ''
509-
const featureTags = feature.tags && feature.tags.length > 0 ?
510-
`<div class="feature-tags">${feature.tags.map(tag => `<span class="feature-tag">${escapeHtml(tag)}</span>`).join('')}</div>` : ''
509+
const featureTags = feature.tags && feature.tags.length > 0 ? `<div class="feature-tags">${feature.tags.map(tag => `<span class="feature-tag">${escapeHtml(tag)}</span>`).join('')}</div>` : ''
511510

512511
return `
513512
<div class="bdd-feature-section">
@@ -677,6 +676,48 @@ module.exports = function (config) {
677676
return unsafe.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/"/g, '&quot;').replace(/'/g, '&#039;')
678677
}
679678

679+
function generateSystemInfoHtml(systemInfo) {
680+
if (!systemInfo) return ''
681+
682+
const formatInfo = (key, value) => {
683+
if (Array.isArray(value) && value.length > 1) {
684+
return `<div class="info-item"><span class="info-key">${key}:</span> <span class="info-value">${escapeHtml(value[1])}</span></div>`
685+
} else if (typeof value === 'string' && value !== 'N/A' && value !== 'undefined') {
686+
return `<div class="info-item"><span class="info-key">${key}:</span> <span class="info-value">${escapeHtml(value)}</span></div>`
687+
}
688+
return ''
689+
}
690+
691+
const infoItems = [
692+
formatInfo('Node.js', systemInfo.nodeInfo),
693+
formatInfo('OS', systemInfo.osInfo),
694+
formatInfo('CPU', systemInfo.cpuInfo),
695+
formatInfo('Chrome', systemInfo.chromeInfo),
696+
formatInfo('Edge', systemInfo.edgeInfo),
697+
formatInfo('Firefox', systemInfo.firefoxInfo),
698+
formatInfo('Safari', systemInfo.safariInfo),
699+
formatInfo('Playwright Browsers', systemInfo.playwrightBrowsers),
700+
]
701+
.filter(item => item)
702+
.join('')
703+
704+
if (!infoItems) return ''
705+
706+
return `
707+
<section class="system-info-section">
708+
<div class="system-info-header" onclick="toggleSystemInfo()">
709+
<h3>Environment Information</h3>
710+
<span class="toggle-icon">▼</span>
711+
</div>
712+
<div class="system-info-content" id="systemInfoContent">
713+
<div class="system-info-grid">
714+
${infoItems}
715+
</div>
716+
</div>
717+
</section>
718+
`
719+
}
720+
680721
function getHtmlTemplate() {
681722
return `
682723
<!DOCTYPE html>
@@ -697,6 +738,8 @@ module.exports = function (config) {
697738
</header>
698739
699740
<main class="report-content">
741+
{{systemInfoHtml}}
742+
700743
<section class="stats-section">
701744
<h2>Test Statistics</h2>
702745
{{statsHtml}}
@@ -830,7 +873,7 @@ body {
830873
padding: 0 1rem;
831874
}
832875
833-
.stats-section, .tests-section, .failures-section, .retries-section, .filters-section, .history-section {
876+
.stats-section, .tests-section, .failures-section, .retries-section, .filters-section, .history-section, .system-info-section {
834877
background: white;
835878
margin-bottom: 2rem;
836879
border-radius: 8px;
@@ -1352,6 +1395,82 @@ body {
13521395
display: none !important;
13531396
}
13541397
1398+
/* System Info Section */
1399+
.system-info-section {
1400+
background: white;
1401+
margin-bottom: 2rem;
1402+
border-radius: 8px;
1403+
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
1404+
overflow: hidden;
1405+
}
1406+
1407+
.system-info-header {
1408+
background: #2c3e50;
1409+
color: white;
1410+
padding: 1rem;
1411+
cursor: pointer;
1412+
display: flex;
1413+
justify-content: space-between;
1414+
align-items: center;
1415+
transition: background-color 0.2s;
1416+
}
1417+
1418+
.system-info-header:hover {
1419+
background: #34495e;
1420+
}
1421+
1422+
.system-info-header h3 {
1423+
margin: 0;
1424+
font-size: 1.2rem;
1425+
}
1426+
1427+
.toggle-icon {
1428+
font-size: 1rem;
1429+
transition: transform 0.3s ease;
1430+
}
1431+
1432+
.toggle-icon.rotated {
1433+
transform: rotate(-180deg);
1434+
}
1435+
1436+
.system-info-content {
1437+
display: none;
1438+
padding: 1.5rem;
1439+
background: #f8f9fa;
1440+
border-top: 1px solid #e9ecef;
1441+
}
1442+
1443+
.system-info-content.visible {
1444+
display: block;
1445+
}
1446+
1447+
.system-info-grid {
1448+
display: grid;
1449+
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
1450+
gap: 1rem;
1451+
}
1452+
1453+
.info-item {
1454+
padding: 0.75rem;
1455+
background: white;
1456+
border-radius: 6px;
1457+
border-left: 4px solid #3498db;
1458+
box-shadow: 0 1px 3px rgba(0,0,0,0.1);
1459+
}
1460+
1461+
.info-key {
1462+
font-weight: bold;
1463+
color: #2c3e50;
1464+
display: inline-block;
1465+
min-width: 100px;
1466+
}
1467+
1468+
.info-value {
1469+
color: #34495e;
1470+
font-family: 'Courier New', monospace;
1471+
font-size: 0.9rem;
1472+
}
1473+
13551474
/* BDD/Gherkin specific styles */
13561475
.bdd-test {
13571476
border-left: 4px solid #8e44ad;
@@ -1501,6 +1620,19 @@ function closeImageModal() {
15011620
modal.style.display = 'none';
15021621
}
15031622
1623+
function toggleSystemInfo() {
1624+
const content = document.getElementById('systemInfoContent');
1625+
const icon = document.querySelector('.toggle-icon');
1626+
1627+
if (content.classList.contains('visible')) {
1628+
content.classList.remove('visible');
1629+
icon.classList.remove('rotated');
1630+
} else {
1631+
content.classList.add('visible');
1632+
icon.classList.add('rotated');
1633+
}
1634+
}
1635+
15041636
// Filter functionality
15051637
function applyFilters() {
15061638
const statusFilter = Array.from(document.getElementById('statusFilter').selectedOptions).map(opt => opt.value);

test/data/sandbox/configs/html-reporter-plugin/artifacts_test.js

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,17 @@ Feature('HTML Reporter with Artifacts Test')
33
Scenario('test with artifacts', async ({ I }) => {
44
I.amInPath('.')
55
I.seeFile('codecept.conf.js')
6-
6+
77
// Simulate adding test artifacts
8-
const currentTest = global.codecept_dir ? require('../../../../lib/container').get('mocha') : null
9-
if (currentTest && currentTest.currentTest) {
10-
currentTest.currentTest.artifacts = currentTest.currentTest.artifacts || []
11-
currentTest.currentTest.artifacts.push('fake-screenshot-1.png')
12-
currentTest.currentTest.artifacts.push('fake-screenshot-2.png')
8+
const container = require('../../../../../lib/container')
9+
try {
10+
const currentTest = container.mocha().currentTest
11+
if (currentTest) {
12+
currentTest.artifacts = currentTest.artifacts || []
13+
currentTest.artifacts.push('fake-screenshot-1.png')
14+
currentTest.artifacts.push('fake-screenshot-2.png')
15+
}
16+
} catch (e) {
17+
// Ignore if container not available
1318
}
14-
})
19+
})
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
{
2+
"name": "html-reporter-plugin-test",
3+
"version": "1.0.0",
4+
"description": "Test package for HTML reporter plugin tests",
5+
"main": "index.js",
6+
"scripts": {
7+
"test": "echo \"Error: no test specified\" && exit 1"
8+
},
9+
"author": "",
10+
"license": "ISC"
11+
}

0 commit comments

Comments
 (0)