@arghajit/dummy 0.3.27 → 0.3.31
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/dist/reporter/playwright-pulse-reporter.js +10 -3
- package/dist/types/index.d.ts +2 -0
- package/package.json +1 -1
- package/scripts/generate-email-report.mjs +18 -3
- package/scripts/generate-report.mjs +112 -35
- package/scripts/generate-static-report.mjs +106 -32
- package/scripts/merge-pulse-report.js +2 -1
- package/dist/index.d.ts +0 -5
- package/dist/index.js +0 -26
- package/dist/playwright-pulse-reporter.d.ts +0 -26
- package/dist/playwright-pulse-reporter.js +0 -304
- package/dist/reporter/lib/report-types.d.ts +0 -8
- package/dist/reporter/lib/report-types.js +0 -2
- package/dist/reporter/reporter/playwright-pulse-reporter.d.ts +0 -1
- package/dist/reporter/reporter/playwright-pulse-reporter.js +0 -398
- package/dist/reporter/types/index.d.ts +0 -52
- package/dist/reporter/types/index.js +0 -2
|
@@ -339,6 +339,12 @@ function generateTestTrendsChart(trendData) {
|
|
|
339
339
|
color: "var(--warning-color)",
|
|
340
340
|
marker: { symbol: "circle" },
|
|
341
341
|
},
|
|
342
|
+
{
|
|
343
|
+
name: "Flaky",
|
|
344
|
+
data: runs.map((r) => r.flaky || 0),
|
|
345
|
+
color: "#00ccd3",
|
|
346
|
+
marker: { symbol: "circle" },
|
|
347
|
+
},
|
|
342
348
|
];
|
|
343
349
|
const runsForTooltip = runs.map((r) => ({
|
|
344
350
|
runId: r.runId,
|
|
@@ -542,6 +548,9 @@ function generateTestHistoryChart(history) {
|
|
|
542
548
|
case "skipped":
|
|
543
549
|
color = "var(--warning-color)";
|
|
544
550
|
break;
|
|
551
|
+
case "flaky":
|
|
552
|
+
color = "var(--neutral-500)";
|
|
553
|
+
break;
|
|
545
554
|
default:
|
|
546
555
|
color = "var(--dark-gray-color)";
|
|
547
556
|
}
|
|
@@ -658,6 +667,9 @@ function generatePieChart(data, chartWidth = 300, chartHeight = 300) {
|
|
|
658
667
|
case "Failed":
|
|
659
668
|
color = "var(--danger-color)";
|
|
660
669
|
break;
|
|
670
|
+
case "Flaky":
|
|
671
|
+
color = "#00ccd3";
|
|
672
|
+
break;
|
|
661
673
|
case "Skipped":
|
|
662
674
|
color = "var(--warning-color)";
|
|
663
675
|
break;
|
|
@@ -904,7 +916,10 @@ function generateEnvironmentSection(environmentData) {
|
|
|
904
916
|
}
|
|
905
917
|
|
|
906
918
|
function generateEnvironmentDashboard(environment, hideHeader = false) {
|
|
907
|
-
const
|
|
919
|
+
const cpuModel = environment.cpu && environment.cpu.model ? environment.cpu.model : "N/A";
|
|
920
|
+
const cpuCores = environment.cpu && environment.cpu.cores ? environment.cpu.cores : "N/A";
|
|
921
|
+
const cpuInfo = `model: ${cpuModel}, cores: ${cpuCores}`;
|
|
922
|
+
const cwdInfo = environment.cwd || "N/A";
|
|
908
923
|
|
|
909
924
|
return `
|
|
910
925
|
<div class="env-modern-card${hideHeader ? " no-header" : ""}">
|
|
@@ -1294,7 +1309,7 @@ function generateEnvironmentDashboard(environment, hideHeader = false) {
|
|
|
1294
1309
|
</div>
|
|
1295
1310
|
<div class="env-item-content">
|
|
1296
1311
|
<p class="env-item-label">Working Dir</p>
|
|
1297
|
-
<div class="env-item-value" title="${
|
|
1312
|
+
<div class="env-item-value" title="${cwdInfo}">${cwdInfo.length > 30 ? "..." + cwdInfo.slice(-27) : cwdInfo}</div>
|
|
1298
1313
|
</div>
|
|
1299
1314
|
</div>
|
|
1300
1315
|
</div>
|
|
@@ -1323,11 +1338,11 @@ function generateWorkerDistributionChart(results) {
|
|
|
1323
1338
|
const workerId =
|
|
1324
1339
|
typeof test.workerId !== "undefined" ? test.workerId : "N/A";
|
|
1325
1340
|
if (!acc[workerId]) {
|
|
1326
|
-
acc[workerId] = { passed: 0, failed: 0, skipped: 0, tests: [] };
|
|
1341
|
+
acc[workerId] = { passed: 0, failed: 0, skipped: 0, flaky: 0, tests: [] };
|
|
1327
1342
|
}
|
|
1328
1343
|
|
|
1329
1344
|
const status = String(test.status).toLowerCase();
|
|
1330
|
-
if (status === "passed" || status === "failed" || status === "skipped") {
|
|
1345
|
+
if (status === "passed" || status === "failed" || status === "skipped" || status === "flaky") {
|
|
1331
1346
|
acc[workerId][status]++;
|
|
1332
1347
|
}
|
|
1333
1348
|
|
|
@@ -1372,6 +1387,7 @@ function generateWorkerDistributionChart(results) {
|
|
|
1372
1387
|
const passedData = workerIds.map((id) => workerData[id].passed);
|
|
1373
1388
|
const failedData = workerIds.map((id) => workerData[id].failed);
|
|
1374
1389
|
const skippedData = workerIds.map((id) => workerData[id].skipped);
|
|
1390
|
+
const flakyData = workerIds.map((id) => workerData[id].flaky);
|
|
1375
1391
|
|
|
1376
1392
|
const categoriesString = JSON.stringify(categories);
|
|
1377
1393
|
const fullDataString = JSON.stringify(fullWorkerData);
|
|
@@ -1379,6 +1395,7 @@ function generateWorkerDistributionChart(results) {
|
|
|
1379
1395
|
{ name: "Passed", data: passedData, color: "var(--success-color)" },
|
|
1380
1396
|
{ name: "Failed", data: failedData, color: "var(--danger-color)" },
|
|
1381
1397
|
{ name: "Skipped", data: skippedData, color: "var(--warning-color)" },
|
|
1398
|
+
{ name: "Flaky", data: flakyData, color: "#00ccd3" },
|
|
1382
1399
|
]);
|
|
1383
1400
|
|
|
1384
1401
|
// The HTML now includes the chart container, the modal, and styles for the modal
|
|
@@ -1645,6 +1662,7 @@ function generateTestHistoryContent(trendData) {
|
|
|
1645
1662
|
<option value="">All Statuses</option>
|
|
1646
1663
|
<option value="passed">Passed</option>
|
|
1647
1664
|
<option value="failed">Failed</option>
|
|
1665
|
+
<option value="flaky">Flaky</option>
|
|
1648
1666
|
<option value="skipped">Skipped</option>
|
|
1649
1667
|
</select>
|
|
1650
1668
|
<button id="clear-history-filters" class="clear-filters-btn">Clear Filters</button>
|
|
@@ -1716,7 +1734,7 @@ function getStatusClass(status) {
|
|
|
1716
1734
|
case "failed":
|
|
1717
1735
|
return "status-failed";
|
|
1718
1736
|
case "skipped":
|
|
1719
|
-
return "
|
|
1737
|
+
return "status-skipped";
|
|
1720
1738
|
case "flaky":
|
|
1721
1739
|
return "status-flaky";
|
|
1722
1740
|
default:
|
|
@@ -1778,6 +1796,7 @@ function getSuitesData(results) {
|
|
|
1778
1796
|
browser: browser,
|
|
1779
1797
|
passed: 0,
|
|
1780
1798
|
failed: 0,
|
|
1799
|
+
flaky: 0,
|
|
1781
1800
|
skipped: 0,
|
|
1782
1801
|
count: 0,
|
|
1783
1802
|
statusOverall: "passed",
|
|
@@ -1785,12 +1804,15 @@ function getSuitesData(results) {
|
|
|
1785
1804
|
}
|
|
1786
1805
|
const suite = suitesMap.get(key);
|
|
1787
1806
|
suite.count++;
|
|
1788
|
-
|
|
1807
|
+
let currentStatus = String(test.status).toLowerCase();
|
|
1808
|
+
if (test.outcome === 'flaky') currentStatus = 'flaky';
|
|
1789
1809
|
if (currentStatus && suite[currentStatus] !== undefined) {
|
|
1790
1810
|
suite[currentStatus]++;
|
|
1791
1811
|
}
|
|
1792
1812
|
if (currentStatus === "failed") suite.statusOverall = "failed";
|
|
1793
|
-
else if (currentStatus === "
|
|
1813
|
+
else if (currentStatus === "flaky" && suite.statusOverall !== "failed")
|
|
1814
|
+
suite.statusOverall = "flaky";
|
|
1815
|
+
else if (currentStatus === "skipped" && suite.statusOverall !== "failed" && suite.statusOverall !== "flaky")
|
|
1794
1816
|
suite.statusOverall = "skipped";
|
|
1795
1817
|
});
|
|
1796
1818
|
return Array.from(suitesMap.values());
|
|
@@ -1873,6 +1895,10 @@ function generateSuitesWidget(suitesData) {
|
|
|
1873
1895
|
<svg xmlns="http://www.w3.org/2000/svg" fill="currentColor" viewBox="0 0 16 16"><path d="M16 8A8 8 0 1 1 0 8a8 8 0 0 1 16 0zM5.354 4.646a.5.5 0 1 0-.708.708L7.293 8l-2.647 2.646a.5.5 0 0 0 .708.708L8 8.707l2.646 2.647a.5.5 0 0 0 .708-.708L8.707 8l2.647-2.646a.5.5 0 0 0-.708-.708L8 7.293 5.354 4.646z"/></svg>
|
|
1874
1896
|
${suite.failed}
|
|
1875
1897
|
</span>
|
|
1898
|
+
<span class="stat-pill flaky" title="Flaky">
|
|
1899
|
+
<svg xmlns="http://www.w3.org/2000/svg" fill="currentColor" viewBox="0 0 16 16"><path d="M8.982 1.566a1.13 1.13 0 0 0-1.96 0L.165 13.233c-.457.778.091 1.767.98 1.767h13.713c.889 0 1.438-.99.98-1.767L8.982 1.566zM8 5c.535 0 .954.462.9.995l-.35 3.507a.552.552 0 0 1-1.1 0L7.1 5.995A.905.905 0 0 1 8 5zm.002 6a1 1 0 1 1 0 2 1 1 0 0 1 0-2z"/></svg>
|
|
1900
|
+
${suite.flaky || 0}
|
|
1901
|
+
</span>
|
|
1876
1902
|
<span class="stat-pill skipped" title="Skipped">
|
|
1877
1903
|
<svg xmlns="http://www.w3.org/2000/svg" fill="currentColor" viewBox="0 0 16 16"><path d="M8.982 1.566a1.13 1.13 0 0 0-1.96 0L.165 13.233c-.457.778.091 1.767.98 1.767h13.713c.889 0 1.438-.99.98-1.767L8.982 1.566zM8 5c.535 0 .954.462.9.995l-.35 3.507a.552.552 0 0 1-1.1 0L7.1 5.995A.905.905 0 0 1 8 5zm.002 6a1 1 0 1 1 0 2 1 1 0 0 1 0-2z"/></svg>
|
|
1878
1904
|
${suite.skipped}
|
|
@@ -2255,6 +2281,7 @@ function generateSeverityDistributionChart(results) {
|
|
|
2255
2281
|
const data = {
|
|
2256
2282
|
passed: [0, 0, 0, 0, 0],
|
|
2257
2283
|
failed: [0, 0, 0, 0, 0],
|
|
2284
|
+
flaky: [0, 0, 0, 0, 0],
|
|
2258
2285
|
skipped: [0, 0, 0, 0, 0],
|
|
2259
2286
|
};
|
|
2260
2287
|
|
|
@@ -2273,6 +2300,8 @@ function generateSeverityDistributionChart(results) {
|
|
|
2273
2300
|
status === "interrupted"
|
|
2274
2301
|
) {
|
|
2275
2302
|
data.failed[index]++;
|
|
2303
|
+
} else if (status === "flaky") {
|
|
2304
|
+
data.flaky[index]++;
|
|
2276
2305
|
} else {
|
|
2277
2306
|
data.skipped[index]++;
|
|
2278
2307
|
}
|
|
@@ -2286,6 +2315,7 @@ function generateSeverityDistributionChart(results) {
|
|
|
2286
2315
|
const seriesData = [
|
|
2287
2316
|
{ name: "Passed", data: data.passed, color: "var(--success-color)" },
|
|
2288
2317
|
{ name: "Failed", data: data.failed, color: "var(--danger-color)" },
|
|
2318
|
+
{ name: "Flaky", data: data.flaky, color: "#00ccd3" },
|
|
2289
2319
|
{ name: "Skipped", data: data.skipped, color: "var(--warning-color)" },
|
|
2290
2320
|
];
|
|
2291
2321
|
|
|
@@ -2429,21 +2459,27 @@ function generateHTML(reportData, trendData = null) {
|
|
|
2429
2459
|
duration: 0,
|
|
2430
2460
|
timestamp: new Date().toISOString(),
|
|
2431
2461
|
};
|
|
2432
|
-
|
|
2433
|
-
const passPercentage = Math.round((runSummary.passed / totalTestsOr1) * 100);
|
|
2434
|
-
const failPercentage = Math.round((runSummary.failed / totalTestsOr1) * 100);
|
|
2435
|
-
const skipPercentage = Math.round(
|
|
2436
|
-
((runSummary.skipped || 0) / totalTestsOr1) * 100,
|
|
2437
|
-
);
|
|
2462
|
+
|
|
2438
2463
|
const avgTestDuration =
|
|
2439
2464
|
runSummary.totalTests > 0
|
|
2440
2465
|
? formatDuration(runSummary.duration / runSummary.totalTests)
|
|
2441
2466
|
: "0.0s";
|
|
2442
2467
|
|
|
2468
|
+
const flakyCount = (results || []).filter(r => r.outcome === 'flaky').length;
|
|
2469
|
+
|
|
2443
2470
|
// Calculate retry statistics
|
|
2471
|
+
let retriedTestsCount = 0;
|
|
2444
2472
|
const totalRetried = (results || []).reduce((acc, test) => {
|
|
2445
2473
|
if (test.retryHistory && test.retryHistory.length > 0) {
|
|
2446
|
-
|
|
2474
|
+
// Filter out any "passed" or "skipped" entries in the history
|
|
2475
|
+
// We only count attempts that actually failed or timed out, triggering a retry.
|
|
2476
|
+
const unsuccessfulRetries = test.retryHistory.filter(attempt =>
|
|
2477
|
+
attempt.status === 'failed' || attempt.status === 'timedout' || attempt.status === 'flaky'
|
|
2478
|
+
);
|
|
2479
|
+
if (unsuccessfulRetries.length > 0) {
|
|
2480
|
+
retriedTestsCount++;
|
|
2481
|
+
}
|
|
2482
|
+
return acc + unsuccessfulRetries.length;
|
|
2447
2483
|
}
|
|
2448
2484
|
return acc;
|
|
2449
2485
|
}, 0);
|
|
@@ -2452,19 +2488,30 @@ function generateHTML(reportData, trendData = null) {
|
|
|
2452
2488
|
let calculatedPassed = 0;
|
|
2453
2489
|
let calculatedFailed = 0;
|
|
2454
2490
|
let calculatedSkipped = 0;
|
|
2491
|
+
let calculatedFlaky = 0;
|
|
2455
2492
|
let calculatedTotal = 0;
|
|
2456
2493
|
|
|
2457
2494
|
(results || []).forEach(test => {
|
|
2458
2495
|
calculatedTotal++;
|
|
2459
|
-
//
|
|
2460
|
-
|
|
2461
|
-
|
|
2462
|
-
|
|
2496
|
+
// New Logic: If outcome is 'flaky', it overrides everything.
|
|
2497
|
+
let statusToUse = test.status;
|
|
2498
|
+
if (test.outcome === 'flaky') {
|
|
2499
|
+
statusToUse = 'flaky';
|
|
2500
|
+
} else if (test.status === 'flaky') {
|
|
2501
|
+
// Just in case outcome wasn't set but status was (unlikely with new reporter)
|
|
2502
|
+
statusToUse = 'flaky';
|
|
2503
|
+
} else if (test.retryHistory && test.retryHistory.length > 0 && test.final_status) {
|
|
2504
|
+
statusToUse = test.final_status;
|
|
2505
|
+
}
|
|
2506
|
+
|
|
2507
|
+
// Update test status in place for charts
|
|
2508
|
+
test.status = statusToUse;
|
|
2463
2509
|
|
|
2464
2510
|
const s = String(statusToUse).toLowerCase();
|
|
2465
2511
|
if (s === 'passed') calculatedPassed++;
|
|
2466
2512
|
else if (s === 'skipped') calculatedSkipped++;
|
|
2467
|
-
else
|
|
2513
|
+
else if (s === 'flaky') calculatedFlaky++;
|
|
2514
|
+
else calculatedFailed++; // failed, timedout, interrupted
|
|
2468
2515
|
});
|
|
2469
2516
|
|
|
2470
2517
|
// Override runSummary counts with our calculated ones if results exist
|
|
@@ -2472,9 +2519,18 @@ function generateHTML(reportData, trendData = null) {
|
|
|
2472
2519
|
runSummary.passed = calculatedPassed;
|
|
2473
2520
|
runSummary.failed = calculatedFailed;
|
|
2474
2521
|
runSummary.skipped = calculatedSkipped;
|
|
2522
|
+
runSummary.flaky = calculatedFlaky;
|
|
2475
2523
|
runSummary.totalTests = calculatedTotal;
|
|
2476
2524
|
}
|
|
2477
2525
|
|
|
2526
|
+
const totalTestsOr1 = runSummary.totalTests || 1;
|
|
2527
|
+
const passPercentage = Math.round((runSummary.passed / totalTestsOr1) * 100);
|
|
2528
|
+
const failPercentage = Math.round((runSummary.failed / totalTestsOr1) * 100);
|
|
2529
|
+
const skipPercentage = Math.round(
|
|
2530
|
+
((runSummary.skipped || 0) / totalTestsOr1) * 100,
|
|
2531
|
+
);
|
|
2532
|
+
const flakyPercentage = Math.round(((runSummary.flaky || 0) / totalTestsOr1) * 100);
|
|
2533
|
+
|
|
2478
2534
|
|
|
2479
2535
|
// Calculate browser distribution
|
|
2480
2536
|
const browserStats = (results || []).reduce((acc, test) => {
|
|
@@ -2523,8 +2579,8 @@ function generateHTML(reportData, trendData = null) {
|
|
|
2523
2579
|
const severityBadge = `<span class="severity-badge" data-severity="${severity.toLowerCase()}">${severity}</span>`;
|
|
2524
2580
|
|
|
2525
2581
|
// --- Retry Count Badge (only show if retries occurred) ---
|
|
2526
|
-
const retryCount = test.retryHistory ? test.retryHistory.length : 0;
|
|
2527
|
-
const retryBadge =
|
|
2582
|
+
const retryCount = (test.retryHistory && test.retryHistory.length > 0) ? test.retryHistory.length : 0;
|
|
2583
|
+
const retryBadge = (test.retryHistory && test.retryHistory.length > 0) ? `<span class="retry-badge">Retry Count: ${retryCount}</span>` : '';
|
|
2528
2584
|
|
|
2529
2585
|
// --- Step Generation ---
|
|
2530
2586
|
const generateStepsHTML = (steps, depth = 0) => {
|
|
@@ -2602,6 +2658,7 @@ function generateHTML(reportData, trendData = null) {
|
|
|
2602
2658
|
if(s === 'passed') colorVar = 'var(--success-color)';
|
|
2603
2659
|
else if(s === 'failed') colorVar = 'var(--danger-color)';
|
|
2604
2660
|
else if(s === 'skipped') colorVar = 'var(--warning-color)';
|
|
2661
|
+
else if(s === 'flaky') colorVar = '#00ccd3';
|
|
2605
2662
|
|
|
2606
2663
|
return `<span style="
|
|
2607
2664
|
display: inline-block;
|
|
@@ -2876,7 +2933,7 @@ function generateHTML(reportData, trendData = null) {
|
|
|
2876
2933
|
? test.final_status
|
|
2877
2934
|
: test.status;
|
|
2878
2935
|
|
|
2879
|
-
const outcomeBadge = (test.outcome)
|
|
2936
|
+
const outcomeBadge = (test.outcome && test.outcome !== 'flaky')
|
|
2880
2937
|
? `<span class="outcome-badge ${test.outcome}">${test.outcome}</span>`
|
|
2881
2938
|
: '';
|
|
2882
2939
|
|
|
@@ -2970,7 +3027,8 @@ function generateHTML(reportData, trendData = null) {
|
|
|
2970
3027
|
--success-color: #34d399; --success-dark: #10b981; --success-light: #6ee7b7;
|
|
2971
3028
|
--danger-color: #f87171; --danger-dark: #ef4444; --danger-light: #fca5a5;
|
|
2972
3029
|
--warning-color: #fbbf24; --warning-dark: #f59e0b; --warning-light: #fcd34d;
|
|
2973
|
-
--info-color: #9ca3af;
|
|
3030
|
+
--info-color: #9ca3af;
|
|
3031
|
+
--flaky-color: #00ccd3;
|
|
2974
3032
|
--text-primary: #f9fafb; --text-secondary: #e5e7eb; --text-tertiary: #d1d5db;
|
|
2975
3033
|
--bg-primary: #000000; --bg-secondary: #0a0a0a; --bg-tertiary: #050505;
|
|
2976
3034
|
--bg-card: #0d0d0d; --bg-card-hover: #121212;
|
|
@@ -3423,6 +3481,16 @@ function generateHTML(reportData, trendData = null) {
|
|
|
3423
3481
|
.summary-card.status-skipped .value {
|
|
3424
3482
|
color: #f59e0b;
|
|
3425
3483
|
}
|
|
3484
|
+
.summary-card.flaky-status {
|
|
3485
|
+
background: rgba(0, 204, 211, 0.05);
|
|
3486
|
+
}
|
|
3487
|
+
.summary-card.flaky-status:hover {
|
|
3488
|
+
background: rgba(0, 204, 211, 0.15);
|
|
3489
|
+
box-shadow: 0 4px 12px rgba(0, 204, 211, 0.2);
|
|
3490
|
+
}
|
|
3491
|
+
.summary-card.flaky-status .value {
|
|
3492
|
+
color: #00ccd3;
|
|
3493
|
+
}
|
|
3426
3494
|
.summary-card:not([class*='status-']) .value {
|
|
3427
3495
|
color: #f9fafb;
|
|
3428
3496
|
}
|
|
@@ -3545,6 +3613,7 @@ function generateHTML(reportData, trendData = null) {
|
|
|
3545
3613
|
}
|
|
3546
3614
|
.suite-card.status-passed::before { background: var(--success-color); }
|
|
3547
3615
|
.suite-card.status-failed::before { background: var(--danger-color); }
|
|
3616
|
+
.suite-card.status-flaky::before { background: #00ccd3; }
|
|
3548
3617
|
.suite-card.status-skipped::before { background: var(--warning-color); }
|
|
3549
3618
|
|
|
3550
3619
|
.suite-card.status-skipped::before { background: var(--warning-color); }
|
|
@@ -3562,8 +3631,8 @@ function generateHTML(reportData, trendData = null) {
|
|
|
3562
3631
|
letter-spacing: 0.5px;
|
|
3563
3632
|
}
|
|
3564
3633
|
.outcome-badge.flaky {
|
|
3565
|
-
background-color: #
|
|
3566
|
-
color: #
|
|
3634
|
+
background-color: #00ccd3;
|
|
3635
|
+
color: #fff;
|
|
3567
3636
|
}
|
|
3568
3637
|
|
|
3569
3638
|
.suite-card-header {
|
|
@@ -3647,6 +3716,7 @@ function generateHTML(reportData, trendData = null) {
|
|
|
3647
3716
|
.stat-pill svg { width: 14px; height: 14px; }
|
|
3648
3717
|
.stat-pill.passed { color: var(--success-dark); }
|
|
3649
3718
|
.stat-pill.failed { color: var(--danger-dark); }
|
|
3719
|
+
.stat-pill.flaky { color: #00ccd3; }
|
|
3650
3720
|
.stat-pill.skipped { color: var(--warning-dark); }
|
|
3651
3721
|
color: #93c5fd;
|
|
3652
3722
|
padding: 6px 12px;
|
|
@@ -3842,9 +3912,8 @@ function generateHTML(reportData, trendData = null) {
|
|
|
3842
3912
|
background: var(--warning-color);
|
|
3843
3913
|
}
|
|
3844
3914
|
.status-badge.status-flaky {
|
|
3845
|
-
background:
|
|
3846
|
-
color:
|
|
3847
|
-
border: 1px solid var(--warning-color);
|
|
3915
|
+
background-color: #00ccd3;
|
|
3916
|
+
color: #fff;
|
|
3848
3917
|
}
|
|
3849
3918
|
.status-badge.status-unknown {
|
|
3850
3919
|
background: var(--dark-gray-color);
|
|
@@ -4480,7 +4549,8 @@ function generateHTML(reportData, trendData = null) {
|
|
|
4480
4549
|
background-color: #f59e0b;
|
|
4481
4550
|
}
|
|
4482
4551
|
.status-badge-small.status-flaky {
|
|
4483
|
-
background-color: #
|
|
4552
|
+
background-color: #00ccd3;
|
|
4553
|
+
color: #fff;
|
|
4484
4554
|
}
|
|
4485
4555
|
.status-badge-small.status-unknown {
|
|
4486
4556
|
background-color: var(--dark-gray-color);
|
|
@@ -6182,13 +6252,15 @@ function generateHTML(reportData, trendData = null) {
|
|
|
6182
6252
|
<div class="summary-card status-skipped"><h3>Skipped</h3><div class="value">${
|
|
6183
6253
|
runSummary.skipped || 0
|
|
6184
6254
|
}</div><div class="trend-percentage">${skipPercentage}%</div></div>
|
|
6185
|
-
<div class="summary-card"><h3>
|
|
6255
|
+
<div class="summary-card flaky-status"><h3>Flaky</h3><div class="value">${runSummary.flaky || 0}</div>
|
|
6256
|
+
<div class="trend-percentage">${flakyPercentage}%</div></div>
|
|
6186
6257
|
<div class="summary-card"><h3>Run Duration</h3><div class="value">${formatDuration(
|
|
6187
6258
|
runSummary.duration,
|
|
6188
|
-
)}</div></div>
|
|
6259
|
+
)}</div><div class="trend-percentage">Avg. Test Duration ${avgTestDuration}</div></div>
|
|
6189
6260
|
<div class="summary-card">
|
|
6190
6261
|
<h3>Total Retry Count</h3>
|
|
6191
6262
|
<div class="value">${totalRetried}</div>
|
|
6263
|
+
<div class="trend-percentage">Test Retried ${retriedTestsCount}</div>
|
|
6192
6264
|
</div>
|
|
6193
6265
|
<div class="summary-card">
|
|
6194
6266
|
<h3>🌐 Browser Distribution <span style="font-size: 0.7em; color: var(--text-color-secondary); font-weight: 400;">(${browserBreakdown.length} total)</span></h3>
|
|
@@ -6219,6 +6291,7 @@ function generateHTML(reportData, trendData = null) {
|
|
|
6219
6291
|
[
|
|
6220
6292
|
{ label: "Passed", value: runSummary.passed },
|
|
6221
6293
|
{ label: "Failed", value: runSummary.failed },
|
|
6294
|
+
{ label: "Flaky", value: runSummary.flaky || 0 },
|
|
6222
6295
|
{ label: "Skipped", value: runSummary.skipped || 0 },
|
|
6223
6296
|
],
|
|
6224
6297
|
400,
|
|
@@ -6235,7 +6308,7 @@ function generateHTML(reportData, trendData = null) {
|
|
|
6235
6308
|
<div id="test-runs" class="tab-content">
|
|
6236
6309
|
<div class="filters" style="border-color: black; border-style: groove;">
|
|
6237
6310
|
<input type="text" id="filter-name" placeholder="Filter by test name/path..." style="border-color: black; border-style: outset;">
|
|
6238
|
-
<select id="filter-status"><option value="">All Statuses</option><option value="passed">Passed</option><option value="failed">Failed</option><option value="skipped">Skipped</option></select>
|
|
6311
|
+
<select id="filter-status"><option value="">All Statuses</option><option value="passed">Passed</option><option value="failed">Failed</option><option value="flaky">Flaky</option><option value="skipped">Skipped</option></select>
|
|
6239
6312
|
<select id="filter-browser"><option value="">All Browsers</option>${Array.from(
|
|
6240
6313
|
new Set(
|
|
6241
6314
|
(results || []).map((test) => test.browser || "unknown"),
|
|
@@ -7175,6 +7248,7 @@ async function main() {
|
|
|
7175
7248
|
passed: histRunReport.run.passed,
|
|
7176
7249
|
failed: histRunReport.run.failed,
|
|
7177
7250
|
skipped: histRunReport.run.skipped || 0,
|
|
7251
|
+
flaky: histRunReport.run.flaky || (histRunReport.results ? histRunReport.results.filter(r => r.status === 'flaky' || r.outcome === 'flaky').length : 0),
|
|
7178
7252
|
});
|
|
7179
7253
|
|
|
7180
7254
|
if (histRunReport.results && Array.isArray(histRunReport.results)) {
|
|
@@ -92,6 +92,7 @@ function mergeReports(shardDirs) {
|
|
|
92
92
|
combinedRun.passed += run.passed || 0;
|
|
93
93
|
combinedRun.failed += run.failed || 0;
|
|
94
94
|
combinedRun.skipped += run.skipped || 0;
|
|
95
|
+
combinedRun.flaky = (combinedRun.flaky || 0) + (run.flaky || 0);
|
|
95
96
|
combinedRun.duration += run.duration || 0;
|
|
96
97
|
|
|
97
98
|
if (run.environment) {
|
|
@@ -228,7 +229,7 @@ function cleanupShardDirectories(shardDirs) {
|
|
|
228
229
|
|
|
229
230
|
console.log(`\n✅ Merged report saved as ${OUTPUT_FILE}`);
|
|
230
231
|
console.log(` Total tests: ${merged.run.totalTests}`);
|
|
231
|
-
console.log(` Passed: ${merged.run.passed} | Failed: ${merged.run.failed} | Skipped: ${merged.run.skipped}`);
|
|
232
|
+
console.log(` Passed: ${merged.run.passed} | Failed: ${merged.run.failed} | Skipped: ${merged.run.skipped} | Flaky: ${merged.run.flaky}`);
|
|
232
233
|
|
|
233
234
|
// 5. Cleanup Shard Directories
|
|
234
235
|
cleanupShardDirectories(shardDirs);
|
package/dist/index.d.ts
DELETED
package/dist/index.js
DELETED
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
-
if (k2 === undefined) k2 = k;
|
|
4
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
-
}
|
|
8
|
-
Object.defineProperty(o, k2, desc);
|
|
9
|
-
}) : (function(o, m, k, k2) {
|
|
10
|
-
if (k2 === undefined) k2 = k;
|
|
11
|
-
o[k2] = m[k];
|
|
12
|
-
}));
|
|
13
|
-
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
-
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
-
};
|
|
16
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
-
exports.PlaywrightPulseReporter = void 0;
|
|
18
|
-
// src/reporter/index.ts
|
|
19
|
-
const playwright_pulse_reporter_1 = require("./playwright-pulse-reporter");
|
|
20
|
-
Object.defineProperty(exports, "PlaywrightPulseReporter", { enumerable: true, get: function () { return playwright_pulse_reporter_1.PlaywrightPulseReporter; } });
|
|
21
|
-
// Export the reporter class as the default export for CommonJS compatibility
|
|
22
|
-
// and also as a named export for potential ES module consumers.
|
|
23
|
-
exports.default = playwright_pulse_reporter_1.PlaywrightPulseReporter;
|
|
24
|
-
// You can also export other related types or utilities if needed
|
|
25
|
-
__exportStar(require("../types"), exports); // Re-export shared types if they are used by the reporter consumers
|
|
26
|
-
__exportStar(require("../lib/report-types"), exports);
|
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
import type { FullConfig, FullResult, Reporter, Suite, TestCase, TestResult as PwTestResult } from "@playwright/test/reporter";
|
|
2
|
-
export declare class PlaywrightPulseReporter implements Reporter {
|
|
3
|
-
private config;
|
|
4
|
-
private suite;
|
|
5
|
-
private results;
|
|
6
|
-
private runStartTime;
|
|
7
|
-
private outputDir;
|
|
8
|
-
private baseOutputFile;
|
|
9
|
-
private isSharded;
|
|
10
|
-
private shardIndex;
|
|
11
|
-
constructor(options?: {
|
|
12
|
-
outputFile?: string;
|
|
13
|
-
outputDir?: string;
|
|
14
|
-
});
|
|
15
|
-
printsToStdio(): boolean;
|
|
16
|
-
onBegin(config: FullConfig, suite: Suite): void;
|
|
17
|
-
onTestBegin(test: TestCase): void;
|
|
18
|
-
private processStep;
|
|
19
|
-
onTestEnd(test: TestCase, result: PwTestResult): void;
|
|
20
|
-
onError(error: any): void;
|
|
21
|
-
private _writeShardResults;
|
|
22
|
-
private _mergeShardResults;
|
|
23
|
-
private _cleanupTemporaryFiles;
|
|
24
|
-
private _ensureDirExists;
|
|
25
|
-
onEnd(result: FullResult): Promise<void>;
|
|
26
|
-
}
|