@test-station/render-html 0.2.22 → 0.2.23
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/index.js +62 -9
package/package.json
CHANGED
package/src/index.js
CHANGED
|
@@ -1156,14 +1156,18 @@ function renderModuleCard(moduleEntry) {
|
|
|
1156
1156
|
}
|
|
1157
1157
|
|
|
1158
1158
|
function renderPackageCard(pkg) {
|
|
1159
|
-
const status =
|
|
1159
|
+
const status = deriveDisplayStatus({
|
|
1160
|
+
summary: pkg.summary,
|
|
1161
|
+
reportedStatus: pkg.status,
|
|
1162
|
+
suites: pkg.suites,
|
|
1163
|
+
});
|
|
1160
1164
|
const targetId = `package-${slugify(pkg.name)}`;
|
|
1161
1165
|
const filterAttrs = renderFilterAttributes({
|
|
1162
1166
|
nodeType: 'package-card',
|
|
1163
1167
|
moduleNames: pkg.modules,
|
|
1164
1168
|
packageNames: [pkg.name],
|
|
1165
1169
|
frameworks: pkg.frameworks,
|
|
1166
|
-
hasFailures: (pkg.summary?.failed || 0) > 0,
|
|
1170
|
+
hasFailures: status === 'failed' || (pkg.summary?.failed || 0) > 0,
|
|
1167
1171
|
lineCoverage: pkg.coverage?.lines?.pct,
|
|
1168
1172
|
});
|
|
1169
1173
|
return `
|
|
@@ -1224,7 +1228,11 @@ function renderModuleSection(moduleEntry, rootDir) {
|
|
|
1224
1228
|
}
|
|
1225
1229
|
|
|
1226
1230
|
function renderPackageSection(pkg, rootDir) {
|
|
1227
|
-
const status =
|
|
1231
|
+
const status = deriveDisplayStatus({
|
|
1232
|
+
summary: pkg.summary,
|
|
1233
|
+
reportedStatus: pkg.status,
|
|
1234
|
+
suites: pkg.suites,
|
|
1235
|
+
});
|
|
1228
1236
|
const suites = Array.isArray(pkg.suites) ? pkg.suites : [];
|
|
1229
1237
|
const suiteMarkup = suites.length === 0
|
|
1230
1238
|
? '<div class="suite"><div class="suite__summaryRow"><div><span class="suite__label">No test suites</span></div><div class="suite__summary">No package test script was found.</div></div></div>'
|
|
@@ -1234,7 +1242,7 @@ function renderPackageSection(pkg, rootDir) {
|
|
|
1234
1242
|
moduleNames: pkg.modules,
|
|
1235
1243
|
packageNames: [pkg.name],
|
|
1236
1244
|
frameworks: pkg.frameworks,
|
|
1237
|
-
hasFailures: (pkg.summary?.failed || 0) > 0,
|
|
1245
|
+
hasFailures: status === 'failed' || (pkg.summary?.failed || 0) > 0,
|
|
1238
1246
|
lineCoverage: pkg.coverage?.lines?.pct,
|
|
1239
1247
|
});
|
|
1240
1248
|
return `
|
|
@@ -1292,7 +1300,11 @@ function renderThemeSection(moduleEntry, themeEntry, rootDir) {
|
|
|
1292
1300
|
}
|
|
1293
1301
|
|
|
1294
1302
|
function renderThemePackageSection(moduleEntry, themeEntry, packageEntry, rootDir) {
|
|
1295
|
-
const status =
|
|
1303
|
+
const status = deriveDisplayStatus({
|
|
1304
|
+
summary: packageEntry.summary,
|
|
1305
|
+
reportedStatus: packageEntry.status,
|
|
1306
|
+
suites: packageEntry.suites,
|
|
1307
|
+
});
|
|
1296
1308
|
const suites = Array.isArray(packageEntry.suites) ? packageEntry.suites : [];
|
|
1297
1309
|
const suiteMarkup = suites.length === 0
|
|
1298
1310
|
? '<div class="suite"><div class="suite__summaryRow"><div><span class="suite__label">No test suites</span></div><div class="suite__summary">No suite results were grouped under this package.</div></div></div>'
|
|
@@ -1302,7 +1314,7 @@ function renderThemePackageSection(moduleEntry, themeEntry, packageEntry, rootDi
|
|
|
1302
1314
|
moduleNames: [moduleEntry.module],
|
|
1303
1315
|
packageNames: [packageEntry.name],
|
|
1304
1316
|
frameworks: packageEntry.frameworks,
|
|
1305
|
-
hasFailures: (packageEntry.summary?.failed || 0) > 0,
|
|
1317
|
+
hasFailures: status === 'failed' || (packageEntry.summary?.failed || 0) > 0,
|
|
1306
1318
|
});
|
|
1307
1319
|
return `
|
|
1308
1320
|
<details class="package-group" ${filterAttrs}>
|
|
@@ -1321,6 +1333,10 @@ function renderThemePackageSection(moduleEntry, themeEntry, packageEntry, rootDi
|
|
|
1321
1333
|
}
|
|
1322
1334
|
|
|
1323
1335
|
function renderSuite(suite, rootDir, filterContext = {}) {
|
|
1336
|
+
const status = deriveDisplayStatus({
|
|
1337
|
+
summary: suite.summary,
|
|
1338
|
+
reportedStatus: suite.status,
|
|
1339
|
+
});
|
|
1324
1340
|
const warnings = Array.isArray(suite.warnings) ? suite.warnings : [];
|
|
1325
1341
|
const tests = Array.isArray(suite.tests) ? suite.tests : [];
|
|
1326
1342
|
const rawArtifacts = Array.isArray(suite.rawArtifacts) ? suite.rawArtifacts : [];
|
|
@@ -1331,14 +1347,14 @@ function renderSuite(suite, rootDir, filterContext = {}) {
|
|
|
1331
1347
|
const diagnosticsMarkup = renderDiagnosticsBlock(suite.diagnostics);
|
|
1332
1348
|
const artifactMarkup = rawArtifacts.length > 0 ? renderRawArtifactBlock(rawArtifacts) : '';
|
|
1333
1349
|
const testsMarkup = tests.length === 0
|
|
1334
|
-
?
|
|
1350
|
+
? renderSuiteEmptyState(status)
|
|
1335
1351
|
: tests.map((test) => renderTest(suite, test, rootDir, filterContext)).join('');
|
|
1336
1352
|
const filterAttrs = renderFilterAttributes({
|
|
1337
1353
|
nodeType: 'suite',
|
|
1338
1354
|
moduleNames: filterContext.moduleNames || dedupe(tests.map((test) => test.module || 'uncategorized')),
|
|
1339
1355
|
packageNames: filterContext.packageNames || [],
|
|
1340
1356
|
frameworks: [suite.runtime],
|
|
1341
|
-
hasFailures: (suite.summary?.failed || 0) > 0,
|
|
1357
|
+
hasFailures: status === 'failed' || (suite.summary?.failed || 0) > 0,
|
|
1342
1358
|
lineCoverage: suite.coverage?.lines?.pct,
|
|
1343
1359
|
});
|
|
1344
1360
|
return `
|
|
@@ -1348,7 +1364,7 @@ function renderSuite(suite, rootDir, filterContext = {}) {
|
|
|
1348
1364
|
<div class="suite__label">${escapeHtml(suite.label)}</div>
|
|
1349
1365
|
<div class="suite__runtime">${escapeHtml(suite.runtime || 'custom')} • ${escapeHtml(suite.command || '')}</div>
|
|
1350
1366
|
</div>
|
|
1351
|
-
<div class="suite__summary">${escapeHtml(formatSummary(suite.summary))} • ${escapeHtml(formatDuration(suite.durationMs || 0))}</div>
|
|
1367
|
+
<div class="suite__summary">${renderStatusPill(status)} <span>${escapeHtml(formatSummary(suite.summary))} • ${escapeHtml(formatDuration(suite.durationMs || 0))}</span></div>
|
|
1352
1368
|
</summary>
|
|
1353
1369
|
<div class="suite__body">
|
|
1354
1370
|
${warningMarkup}
|
|
@@ -1361,6 +1377,17 @@ function renderSuite(suite, rootDir, filterContext = {}) {
|
|
|
1361
1377
|
`;
|
|
1362
1378
|
}
|
|
1363
1379
|
|
|
1380
|
+
function renderSuiteEmptyState(status) {
|
|
1381
|
+
const statusClass = status === 'failed' ? 'fail' : status === 'passed' ? 'pass' : 'skip';
|
|
1382
|
+
const title = status === 'failed'
|
|
1383
|
+
? 'Suite failed before emitting test results'
|
|
1384
|
+
: status === 'passed'
|
|
1385
|
+
? 'Suite passed without discrete test records'
|
|
1386
|
+
: 'No test results emitted';
|
|
1387
|
+
|
|
1388
|
+
return `<div class="test-row"><div class="test-row__summary"><span class="status-pill ${statusClass}">${escapeHtml(status)}</span><div class="test-row__name"><span class="test-row__title">${escapeHtml(title)}</span></div></div></div>`;
|
|
1389
|
+
}
|
|
1390
|
+
|
|
1364
1391
|
function renderRawArtifactBlock(rawArtifacts) {
|
|
1365
1392
|
return `
|
|
1366
1393
|
<section class="suite__artifacts">
|
|
@@ -1392,6 +1419,25 @@ function capitalize(value) {
|
|
|
1392
1419
|
return normalized.length > 0 ? normalized[0].toUpperCase() + normalized.slice(1) : normalized;
|
|
1393
1420
|
}
|
|
1394
1421
|
|
|
1422
|
+
function deriveDisplayStatus({ summary, reportedStatus = null, suites = [] } = {}) {
|
|
1423
|
+
const normalizedReportedStatus = normalizeOptionalStatus(reportedStatus);
|
|
1424
|
+
const suiteStatuses = (Array.isArray(suites) ? suites : []).map((suite) => normalizeOptionalStatus(suite?.status));
|
|
1425
|
+
|
|
1426
|
+
if (suiteStatuses.includes('failed') || normalizedReportedStatus === 'failed') {
|
|
1427
|
+
return 'failed';
|
|
1428
|
+
}
|
|
1429
|
+
|
|
1430
|
+
if (summary && summary.total > 0) {
|
|
1431
|
+
return deriveStatusFromSummary(summary);
|
|
1432
|
+
}
|
|
1433
|
+
|
|
1434
|
+
if (suiteStatuses.includes('passed') || normalizedReportedStatus === 'passed') {
|
|
1435
|
+
return 'passed';
|
|
1436
|
+
}
|
|
1437
|
+
|
|
1438
|
+
return 'skipped';
|
|
1439
|
+
}
|
|
1440
|
+
|
|
1395
1441
|
function renderTest(suite, test, rootDir, filterContext = {}) {
|
|
1396
1442
|
const statusClass = test.status === 'failed' ? 'fail' : test.status === 'skipped' ? 'skip' : 'pass';
|
|
1397
1443
|
const assertions = Array.isArray(test.assertions) && test.assertions.length > 0
|
|
@@ -1592,6 +1638,13 @@ function deriveStatusFromSummary(summary) {
|
|
|
1592
1638
|
return 'passed';
|
|
1593
1639
|
}
|
|
1594
1640
|
|
|
1641
|
+
function normalizeOptionalStatus(status) {
|
|
1642
|
+
if (status === 'failed' || status === 'skipped' || status === 'passed') {
|
|
1643
|
+
return status;
|
|
1644
|
+
}
|
|
1645
|
+
return null;
|
|
1646
|
+
}
|
|
1647
|
+
|
|
1595
1648
|
function formatSummary(summary = {}) {
|
|
1596
1649
|
const total = Number.isFinite(summary.total) ? summary.total : 0;
|
|
1597
1650
|
const passed = Number.isFinite(summary.passed) ? summary.passed : 0;
|