@arghajit/dummy 0.3.27 → 0.3.28
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/lib/data-reader.js +116 -0
- package/dist/lib/data.js +39 -0
- package/dist/lib/utils.js +1 -0
- package/dist/pulse.js +3 -6
- package/dist/reporter/playwright-pulse-reporter.js +4 -1
- package/dist/tsconfig.tsbuildinfo +1 -0
- package/dist/types/index.d.ts +2 -0
- package/package.json +1 -1
- package/scripts/generate-report.mjs +86 -21
- package/scripts/generate-static-report.mjs +88 -25
- package/scripts/merge-pulse-report.js +2 -1
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
'use server';
|
|
2
|
+
import * as fs from 'fs/promises';
|
|
3
|
+
import * as path from 'path';
|
|
4
|
+
const reportFileName = 'playwright-pulse-report.json'; // Use a constant for the filename
|
|
5
|
+
const reportFilePath = path.resolve(process.cwd(), reportFileName); // Default path relative to cwd
|
|
6
|
+
let cachedReportData = null;
|
|
7
|
+
let lastReadTime = null;
|
|
8
|
+
const CACHE_DURATION = 5000; // Cache duration in milliseconds (e.g., 5 seconds)
|
|
9
|
+
export async function readReportDataInternal() {
|
|
10
|
+
const now = Date.now();
|
|
11
|
+
// Use cache if it's recent and not forced refresh
|
|
12
|
+
if (cachedReportData && lastReadTime && (now - lastReadTime < CACHE_DURATION)) {
|
|
13
|
+
// console.log("Returning cached report data.");
|
|
14
|
+
return cachedReportData;
|
|
15
|
+
}
|
|
16
|
+
// console.log(`Attempting to read report file from: ${reportFilePath}`);
|
|
17
|
+
try {
|
|
18
|
+
const fileContent = await fs.readFile(reportFilePath, 'utf-8');
|
|
19
|
+
let parsedData;
|
|
20
|
+
try {
|
|
21
|
+
parsedData = JSON.parse(fileContent);
|
|
22
|
+
}
|
|
23
|
+
catch (parseError) {
|
|
24
|
+
console.error(`Error parsing JSON from ${reportFilePath}:`, parseError);
|
|
25
|
+
throw new Error(`Invalid JSON in report file: ${parseError.message}`);
|
|
26
|
+
}
|
|
27
|
+
// --- Date Reviver ---
|
|
28
|
+
// Function to convert ISO date strings back to Date objects recursively
|
|
29
|
+
const reviveDates = (key, value) => {
|
|
30
|
+
// Matches ISO 8601 date format (YYYY-MM-DDTHH:mm:ss.sssZ)
|
|
31
|
+
const isoDateRegex = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(\.\d+)?Z$/;
|
|
32
|
+
if (typeof value === 'string' && isoDateRegex.test(value)) {
|
|
33
|
+
const date = new Date(value);
|
|
34
|
+
// Check if the parsed date is valid before returning
|
|
35
|
+
if (!isNaN(date.getTime())) {
|
|
36
|
+
return date;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
return value;
|
|
40
|
+
};
|
|
41
|
+
// Re-parse with the date reviver
|
|
42
|
+
const reportData = JSON.parse(fileContent, reviveDates);
|
|
43
|
+
// Basic validation after parsing and date revival
|
|
44
|
+
if (!reportData || typeof reportData !== 'object') {
|
|
45
|
+
throw new Error('Report file is empty or not a valid object.');
|
|
46
|
+
}
|
|
47
|
+
if (!reportData.metadata || typeof reportData.metadata.generatedAt !== 'string') { // generatedAt should remain string from JSON
|
|
48
|
+
throw new Error('Invalid or missing metadata in report file.');
|
|
49
|
+
}
|
|
50
|
+
if (!Array.isArray(reportData.results)) {
|
|
51
|
+
throw new Error('Missing or invalid "results" array in report file.');
|
|
52
|
+
}
|
|
53
|
+
// Optional: Validate run data if present
|
|
54
|
+
if (reportData.run && typeof reportData.run !== 'object') {
|
|
55
|
+
throw new Error('Invalid "run" data in report file.');
|
|
56
|
+
}
|
|
57
|
+
if (reportData.run && !(reportData.run.timestamp instanceof Date)) {
|
|
58
|
+
console.warn('Warning: Run timestamp was not correctly revived to a Date object.');
|
|
59
|
+
// Potentially attempt fallback parsing or throw error
|
|
60
|
+
reportData.run.timestamp = new Date(reportData.run.timestamp); // Attempt fallback
|
|
61
|
+
if (isNaN(reportData.run.timestamp.getTime())) {
|
|
62
|
+
throw new Error('Invalid run timestamp format.');
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
// Validate dates within results and steps
|
|
66
|
+
reportData.results.forEach((result, index) => {
|
|
67
|
+
if (!(result.startTime instanceof Date) || !(result.endTime instanceof Date)) {
|
|
68
|
+
console.warn(`Warning: Invalid start/end time for result index ${index}. Attempting fallback parsing.`);
|
|
69
|
+
result.startTime = new Date(result.startTime);
|
|
70
|
+
result.endTime = new Date(result.endTime);
|
|
71
|
+
if (isNaN(result.startTime.getTime()) || isNaN(result.endTime.getTime())) {
|
|
72
|
+
throw new Error(`Invalid start/end time in result index ${index}.`);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
if (Array.isArray(result.steps)) {
|
|
76
|
+
result.steps.forEach((step, stepIndex) => {
|
|
77
|
+
if (!(step.startTime instanceof Date) || !(step.endTime instanceof Date)) {
|
|
78
|
+
console.warn(`Warning: Invalid start/end time for step index ${stepIndex} in result index ${index}. Attempting fallback parsing.`);
|
|
79
|
+
step.startTime = new Date(step.startTime);
|
|
80
|
+
step.endTime = new Date(step.endTime);
|
|
81
|
+
if (isNaN(step.startTime.getTime()) || isNaN(step.endTime.getTime())) {
|
|
82
|
+
throw new Error(`Invalid start/end time in step index ${stepIndex}, result index ${index}.`);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
else {
|
|
88
|
+
result.steps = []; // Initialize if steps array is missing
|
|
89
|
+
}
|
|
90
|
+
});
|
|
91
|
+
cachedReportData = reportData;
|
|
92
|
+
lastReadTime = now;
|
|
93
|
+
// console.log("Successfully read, parsed, and cached report file.");
|
|
94
|
+
return reportData;
|
|
95
|
+
}
|
|
96
|
+
catch (error) {
|
|
97
|
+
if (error.code === 'ENOENT') {
|
|
98
|
+
console.warn(`Report file not found at ${reportFilePath}. Returning empty data structure. Ensure Playwright tests ran with the reporter enabled and the file exists.`);
|
|
99
|
+
// Return a valid, empty structure
|
|
100
|
+
const defaultReport = {
|
|
101
|
+
run: null,
|
|
102
|
+
results: [],
|
|
103
|
+
metadata: { generatedAt: new Date().toISOString() }
|
|
104
|
+
};
|
|
105
|
+
cachedReportData = defaultReport; // Cache the default empty state
|
|
106
|
+
lastReadTime = now;
|
|
107
|
+
return defaultReport;
|
|
108
|
+
}
|
|
109
|
+
else {
|
|
110
|
+
// Log the specific error for debugging
|
|
111
|
+
console.error(`Error processing report file at ${reportFilePath}:`, error);
|
|
112
|
+
// Propagate a user-friendly error
|
|
113
|
+
throw new Error(`Failed to load report data: ${error.message}`);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
}
|
package/dist/lib/data.js
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
'use server';
|
|
2
|
+
import { readReportDataInternal } from './data-reader'; // Import the server-only reader
|
|
3
|
+
// --- Modified Data Fetching Functions ---
|
|
4
|
+
export const getLatestTestRun = async () => {
|
|
5
|
+
await new Promise(resolve => setTimeout(resolve, 20)); // Minimal delay for demo
|
|
6
|
+
const reportData = await readReportDataInternal();
|
|
7
|
+
return reportData.run;
|
|
8
|
+
};
|
|
9
|
+
export const getTestResultById = async (testId) => {
|
|
10
|
+
await new Promise(resolve => setTimeout(resolve, 20)); // Minimal delay for demo
|
|
11
|
+
const reportData = await readReportDataInternal();
|
|
12
|
+
return reportData.results.find(r => r.id === testId) || null;
|
|
13
|
+
};
|
|
14
|
+
export const getTrendData = async (limit = 1) => {
|
|
15
|
+
await new Promise(resolve => setTimeout(resolve, 30)); // Minimal delay for demo
|
|
16
|
+
const reportData = await readReportDataInternal();
|
|
17
|
+
if (reportData.run) {
|
|
18
|
+
const run = reportData.run;
|
|
19
|
+
// Return a single data point based on the current run
|
|
20
|
+
// You might want a more sophisticated trend mechanism later
|
|
21
|
+
return [{
|
|
22
|
+
date: run.timestamp.toISOString().split('T')[0], // Use date part of timestamp
|
|
23
|
+
passed: run.passed,
|
|
24
|
+
failed: run.failed,
|
|
25
|
+
skipped: run.skipped,
|
|
26
|
+
}];
|
|
27
|
+
}
|
|
28
|
+
return [];
|
|
29
|
+
};
|
|
30
|
+
export const getAllTestResults = async () => {
|
|
31
|
+
await new Promise(resolve => setTimeout(resolve, 50)); // Minimal delay for demo
|
|
32
|
+
const reportData = await readReportDataInternal();
|
|
33
|
+
return reportData.results;
|
|
34
|
+
};
|
|
35
|
+
export const getTestRuns = async (limit = 1) => {
|
|
36
|
+
await new Promise(resolve => setTimeout(resolve, 30)); // Minimal delay for demo
|
|
37
|
+
const reportData = await readReportDataInternal();
|
|
38
|
+
return reportData.run ? [reportData.run] : [];
|
|
39
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export function cn(...inputs) { }
|
package/dist/pulse.js
CHANGED
|
@@ -1,8 +1,5 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
exports.pulse = void 0;
|
|
4
|
-
const test_1 = require("@playwright/test");
|
|
5
|
-
exports.pulse = {
|
|
1
|
+
import { test } from "@playwright/test";
|
|
2
|
+
export const pulse = {
|
|
6
3
|
/**
|
|
7
4
|
* Sets the severity level for the current test.
|
|
8
5
|
* * @param level - The severity level ('Minor' | 'Low' | 'Medium' | 'High' | 'Critical')
|
|
@@ -16,7 +13,7 @@ exports.pulse = {
|
|
|
16
13
|
// Default to "Medium" if an invalid string is passed
|
|
17
14
|
const selectedLevel = validLevels.includes(level) ? level : "Medium";
|
|
18
15
|
// Add the annotation to Playwright's test info
|
|
19
|
-
|
|
16
|
+
test.info().annotations.push({
|
|
20
17
|
type: "pulse_severity",
|
|
21
18
|
description: selectedLevel,
|
|
22
19
|
});
|
|
@@ -368,8 +368,9 @@ class PlaywrightPulseReporter {
|
|
|
368
368
|
const lastAttempt = attempts[attempts.length - 1];
|
|
369
369
|
firstAttempt.final_status = lastAttempt.status;
|
|
370
370
|
// If the last attempt was flaky, ensure outcome is set on the main result
|
|
371
|
-
if (lastAttempt.outcome === 'flaky') {
|
|
371
|
+
if (lastAttempt.outcome === 'flaky' || lastAttempt.status === 'flaky') {
|
|
372
372
|
firstAttempt.outcome = 'flaky';
|
|
373
|
+
firstAttempt.status = 'flaky';
|
|
373
374
|
}
|
|
374
375
|
}
|
|
375
376
|
else {
|
|
@@ -438,6 +439,7 @@ class PlaywrightPulseReporter {
|
|
|
438
439
|
finalRunData.passed = finalResultsList.filter((r) => r.status === "passed").length;
|
|
439
440
|
finalRunData.failed = finalResultsList.filter((r) => r.status === "failed").length;
|
|
440
441
|
finalRunData.skipped = finalResultsList.filter((r) => r.status === "skipped").length;
|
|
442
|
+
finalRunData.flaky = finalResultsList.filter((r) => r.status === "flaky").length;
|
|
441
443
|
finalRunData.totalTests = finalResultsList.length;
|
|
442
444
|
const reviveDates = (key, value) => {
|
|
443
445
|
const isoDateRegex = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(\.\d+)?Z$/;
|
|
@@ -498,6 +500,7 @@ class PlaywrightPulseReporter {
|
|
|
498
500
|
passed: finalResults.filter((r) => r.status === "passed").length,
|
|
499
501
|
failed: finalResults.filter((r) => r.status === "failed").length,
|
|
500
502
|
skipped: finalResults.filter((r) => r.status === "skipped").length,
|
|
503
|
+
flaky: finalResults.filter((r) => r.status === "flaky").length,
|
|
501
504
|
duration,
|
|
502
505
|
environment: environmentDetails,
|
|
503
506
|
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"fileNames":["../node_modules/typescript/lib/lib.es5.d.ts","../node_modules/typescript/lib/lib.es2015.d.ts","../node_modules/typescript/lib/lib.es2016.d.ts","../node_modules/typescript/lib/lib.es2017.d.ts","../node_modules/typescript/lib/lib.es2018.d.ts","../node_modules/typescript/lib/lib.es2019.d.ts","../node_modules/typescript/lib/lib.es2020.d.ts","../node_modules/typescript/lib/lib.es2021.d.ts","../node_modules/typescript/lib/lib.es2022.d.ts","../node_modules/typescript/lib/lib.es2023.d.ts","../node_modules/typescript/lib/lib.es2024.d.ts","../node_modules/typescript/lib/lib.esnext.d.ts","../node_modules/typescript/lib/lib.dom.d.ts","../node_modules/typescript/lib/lib.dom.iterable.d.ts","../node_modules/typescript/lib/lib.es2015.core.d.ts","../node_modules/typescript/lib/lib.es2015.collection.d.ts","../node_modules/typescript/lib/lib.es2015.generator.d.ts","../node_modules/typescript/lib/lib.es2015.iterable.d.ts","../node_modules/typescript/lib/lib.es2015.promise.d.ts","../node_modules/typescript/lib/lib.es2015.proxy.d.ts","../node_modules/typescript/lib/lib.es2015.reflect.d.ts","../node_modules/typescript/lib/lib.es2015.symbol.d.ts","../node_modules/typescript/lib/lib.es2015.symbol.wellknown.d.ts","../node_modules/typescript/lib/lib.es2016.array.include.d.ts","../node_modules/typescript/lib/lib.es2016.intl.d.ts","../node_modules/typescript/lib/lib.es2017.arraybuffer.d.ts","../node_modules/typescript/lib/lib.es2017.date.d.ts","../node_modules/typescript/lib/lib.es2017.object.d.ts","../node_modules/typescript/lib/lib.es2017.sharedmemory.d.ts","../node_modules/typescript/lib/lib.es2017.string.d.ts","../node_modules/typescript/lib/lib.es2017.intl.d.ts","../node_modules/typescript/lib/lib.es2017.typedarrays.d.ts","../node_modules/typescript/lib/lib.es2018.asyncgenerator.d.ts","../node_modules/typescript/lib/lib.es2018.asynciterable.d.ts","../node_modules/typescript/lib/lib.es2018.intl.d.ts","../node_modules/typescript/lib/lib.es2018.promise.d.ts","../node_modules/typescript/lib/lib.es2018.regexp.d.ts","../node_modules/typescript/lib/lib.es2019.array.d.ts","../node_modules/typescript/lib/lib.es2019.object.d.ts","../node_modules/typescript/lib/lib.es2019.string.d.ts","../node_modules/typescript/lib/lib.es2019.symbol.d.ts","../node_modules/typescript/lib/lib.es2019.intl.d.ts","../node_modules/typescript/lib/lib.es2020.bigint.d.ts","../node_modules/typescript/lib/lib.es2020.date.d.ts","../node_modules/typescript/lib/lib.es2020.promise.d.ts","../node_modules/typescript/lib/lib.es2020.sharedmemory.d.ts","../node_modules/typescript/lib/lib.es2020.string.d.ts","../node_modules/typescript/lib/lib.es2020.symbol.wellknown.d.ts","../node_modules/typescript/lib/lib.es2020.intl.d.ts","../node_modules/typescript/lib/lib.es2020.number.d.ts","../node_modules/typescript/lib/lib.es2021.promise.d.ts","../node_modules/typescript/lib/lib.es2021.string.d.ts","../node_modules/typescript/lib/lib.es2021.weakref.d.ts","../node_modules/typescript/lib/lib.es2021.intl.d.ts","../node_modules/typescript/lib/lib.es2022.array.d.ts","../node_modules/typescript/lib/lib.es2022.error.d.ts","../node_modules/typescript/lib/lib.es2022.intl.d.ts","../node_modules/typescript/lib/lib.es2022.object.d.ts","../node_modules/typescript/lib/lib.es2022.string.d.ts","../node_modules/typescript/lib/lib.es2022.regexp.d.ts","../node_modules/typescript/lib/lib.es2023.array.d.ts","../node_modules/typescript/lib/lib.es2023.collection.d.ts","../node_modules/typescript/lib/lib.es2023.intl.d.ts","../node_modules/typescript/lib/lib.es2024.arraybuffer.d.ts","../node_modules/typescript/lib/lib.es2024.collection.d.ts","../node_modules/typescript/lib/lib.es2024.object.d.ts","../node_modules/typescript/lib/lib.es2024.promise.d.ts","../node_modules/typescript/lib/lib.es2024.regexp.d.ts","../node_modules/typescript/lib/lib.es2024.sharedmemory.d.ts","../node_modules/typescript/lib/lib.es2024.string.d.ts","../node_modules/typescript/lib/lib.esnext.array.d.ts","../node_modules/typescript/lib/lib.esnext.collection.d.ts","../node_modules/typescript/lib/lib.esnext.intl.d.ts","../node_modules/typescript/lib/lib.esnext.disposable.d.ts","../node_modules/typescript/lib/lib.esnext.decorators.d.ts","../node_modules/typescript/lib/lib.esnext.iterator.d.ts","../node_modules/typescript/lib/lib.decorators.d.ts","../node_modules/typescript/lib/lib.decorators.legacy.d.ts","../node_modules/playwright-core/types/protocol.d.ts","../node_modules/playwright-core/types/structs.d.ts","../node_modules/playwright-core/types/types.d.ts","../node_modules/playwright/types/test.d.ts","../node_modules/playwright/test.d.ts","../node_modules/@playwright/test/index.d.ts","../src/pulse.ts","../node_modules/lucide-react/dist/lucide-react.d.ts","../src/types/index.ts","../src/lib/report-types.ts","../src/lib/data-reader.ts","../src/lib/data.ts","../node_modules/clsx/clsx.d.ts","../src/lib/utils.ts","../node_modules/playwright/types/testreporter.d.ts","../node_modules/@playwright/test/reporter.d.ts","../src/reporter/attachment-utils.ts","../node_modules/@types/ua-parser-js/index.d.ts","../src/reporter/playwright-pulse-reporter.ts","../src/reporter/index.ts","../node_modules/@types/estree/index.d.ts","../node_modules/@types/json-schema/index.d.ts","../node_modules/@types/node/compatibility/disposable.d.ts","../node_modules/@types/node/compatibility/indexable.d.ts","../node_modules/@types/node/compatibility/iterators.d.ts","../node_modules/@types/node/compatibility/index.d.ts","../node_modules/@types/node/globals.typedarray.d.ts","../node_modules/@types/node/buffer.buffer.d.ts","../node_modules/undici-types/header.d.ts","../node_modules/undici-types/readable.d.ts","../node_modules/undici-types/file.d.ts","../node_modules/undici-types/fetch.d.ts","../node_modules/undici-types/formdata.d.ts","../node_modules/undici-types/connector.d.ts","../node_modules/undici-types/client.d.ts","../node_modules/undici-types/errors.d.ts","../node_modules/undici-types/dispatcher.d.ts","../node_modules/undici-types/global-dispatcher.d.ts","../node_modules/undici-types/global-origin.d.ts","../node_modules/undici-types/pool-stats.d.ts","../node_modules/undici-types/pool.d.ts","../node_modules/undici-types/handlers.d.ts","../node_modules/undici-types/balanced-pool.d.ts","../node_modules/undici-types/agent.d.ts","../node_modules/undici-types/mock-interceptor.d.ts","../node_modules/undici-types/mock-agent.d.ts","../node_modules/undici-types/mock-client.d.ts","../node_modules/undici-types/mock-pool.d.ts","../node_modules/undici-types/mock-errors.d.ts","../node_modules/undici-types/proxy-agent.d.ts","../node_modules/undici-types/env-http-proxy-agent.d.ts","../node_modules/undici-types/retry-handler.d.ts","../node_modules/undici-types/retry-agent.d.ts","../node_modules/undici-types/api.d.ts","../node_modules/undici-types/interceptors.d.ts","../node_modules/undici-types/util.d.ts","../node_modules/undici-types/cookies.d.ts","../node_modules/undici-types/patch.d.ts","../node_modules/undici-types/websocket.d.ts","../node_modules/undici-types/eventsource.d.ts","../node_modules/undici-types/filereader.d.ts","../node_modules/undici-types/diagnostics-channel.d.ts","../node_modules/undici-types/content-type.d.ts","../node_modules/undici-types/cache.d.ts","../node_modules/undici-types/index.d.ts","../node_modules/@types/node/globals.d.ts","../node_modules/@types/node/assert.d.ts","../node_modules/@types/node/assert/strict.d.ts","../node_modules/@types/node/async_hooks.d.ts","../node_modules/@types/node/buffer.d.ts","../node_modules/@types/node/child_process.d.ts","../node_modules/@types/node/cluster.d.ts","../node_modules/@types/node/console.d.ts","../node_modules/@types/node/constants.d.ts","../node_modules/@types/node/crypto.d.ts","../node_modules/@types/node/dgram.d.ts","../node_modules/@types/node/diagnostics_channel.d.ts","../node_modules/@types/node/dns.d.ts","../node_modules/@types/node/dns/promises.d.ts","../node_modules/@types/node/domain.d.ts","../node_modules/@types/node/dom-events.d.ts","../node_modules/@types/node/events.d.ts","../node_modules/@types/node/fs.d.ts","../node_modules/@types/node/fs/promises.d.ts","../node_modules/@types/node/http.d.ts","../node_modules/@types/node/http2.d.ts","../node_modules/@types/node/https.d.ts","../node_modules/@types/node/inspector.d.ts","../node_modules/@types/node/module.d.ts","../node_modules/@types/node/net.d.ts","../node_modules/@types/node/os.d.ts","../node_modules/@types/node/path.d.ts","../node_modules/@types/node/perf_hooks.d.ts","../node_modules/@types/node/process.d.ts","../node_modules/@types/node/punycode.d.ts","../node_modules/@types/node/querystring.d.ts","../node_modules/@types/node/readline.d.ts","../node_modules/@types/node/readline/promises.d.ts","../node_modules/@types/node/repl.d.ts","../node_modules/@types/node/sea.d.ts","../node_modules/@types/node/stream.d.ts","../node_modules/@types/node/stream/promises.d.ts","../node_modules/@types/node/stream/consumers.d.ts","../node_modules/@types/node/stream/web.d.ts","../node_modules/@types/node/string_decoder.d.ts","../node_modules/@types/node/test.d.ts","../node_modules/@types/node/timers.d.ts","../node_modules/@types/node/timers/promises.d.ts","../node_modules/@types/node/tls.d.ts","../node_modules/@types/node/trace_events.d.ts","../node_modules/@types/node/tty.d.ts","../node_modules/@types/node/url.d.ts","../node_modules/@types/node/util.d.ts","../node_modules/@types/node/v8.d.ts","../node_modules/@types/node/vm.d.ts","../node_modules/@types/node/wasi.d.ts","../node_modules/@types/node/worker_threads.d.ts","../node_modules/@types/node/zlib.d.ts","../node_modules/@types/node/index.d.ts"],"fileIdsList":[[83,106,148],[93,106,148],[106,148],[106,145,148],[106,147,148],[148],[106,148,153,182],[106,148,149,154,160,161,168,179,190],[106,148,149,150,160,168],[101,102,103,106,148],[106,148,151,191],[106,148,152,153,161,169],[106,148,153,179,187],[106,148,154,156,160,168],[106,147,148,155],[106,148,156,157],[106,148,160],[106,148,158,160],[106,147,148,160],[106,148,160,161,162,179,190],[106,148,160,161,162,175,179,182],[106,143,148,195],[106,148,156,160,163,168,179,190],[106,148,160,161,163,164,168,179,187,190],[106,148,163,165,179,187,190],[104,105,106,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196],[106,148,160,166],[106,148,167,190,195],[106,148,156,160,168,179],[106,148,169],[106,148,170],[106,147,148,171],[106,145,146,147,148,149,150,151,152,153,154,155,156,157,158,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196],[106,148,173],[106,148,174],[106,148,160,175,176],[106,148,175,177,191,193],[106,148,160,179,180,181,182],[106,148,179,181],[106,148,179,180],[106,148,182],[106,148,183],[106,145,148,179],[106,148,160,185,186],[106,148,185,186],[106,148,153,168,179,187],[106,148,188],[106,148,168,189],[106,148,163,174,190],[106,148,153,191],[106,148,179,192],[106,148,167,193],[106,148,194],[106,148,153,160,162,171,179,190,193,195],[106,148,179,196],[81,106,148],[79,80,106,148,149,161,179],[82,106,148],[106,115,119,148,190],[106,115,148,179,190],[106,110,148],[106,112,115,148,187,190],[106,148,168,187],[106,148,197],[106,110,148,197],[106,112,115,148,168,190],[106,107,108,111,114,148,160,179,190],[106,115,122,148],[106,107,113,148],[106,115,136,137,148],[106,111,115,148,182,190,197],[106,136,148,197],[106,109,110,148,197],[106,115,148],[106,109,110,111,112,113,114,115,116,117,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,137,138,139,140,141,142,148],[106,115,130,148],[106,115,122,123,148],[106,113,115,123,124,148],[106,114,148],[106,107,110,115,148],[106,115,119,123,124,148],[106,119,148],[106,113,115,118,148,190],[106,107,112,115,122,148],[106,148,179],[106,110,115,136,148,195,197],[88,106,148,162,170],[87,89,106,148],[87,106,148],[91,106,148],[84,106,148],[87,94,106,148,161,170],[85,87,88,97,106,148],[87,88,94,96,106,148,153,162,169,170],[86,106,148]],"fileInfos":[{"version":"e41c290ef7dd7dab3493e6cbe5909e0148edf4a8dad0271be08edec368a0f7b9","affectsGlobalScope":true,"impliedFormat":1},{"version":"45b7ab580deca34ae9729e97c13cfd999df04416a79116c3bfb483804f85ded4","impliedFormat":1},{"version":"3facaf05f0c5fc569c5649dd359892c98a85557e3e0c847964caeb67076f4d75","impliedFormat":1},{"version":"e44bb8bbac7f10ecc786703fe0a6a4b952189f908707980ba8f3c8975a760962","impliedFormat":1},{"version":"5e1c4c362065a6b95ff952c0eab010f04dcd2c3494e813b493ecfd4fcb9fc0d8","impliedFormat":1},{"version":"68d73b4a11549f9c0b7d352d10e91e5dca8faa3322bfb77b661839c42b1ddec7","impliedFormat":1},{"version":"5efce4fc3c29ea84e8928f97adec086e3dc876365e0982cc8479a07954a3efd4","impliedFormat":1},{"version":"feecb1be483ed332fad555aff858affd90a48ab19ba7272ee084704eb7167569","impliedFormat":1},{"version":"ee7bad0c15b58988daa84371e0b89d313b762ab83cb5b31b8a2d1162e8eb41c2","impliedFormat":1},{"version":"27bdc30a0e32783366a5abeda841bc22757c1797de8681bbe81fbc735eeb1c10","impliedFormat":1},{"version":"8fd575e12870e9944c7e1d62e1f5a73fcf23dd8d3a321f2a2c74c20d022283fe","impliedFormat":1},{"version":"e12a46ce14b817d4c9e6b2b478956452330bf00c9801b79de46f7a1815b5bd40","impliedFormat":1},{"version":"4fd3f3422b2d2a3dfd5cdd0f387b3a8ec45f006c6ea896a4cb41264c2100bb2c","affectsGlobalScope":true,"impliedFormat":1},{"version":"69e65d976bf166ce4a9e6f6c18f94d2424bf116e90837ace179610dbccad9b42","affectsGlobalScope":true,"impliedFormat":1},{"version":"c57796738e7f83dbc4b8e65132f11a377649c00dd3eee333f672b8f0a6bea671","affectsGlobalScope":true,"impliedFormat":1},{"version":"dc2df20b1bcdc8c2d34af4926e2c3ab15ffe1160a63e58b7e09833f616efff44","affectsGlobalScope":true,"impliedFormat":1},{"version":"515d0b7b9bea2e31ea4ec968e9edd2c39d3eebf4a2d5cbd04e88639819ae3b71","affectsGlobalScope":true,"impliedFormat":1},{"version":"62bb211266ee48b2d0edf0d8d1b191f0c24fc379a82bd4c1692a082c540bc6b1","affectsGlobalScope":true,"impliedFormat":1},{"version":"0dc1e7ceda9b8b9b455c3a2d67b0412feab00bd2f66656cd8850e8831b08b537","affectsGlobalScope":true,"impliedFormat":1},{"version":"ce691fb9e5c64efb9547083e4a34091bcbe5bdb41027e310ebba8f7d96a98671","affectsGlobalScope":true,"impliedFormat":1},{"version":"8d697a2a929a5fcb38b7a65594020fcef05ec1630804a33748829c5ff53640d0","affectsGlobalScope":true,"impliedFormat":1},{"version":"4ff2a353abf8a80ee399af572debb8faab2d33ad38c4b4474cff7f26e7653b8d","affectsGlobalScope":true,"impliedFormat":1},{"version":"936e80ad36a2ee83fc3caf008e7c4c5afe45b3cf3d5c24408f039c1d47bdc1df","affectsGlobalScope":true,"impliedFormat":1},{"version":"d15bea3d62cbbdb9797079416b8ac375ae99162a7fba5de2c6c505446486ac0a","affectsGlobalScope":true,"impliedFormat":1},{"version":"68d18b664c9d32a7336a70235958b8997ebc1c3b8505f4f1ae2b7e7753b87618","affectsGlobalScope":true,"impliedFormat":1},{"version":"eb3d66c8327153d8fa7dd03f9c58d351107fe824c79e9b56b462935176cdf12a","affectsGlobalScope":true,"impliedFormat":1},{"version":"38f0219c9e23c915ef9790ab1d680440d95419ad264816fa15009a8851e79119","affectsGlobalScope":true,"impliedFormat":1},{"version":"69ab18c3b76cd9b1be3d188eaf8bba06112ebbe2f47f6c322b5105a6fbc45a2e","affectsGlobalScope":true,"impliedFormat":1},{"version":"fef8cfad2e2dc5f5b3d97a6f4f2e92848eb1b88e897bb7318cef0e2820bceaab","affectsGlobalScope":true,"impliedFormat":1},{"version":"2f11ff796926e0832f9ae148008138ad583bd181899ab7dd768a2666700b1893","affectsGlobalScope":true,"impliedFormat":1},{"version":"4de680d5bb41c17f7f68e0419412ca23c98d5749dcaaea1896172f06435891fc","affectsGlobalScope":true,"impliedFormat":1},{"version":"954296b30da6d508a104a3a0b5d96b76495c709785c1d11610908e63481ee667","affectsGlobalScope":true,"impliedFormat":1},{"version":"ac9538681b19688c8eae65811b329d3744af679e0bdfa5d842d0e32524c73e1c","affectsGlobalScope":true,"impliedFormat":1},{"version":"0a969edff4bd52585473d24995c5ef223f6652d6ef46193309b3921d65dd4376","affectsGlobalScope":true,"impliedFormat":1},{"version":"9e9fbd7030c440b33d021da145d3232984c8bb7916f277e8ffd3dc2e3eae2bdb","affectsGlobalScope":true,"impliedFormat":1},{"version":"811ec78f7fefcabbda4bfa93b3eb67d9ae166ef95f9bff989d964061cbf81a0c","affectsGlobalScope":true,"impliedFormat":1},{"version":"717937616a17072082152a2ef351cb51f98802fb4b2fdabd32399843875974ca","affectsGlobalScope":true,"impliedFormat":1},{"version":"d7e7d9b7b50e5f22c915b525acc5a49a7a6584cf8f62d0569e557c5cfc4b2ac2","affectsGlobalScope":true,"impliedFormat":1},{"version":"71c37f4c9543f31dfced6c7840e068c5a5aacb7b89111a4364b1d5276b852557","affectsGlobalScope":true,"impliedFormat":1},{"version":"576711e016cf4f1804676043e6a0a5414252560eb57de9faceee34d79798c850","affectsGlobalScope":true,"impliedFormat":1},{"version":"89c1b1281ba7b8a96efc676b11b264de7a8374c5ea1e6617f11880a13fc56dc6","affectsGlobalScope":true,"impliedFormat":1},{"version":"74f7fa2d027d5b33eb0471c8e82a6c87216223181ec31247c357a3e8e2fddc5b","affectsGlobalScope":true,"impliedFormat":1},{"version":"f1e2a172204962276504466a6393426d2ca9c54894b1ad0a6c9dad867a65f876","affectsGlobalScope":true,"impliedFormat":1},{"version":"063600664504610fe3e99b717a1223f8b1900087fab0b4cad1496a114744f8df","affectsGlobalScope":true,"impliedFormat":1},{"version":"934019d7e3c81950f9a8426d093458b65d5aff2c7c1511233c0fd5b941e608ab","affectsGlobalScope":true,"impliedFormat":1},{"version":"52ada8e0b6e0482b728070b7639ee42e83a9b1c22d205992756fe020fd9f4a47","affectsGlobalScope":true,"impliedFormat":1},{"version":"3bdefe1bfd4d6dee0e26f928f93ccc128f1b64d5d501ff4a8cf3c6371200e5e6","affectsGlobalScope":true,"impliedFormat":1},{"version":"59fb2c069260b4ba00b5643b907ef5d5341b167e7d1dbf58dfd895658bda2867","affectsGlobalScope":true,"impliedFormat":1},{"version":"639e512c0dfc3fad96a84caad71b8834d66329a1f28dc95e3946c9b58176c73a","affectsGlobalScope":true,"impliedFormat":1},{"version":"368af93f74c9c932edd84c58883e736c9e3d53cec1fe24c0b0ff451f529ceab1","affectsGlobalScope":true,"impliedFormat":1},{"version":"af3dd424cf267428f30ccfc376f47a2c0114546b55c44d8c0f1d57d841e28d74","affectsGlobalScope":true,"impliedFormat":1},{"version":"995c005ab91a498455ea8dfb63aa9f83fa2ea793c3d8aa344be4a1678d06d399","affectsGlobalScope":true,"impliedFormat":1},{"version":"959d36cddf5e7d572a65045b876f2956c973a586da58e5d26cde519184fd9b8a","affectsGlobalScope":true,"impliedFormat":1},{"version":"965f36eae237dd74e6cca203a43e9ca801ce38824ead814728a2807b1910117d","affectsGlobalScope":true,"impliedFormat":1},{"version":"3925a6c820dcb1a06506c90b1577db1fdbf7705d65b62b99dce4be75c637e26b","affectsGlobalScope":true,"impliedFormat":1},{"version":"0a3d63ef2b853447ec4f749d3f368ce642264246e02911fcb1590d8c161b8005","affectsGlobalScope":true,"impliedFormat":1},{"version":"b5ce7a470bc3628408429040c4e3a53a27755022a32fd05e2cb694e7015386c7","affectsGlobalScope":true,"impliedFormat":1},{"version":"8444af78980e3b20b49324f4a16ba35024fef3ee069a0eb67616ea6ca821c47a","affectsGlobalScope":true,"impliedFormat":1},{"version":"3287d9d085fbd618c3971944b65b4be57859f5415f495b33a6adc994edd2f004","affectsGlobalScope":true,"impliedFormat":1},{"version":"b4b67b1a91182421f5df999988c690f14d813b9850b40acd06ed44691f6727ad","affectsGlobalScope":true,"impliedFormat":1},{"version":"bab26767638ab3557de12c900f0b91f710c7dc40ee9793d5a27d32c04f0bf646","affectsGlobalScope":true,"impliedFormat":1},{"version":"436aaf437562f276ec2ddbee2f2cdedac7664c1e4c1d2c36839ddd582eeb3d0a","affectsGlobalScope":true,"impliedFormat":1},{"version":"8e3c06ea092138bf9fa5e874a1fdbc9d54805d074bee1de31b99a11e2fec239d","affectsGlobalScope":true,"impliedFormat":1},{"version":"87dc0f382502f5bbce5129bdc0aea21e19a3abbc19259e0b43ae038a9fc4e326","affectsGlobalScope":true,"impliedFormat":1},{"version":"b1cb28af0c891c8c96b2d6b7be76bd394fddcfdb4709a20ba05a7c1605eea0f9","affectsGlobalScope":true,"impliedFormat":1},{"version":"2fef54945a13095fdb9b84f705f2b5994597640c46afeb2ce78352fab4cb3279","affectsGlobalScope":true,"impliedFormat":1},{"version":"ac77cb3e8c6d3565793eb90a8373ee8033146315a3dbead3bde8db5eaf5e5ec6","affectsGlobalScope":true,"impliedFormat":1},{"version":"56e4ed5aab5f5920980066a9409bfaf53e6d21d3f8d020c17e4de584d29600ad","affectsGlobalScope":true,"impliedFormat":1},{"version":"4ece9f17b3866cc077099c73f4983bddbcb1dc7ddb943227f1ec070f529dedd1","affectsGlobalScope":true,"impliedFormat":1},{"version":"0a6282c8827e4b9a95f4bf4f5c205673ada31b982f50572d27103df8ceb8013c","affectsGlobalScope":true,"impliedFormat":1},{"version":"1c9319a09485199c1f7b0498f2988d6d2249793ef67edda49d1e584746be9032","affectsGlobalScope":true,"impliedFormat":1},{"version":"e3a2a0cee0f03ffdde24d89660eba2685bfbdeae955a6c67e8c4c9fd28928eeb","affectsGlobalScope":true,"impliedFormat":1},{"version":"811c71eee4aa0ac5f7adf713323a5c41b0cf6c4e17367a34fbce379e12bbf0a4","affectsGlobalScope":true,"impliedFormat":1},{"version":"51ad4c928303041605b4d7ae32e0c1ee387d43a24cd6f1ebf4a2699e1076d4fa","affectsGlobalScope":true,"impliedFormat":1},{"version":"d4b1d2c51d058fc21ec2629fff7a76249dec2e36e12960ea056e3ef89174080f","affectsGlobalScope":true,"impliedFormat":1},{"version":"61d6a2092f48af66dbfb220e31eea8b10bc02b6932d6e529005fd2d7b3281290","affectsGlobalScope":true,"impliedFormat":1},{"version":"8e7f8264d0fb4c5339605a15daadb037bf238c10b654bb3eee14208f860a32ea","affectsGlobalScope":true,"impliedFormat":1},{"version":"782dec38049b92d4e85c1585fbea5474a219c6984a35b004963b00beb1aab538","affectsGlobalScope":true,"impliedFormat":1},{"version":"3f6ef9c13ca4e92bc06426a01f2c3198448e949f64f62eb02e2db23146a8d06c","impliedFormat":1},{"version":"32727845ab5bd8a9ef3e4844c567c09f6d418fcf0f90d381c00652a6f23e7f6e","impliedFormat":1},{"version":"254bdfc7c096df05586db7e69fd2c6d78c766d13713fb5a44b74d49fd45e8881","impliedFormat":1},{"version":"4a405da2b4fe59c59b09a9af656f7b40c18293b1e17118a93580585c01c7dc7a","affectsGlobalScope":true,"impliedFormat":1},{"version":"3f00324f263189b385c3a9383b1f4dae6237697bcf0801f96aa35c340512d79c","impliedFormat":1},{"version":"ec8997c2e5cea26befc76e7bf990750e96babb16977673a9ff3b5c0575d01e48","impliedFormat":1},"88a8818ff468a6bfbd1e798cf10688016e1035b81b841162722a956be0e3d417",{"version":"6717dad91e44ad22d68f1fc0db74e5eb5398c2c06a2943bf06d3a168e8b1ba45","impliedFormat":99},"e671563fbeb355f1e10a8296d3ff5ab2c1bf362801dbab2548e15e826adc3a71","331a971aff7a6da8693ab1ab38961996fecd854f6a639d430c81f8207dc92e96","b45a158fb0a2eae42e6c5d88d674ec5c72c610cc4840c8e9bb7178445dc4d4e3","83de864087649487b699d01917d4245750b114798d180426480e8019bc8497f5",{"version":"ef73bcfef9907c8b772a30e5a64a6bd86a5669cba3d210fcdcc6b625e3312459","impliedFormat":1},"91087920d3b2235d60b478f3d317c8737b64ce7fadba4dc3f88c9a0fb46080ba",{"version":"c76f94b31ae5c283f441916a9feb84257dca7041625eb7f3c9459fac5ac351cc","impliedFormat":1},{"version":"04392f8e190f9e51301f73d17bbb34babd54858c1efc932d2193962f66dabae2","impliedFormat":1},"c769507a3aab1d5491d133bcece45dd63aed97868e14673f73c11ba15ec90168",{"version":"98cbca6c3c5b2f8d1469dcee88c13304b6cb149fb057ec3b8a85f2e39ff1fc84","impliedFormat":1},"29a00357fe4b27487fa0631dfe3d4908249ed032cc4947b99f4098a7a30ad367","d502b970e98c03636f85ec36014de7c97aa31af702956549e1edc02b12067b03",{"version":"e2b48abff5a8adc6bb1cd13a702b9ef05e6045a98e7cfa95a8779b53b6d0e69d","impliedFormat":1},{"version":"f3d8c757e148ad968f0d98697987db363070abada5f503da3c06aefd9d4248c1","impliedFormat":1},{"version":"70521b6ab0dcba37539e5303104f29b721bfb2940b2776da4cc818c07e1fefc1","affectsGlobalScope":true,"impliedFormat":1},{"version":"ab41ef1f2cdafb8df48be20cd969d875602483859dc194e9c97c8a576892c052","affectsGlobalScope":true,"impliedFormat":1},{"version":"d153a11543fd884b596587ccd97aebbeed950b26933ee000f94009f1ab142848","affectsGlobalScope":true,"impliedFormat":1},{"version":"21d819c173c0cf7cc3ce57c3276e77fd9a8a01d35a06ad87158781515c9a438a","impliedFormat":1},{"version":"a79e62f1e20467e11a904399b8b18b18c0c6eea6b50c1168bf215356d5bebfaf","affectsGlobalScope":true,"impliedFormat":1},{"version":"0fd06258805d26c72f5997e07a23155d322d5f05387adb3744a791fe6a0b042d","affectsGlobalScope":true,"impliedFormat":1},{"version":"5929864ce17fba74232584d90cb721a89b7ad277220627cc97054ba15a98ea8f","impliedFormat":1},{"version":"24bd580b5743dc56402c440dc7f9a4f5d592ad7a419f25414d37a7bfe11e342b","impliedFormat":1},{"version":"25c8056edf4314820382a5fdb4bb7816999acdcb929c8f75e3f39473b87e85bc","impliedFormat":1},{"version":"c464d66b20788266e5353b48dc4aa6bc0dc4a707276df1e7152ab0c9ae21fad8","impliedFormat":1},{"version":"78d0d27c130d35c60b5e5566c9f1e5be77caf39804636bc1a40133919a949f21","impliedFormat":1},{"version":"c6fd2c5a395f2432786c9cb8deb870b9b0e8ff7e22c029954fabdd692bff6195","impliedFormat":1},{"version":"1d6e127068ea8e104a912e42fc0a110e2aa5a66a356a917a163e8cf9a65e4a75","impliedFormat":1},{"version":"5ded6427296cdf3b9542de4471d2aa8d3983671d4cac0f4bf9c637208d1ced43","impliedFormat":1},{"version":"6bdc71028db658243775263e93a7db2fd2abfce3ca569c3cca5aee6ed5eb186d","impliedFormat":1},{"version":"cadc8aced301244057c4e7e73fbcae534b0f5b12a37b150d80e5a45aa4bebcbd","impliedFormat":1},{"version":"385aab901643aa54e1c36f5ef3107913b10d1b5bb8cbcd933d4263b80a0d7f20","impliedFormat":1},{"version":"9670d44354bab9d9982eca21945686b5c24a3f893db73c0dae0fd74217a4c219","impliedFormat":1},{"version":"0b8a9268adaf4da35e7fa830c8981cfa22adbbe5b3f6f5ab91f6658899e657a7","impliedFormat":1},{"version":"11396ed8a44c02ab9798b7dca436009f866e8dae3c9c25e8c1fbc396880bf1bb","impliedFormat":1},{"version":"ba7bc87d01492633cb5a0e5da8a4a42a1c86270e7b3d2dea5d156828a84e4882","impliedFormat":1},{"version":"4893a895ea92c85345017a04ed427cbd6a1710453338df26881a6019432febdd","impliedFormat":1},{"version":"c21dc52e277bcfc75fac0436ccb75c204f9e1b3fa5e12729670910639f27343e","impliedFormat":1},{"version":"13f6f39e12b1518c6650bbb220c8985999020fe0f21d818e28f512b7771d00f9","impliedFormat":1},{"version":"9b5369969f6e7175740bf51223112ff209f94ba43ecd3bb09eefff9fd675624a","impliedFormat":1},{"version":"4fe9e626e7164748e8769bbf74b538e09607f07ed17c2f20af8d680ee49fc1da","impliedFormat":1},{"version":"24515859bc0b836719105bb6cc3d68255042a9f02a6022b3187948b204946bd2","impliedFormat":1},{"version":"ea0148f897b45a76544ae179784c95af1bd6721b8610af9ffa467a518a086a43","impliedFormat":1},{"version":"24c6a117721e606c9984335f71711877293a9651e44f59f3d21c1ea0856f9cc9","impliedFormat":1},{"version":"dd3273ead9fbde62a72949c97dbec2247ea08e0c6952e701a483d74ef92d6a17","impliedFormat":1},{"version":"405822be75ad3e4d162e07439bac80c6bcc6dbae1929e179cf467ec0b9ee4e2e","impliedFormat":1},{"version":"0db18c6e78ea846316c012478888f33c11ffadab9efd1cc8bcc12daded7a60b6","impliedFormat":1},{"version":"4d2b0eb911816f66abe4970898f97a2cfc902bcd743cbfa5017fad79f7ef90d8","impliedFormat":1},{"version":"bd0532fd6556073727d28da0edfd1736417a3f9f394877b6d5ef6ad88fba1d1a","impliedFormat":1},{"version":"89167d696a849fce5ca508032aabfe901c0868f833a8625d5a9c6e861ef935d2","impliedFormat":1},{"version":"e53a3c2a9f624d90f24bf4588aacd223e7bec1b9d0d479b68d2f4a9e6011147f","impliedFormat":1},{"version":"24b8685c62562f5d98615c5a0c1d05f297cf5065f15246edfe99e81ec4c0e011","impliedFormat":1},{"version":"93507c745e8f29090efb99399c3f77bec07db17acd75634249dc92f961573387","impliedFormat":1},{"version":"339dc5265ee5ed92e536a93a04c4ebbc2128f45eeec6ed29f379e0085283542c","impliedFormat":1},{"version":"4732aec92b20fb28c5fe9ad99521fb59974289ed1e45aecb282616202184064f","impliedFormat":1},{"version":"2e85db9e6fd73cfa3d7f28e0ab6b55417ea18931423bd47b409a96e4a169e8e6","impliedFormat":1},{"version":"c46e079fe54c76f95c67fb89081b3e399da2c7d109e7dca8e4b58d83e332e605","impliedFormat":1},{"version":"bf67d53d168abc1298888693338cb82854bdb2e69ef83f8a0092093c2d562107","impliedFormat":1},{"version":"08faa97886e71757779428dd4c69a545c32c85fd629d1116d42710b32c6378bc","affectsGlobalScope":true,"impliedFormat":1},{"version":"a72ffc815104fb5c075106ebca459b2d55d07862a773768fce89efc621b3964b","impliedFormat":1},{"version":"7394959e5a741b185456e1ef5d64599c36c60a323207450991e7a42e08911419","impliedFormat":1},{"version":"3d77c73be94570813f8cadd1f05ebc3dc5e2e4fdefe4d340ca20cd018724ee36","impliedFormat":1},{"version":"d674383111e06b6741c4ad2db962131b5b0fa4d0294b998566c635e86195a453","affectsGlobalScope":true,"impliedFormat":1},{"version":"f3e58c4c18a031cbb17abec7a4ad0bd5ae9fc70c1f4ba1e7fb921ad87c504aca","impliedFormat":1},{"version":"a3e8bafb2af8e850c644f4be7f5156cf7d23b7bfdc3b786bd4d10ed40329649c","impliedFormat":1},{"version":"35ec8b6760fd7138bbf5809b84551e31028fb2ba7b6dc91d95d098bf212ca8b4","affectsGlobalScope":true,"impliedFormat":1},{"version":"a40826e8476694e90da94aa008283a7de50d1dafd37beada623863f1901cb7fb","impliedFormat":1},{"version":"f77d9188e41291acf14f476e931972460a303e1952538f9546e7b370cb8d0d20","affectsGlobalScope":true,"impliedFormat":1},{"version":"8d04e3640dd9eb67f7f1e5bd3d0bf96c784666f7aefc8ac1537af6f2d38d4c29","impliedFormat":1},{"version":"3c884d9d9ec454bdf0d5a0b8465bf8297d2caa4d853851d92cc417ac6f30b969","impliedFormat":1},{"version":"5a369483ac4cfbdf0331c248deeb36140e6907db5e1daed241546b4a2055f82c","impliedFormat":1},{"version":"e8f5b5cc36615c17d330eaf8eebbc0d6bdd942c25991f96ef122f246f4ff722f","impliedFormat":1},{"version":"f0bd7e6d931657b59605c44112eaf8b980ba7f957a5051ed21cb93d978cf2f45","impliedFormat":1},{"version":"ee1ee365d88c4c6c0c0a5a5701d66ebc27ccd0bcfcfaa482c6e2e7fe7b98edf7","affectsGlobalScope":true,"impliedFormat":1},{"version":"0ada07543808f3b967624645a8e1ccd446f8b01ade47842acf1328aec899fed0","affectsGlobalScope":true,"impliedFormat":1},{"version":"c4a806152acbef81593f96cae6f2b04784d776457d97adbe2694478b243fcf03","impliedFormat":1},{"version":"71adf5dbc59568663d252a46179e71e4d544c053978bfc526d11543a3f716f42","impliedFormat":1},{"version":"c60db41f7bee80fb80c0b12819f5e465c8c8b465578da43e36d04f4a4646f57d","impliedFormat":1},{"version":"93bd413918fa921c8729cef45302b24d8b6c7855d72d5bf82d3972595ae8dcbf","impliedFormat":1},{"version":"4ff41188773cbf465807dd2f7059c7494cbee5115608efc297383832a1150c43","impliedFormat":1},{"version":"dccdf1677e531e33f8ac961a68bc537418c9a414797c1ea7e91307501cdc3f5e","impliedFormat":1},{"version":"e184c4b8918ef56c8c9e68bd79f3f3780e2d0d75bf2b8a41da1509a40c2deb46","affectsGlobalScope":true,"impliedFormat":1},{"version":"d206b4baf4ddcc15d9d69a9a2f4999a72a2c6adeaa8af20fa7a9960816287555","impliedFormat":1},{"version":"93f437e1398a4f06a984f441f7fa7a9f0535c04399619b5c22e0b87bdee182cb","impliedFormat":1},{"version":"afbe24ab0d74694372baa632ecb28bb375be53f3be53f9b07ecd7fc994907de5","impliedFormat":1},{"version":"70731d10d5311bd4cf710ef7f6539b62660f4b0bfdbb3f9fbe1d25fe6366a7fa","affectsGlobalScope":true,"impliedFormat":1},{"version":"6b19db3600a17af69d4f33d08cc7076a7d19fb65bb36e442cac58929ec7c9482","affectsGlobalScope":true,"impliedFormat":1},{"version":"9e043a1bc8fbf2a255bccf9bf27e0f1caf916c3b0518ea34aa72357c0afd42ec","impliedFormat":1},{"version":"137c2894e8f3e9672d401cc0a305dc7b1db7c69511cf6d3970fb53302f9eae09","impliedFormat":1},{"version":"3bc2f1e2c95c04048212c569ed38e338873f6a8593930cf5a7ef24ffb38fc3b6","impliedFormat":1},{"version":"8145e07aad6da5f23f2fcd8c8e4c5c13fb26ee986a79d03b0829b8fce152d8b2","impliedFormat":1},{"version":"f9d9d753d430ed050dc1bf2667a1bab711ccbb1c1507183d794cc195a5b085cc","impliedFormat":1},{"version":"9eece5e586312581ccd106d4853e861aaaa1a39f8e3ea672b8c3847eedd12f6e","impliedFormat":1},{"version":"235bfb54b4869c26f7e98e3d1f68dbfc85acf4cf5c38a4444a006fbf74a8a43d","impliedFormat":1},{"version":"37ba7b45141a45ce6e80e66f2a96c8a5ab1bcef0fc2d0f56bb58df96ec67e972","impliedFormat":1},{"version":"93452d394fdd1dc551ec62f5042366f011a00d342d36d50793b3529bfc9bd633","impliedFormat":1},{"version":"bb715efb4857eb94539eafb420352105a0cff40746837c5140bf6b035dd220ba","affectsGlobalScope":true,"impliedFormat":1},{"version":"1851a3b4db78664f83901bb9cac9e45e03a37bb5933cc5bf37e10bb7e91ab4eb","impliedFormat":1},{"version":"fdedf82878e4c744bc2a1c1e802ae407d63474da51f14a54babe039018e53d8f","affectsGlobalScope":true,"impliedFormat":1},{"version":"27d8987fd22d92efe6560cf0ce11767bf089903ffe26047727debfd1f3bf438b","affectsGlobalScope":true,"impliedFormat":1},{"version":"578d8bb6dcb2a1c03c4c3f8eb71abc9677e1a5c788b7f24848e3138ce17f3400","impliedFormat":1},{"version":"4f029899f9bae07e225c43aef893590541b2b43267383bf5e32e3a884d219ed5","impliedFormat":1},{"version":"ae56f65caf3be91108707bd8dfbccc2a57a91feb5daabf7165a06a945545ed26","impliedFormat":1},{"version":"a136d5de521da20f31631a0a96bf712370779d1c05b7015d7019a9b2a0446ca9","impliedFormat":1},{"version":"5b566927cad2ed2139655d55d690ffa87df378b956e7fe1c96024c4d9f75c4cf","affectsGlobalScope":true,"impliedFormat":1},{"version":"bce947017cb7a2deebcc4f5ba04cead891ce6ad1602a4438ae45ed9aa1f39104","affectsGlobalScope":true,"impliedFormat":1},{"version":"d3dffd70e6375b872f0b4e152de4ae682d762c61a24881ecc5eb9f04c5caf76f","impliedFormat":1},{"version":"e2c72c065a36bc9ab2a00ac6a6f51e71501619a72c0609defd304d46610487a4","impliedFormat":1},{"version":"d91a7d8b5655c42986f1bdfe2105c4408f472831c8f20cf11a8c3345b6b56c8c","impliedFormat":1},{"version":"616075a6ac578cf5a013ee12964188b4412823796ce0b202c6f1d2e4ca8480d7","affectsGlobalScope":true,"impliedFormat":1},{"version":"e8a979b8af001c9fc2e774e7809d233c8ca955a28756f52ee5dee88ccb0611d2","impliedFormat":1},{"version":"cac793cc47c29e26e4ac3601dcb00b4435ebed26203485790e44f2ad8b6ad847","impliedFormat":1}],"root":[85,[87,90],92,95,97,98],"options":{"allowJs":true,"esModuleInterop":true,"jsx":4,"module":99,"outDir":"./","skipLibCheck":true,"strict":true,"target":4},"referencedMap":[[84,1],[94,2],[99,3],[100,3],[145,4],[146,4],[147,5],[106,6],[148,7],[149,8],[150,9],[101,3],[104,10],[102,3],[103,3],[151,11],[152,12],[153,13],[154,14],[155,15],[156,16],[157,16],[159,17],[158,18],[160,19],[161,20],[162,21],[144,22],[105,3],[163,23],[164,24],[165,25],[197,26],[166,27],[167,28],[168,29],[169,30],[170,31],[171,32],[172,33],[173,34],[174,35],[175,36],[176,36],[177,37],[178,3],[179,38],[181,39],[180,40],[182,41],[183,42],[184,43],[185,44],[186,45],[187,46],[188,47],[189,48],[190,49],[191,50],[192,51],[193,52],[194,53],[195,54],[196,55],[96,3],[91,3],[86,3],[79,3],[80,56],[81,57],[83,58],[82,56],[93,58],[77,3],[78,3],[13,3],[14,3],[16,3],[15,3],[2,3],[17,3],[18,3],[19,3],[20,3],[21,3],[22,3],[23,3],[24,3],[3,3],[25,3],[26,3],[4,3],[27,3],[31,3],[28,3],[29,3],[30,3],[32,3],[33,3],[34,3],[5,3],[35,3],[36,3],[37,3],[38,3],[6,3],[42,3],[39,3],[40,3],[41,3],[43,3],[7,3],[44,3],[49,3],[50,3],[45,3],[46,3],[47,3],[48,3],[8,3],[54,3],[51,3],[52,3],[53,3],[55,3],[9,3],[56,3],[57,3],[58,3],[60,3],[59,3],[61,3],[62,3],[10,3],[63,3],[64,3],[65,3],[11,3],[66,3],[67,3],[68,3],[69,3],[70,3],[1,3],[71,3],[72,3],[12,3],[75,3],[74,3],[73,3],[76,3],[122,59],[132,60],[121,59],[142,61],[113,62],[112,63],[141,64],[135,65],[140,66],[115,67],[129,68],[114,69],[138,70],[110,71],[109,64],[139,72],[111,73],[116,74],[117,3],[120,74],[107,3],[143,75],[133,76],[124,77],[125,78],[127,79],[123,80],[126,81],[136,64],[118,82],[119,83],[128,84],[108,85],[131,76],[130,74],[134,3],[137,86],[89,87],[90,88],[88,89],[92,90],[85,91],[95,92],[98,93],[97,94],[87,95]],"version":"5.7.3"}
|
package/dist/types/index.d.ts
CHANGED
|
@@ -70,6 +70,7 @@ export interface TestRun {
|
|
|
70
70
|
passed: number;
|
|
71
71
|
failed: number;
|
|
72
72
|
skipped: number;
|
|
73
|
+
flaky?: number;
|
|
73
74
|
duration: number;
|
|
74
75
|
environment?: EnvDetails | EnvDetails[];
|
|
75
76
|
}
|
|
@@ -78,6 +79,7 @@ export interface TrendDataPoint {
|
|
|
78
79
|
passed: number;
|
|
79
80
|
failed: number;
|
|
80
81
|
skipped: number;
|
|
82
|
+
flaky?: number;
|
|
81
83
|
}
|
|
82
84
|
export interface SummaryMetric {
|
|
83
85
|
label: string;
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@arghajit/dummy",
|
|
3
3
|
"author": "Arghajit Singha",
|
|
4
|
-
"version": "0.3.
|
|
4
|
+
"version": "0.3.28",
|
|
5
5
|
"description": "A Playwright reporter and dashboard for visualizing test results.",
|
|
6
6
|
"homepage": "https://arghajit47.github.io/playwright-pulse/",
|
|
7
7
|
"repository": {
|
|
@@ -295,6 +295,12 @@ function generateTestTrendsChart(trendData) {
|
|
|
295
295
|
color: "var(--warning-color)",
|
|
296
296
|
marker: { symbol: "circle" },
|
|
297
297
|
},
|
|
298
|
+
{
|
|
299
|
+
name: "Flaky",
|
|
300
|
+
data: runs.map((r) => r.flaky || 0),
|
|
301
|
+
color: "var(--neutral-500)",
|
|
302
|
+
marker: { symbol: "circle" },
|
|
303
|
+
},
|
|
298
304
|
];
|
|
299
305
|
const runsForTooltip = runs.map((r) => ({
|
|
300
306
|
runId: r.runId,
|
|
@@ -481,6 +487,9 @@ function generateTestHistoryChart(history) {
|
|
|
481
487
|
case "skipped":
|
|
482
488
|
color = "var(--warning-color)";
|
|
483
489
|
break;
|
|
490
|
+
case "flaky":
|
|
491
|
+
color = "var(--neutral-500)";
|
|
492
|
+
break;
|
|
484
493
|
default:
|
|
485
494
|
color = "var(--dark-gray-color)";
|
|
486
495
|
}
|
|
@@ -590,6 +599,9 @@ function generatePieChart(data, chartWidth = 300, chartHeight = 300) {
|
|
|
590
599
|
case "Failed":
|
|
591
600
|
color = "var(--danger-color)";
|
|
592
601
|
break;
|
|
602
|
+
case "Flaky":
|
|
603
|
+
color = "var(--neutral-500)";
|
|
604
|
+
break;
|
|
593
605
|
case "Skipped":
|
|
594
606
|
color = "var(--warning-color)";
|
|
595
607
|
break;
|
|
@@ -828,7 +840,9 @@ function generateEnvironmentSection(environmentData) {
|
|
|
828
840
|
}
|
|
829
841
|
|
|
830
842
|
function generateEnvironmentDashboard(environment, hideHeader = false) {
|
|
831
|
-
const
|
|
843
|
+
const cpuModel = environment.cpu && environment.cpu.model ? environment.cpu.model : "N/A";
|
|
844
|
+
const cpuCores = environment.cpu && environment.cpu.cores ? environment.cpu.cores : "N/A";
|
|
845
|
+
const cpuInfo = `model: ${cpuModel}, cores: ${cpuCores}`;
|
|
832
846
|
const osInfo = environment.os || "N/A";
|
|
833
847
|
const nodeInfo = environment.node || "N/A";
|
|
834
848
|
const v8Info = environment.v8 || "N/A";
|
|
@@ -1140,7 +1154,7 @@ function generateEnvironmentDashboard(environment, hideHeader = false) {
|
|
|
1140
1154
|
</div>
|
|
1141
1155
|
<div class="env-item-content">
|
|
1142
1156
|
<p class="env-item-label">Working Dir</p>
|
|
1143
|
-
<div class="env-item-value" title="${
|
|
1157
|
+
<div class="env-item-value" title="${cwdInfo}">${cwdInfo.length > 30 ? "..." + cwdInfo.slice(-27) : cwdInfo}</div>
|
|
1144
1158
|
</div>
|
|
1145
1159
|
</div>
|
|
1146
1160
|
</div>
|
|
@@ -1164,11 +1178,11 @@ function generateWorkerDistributionChart(results) {
|
|
|
1164
1178
|
const workerId =
|
|
1165
1179
|
typeof test.workerId !== "undefined" ? test.workerId : "N/A";
|
|
1166
1180
|
if (!acc[workerId]) {
|
|
1167
|
-
acc[workerId] = { passed: 0, failed: 0, skipped: 0, tests: [] };
|
|
1181
|
+
acc[workerId] = { passed: 0, failed: 0, skipped: 0, flaky: 0, tests: [] };
|
|
1168
1182
|
}
|
|
1169
1183
|
|
|
1170
1184
|
const status = String(test.status).toLowerCase();
|
|
1171
|
-
if (status === "passed" || status === "failed" || status === "skipped") {
|
|
1185
|
+
if (status === "passed" || status === "failed" || status === "skipped" || status === "flaky") {
|
|
1172
1186
|
acc[workerId][status]++;
|
|
1173
1187
|
}
|
|
1174
1188
|
|
|
@@ -1213,12 +1227,14 @@ function generateWorkerDistributionChart(results) {
|
|
|
1213
1227
|
const passedData = workerIds.map((id) => workerData[id].passed);
|
|
1214
1228
|
const failedData = workerIds.map((id) => workerData[id].failed);
|
|
1215
1229
|
const skippedData = workerIds.map((id) => workerData[id].skipped);
|
|
1230
|
+
const flakyData = workerIds.map((id) => workerData[id].flaky);
|
|
1216
1231
|
|
|
1217
1232
|
const categoriesString = JSON.stringify(categories);
|
|
1218
1233
|
const fullDataString = JSON.stringify(fullWorkerData);
|
|
1219
1234
|
const seriesString = JSON.stringify([
|
|
1220
1235
|
{ name: "Passed", data: passedData, color: "var(--success-color)" },
|
|
1221
1236
|
{ name: "Failed", data: failedData, color: "var(--danger-color)" },
|
|
1237
|
+
{ name: "Flaky", data: flakyData, color: "var(--neutral-500)" },
|
|
1222
1238
|
{ name: "Skipped", data: skippedData, color: "var(--warning-color)" },
|
|
1223
1239
|
]);
|
|
1224
1240
|
|
|
@@ -1311,6 +1327,7 @@ function generateWorkerDistributionChart(results) {
|
|
|
1311
1327
|
if (test.status === 'passed') color = 'var(--success-color)';
|
|
1312
1328
|
else if (test.status === 'failed') color = 'var(--danger-color)';
|
|
1313
1329
|
else if (test.status === 'skipped') color = 'var(--warning-color)';
|
|
1330
|
+
else if (test.status === 'flaky') color = 'var(--neutral-500)';
|
|
1314
1331
|
|
|
1315
1332
|
const escapedName = test.name.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>');
|
|
1316
1333
|
testListHtml += \`<li style="color: \${color};"><span style="color: \${color}">[\${test.status.toUpperCase()}]</span> \${escapedName}</li>\`;
|
|
@@ -1476,6 +1493,7 @@ function generateTestHistoryContent(trendData) {
|
|
|
1476
1493
|
<option value="">All Statuses</option>
|
|
1477
1494
|
<option value="passed">Passed</option>
|
|
1478
1495
|
<option value="failed">Failed</option>
|
|
1496
|
+
<option value="flaky">Flaky</option>
|
|
1479
1497
|
<option value="skipped">Skipped</option>
|
|
1480
1498
|
</select>
|
|
1481
1499
|
<button id="clear-history-filters" class="clear-filters-btn">Clear Filters</button>
|
|
@@ -1594,6 +1612,7 @@ function getSuitesData(results) {
|
|
|
1594
1612
|
browser: browser,
|
|
1595
1613
|
passed: 0,
|
|
1596
1614
|
failed: 0,
|
|
1615
|
+
flaky: 0,
|
|
1597
1616
|
skipped: 0,
|
|
1598
1617
|
count: 0,
|
|
1599
1618
|
statusOverall: "passed",
|
|
@@ -1601,12 +1620,15 @@ function getSuitesData(results) {
|
|
|
1601
1620
|
}
|
|
1602
1621
|
const suite = suitesMap.get(key);
|
|
1603
1622
|
suite.count++;
|
|
1604
|
-
|
|
1623
|
+
let currentStatus = String(test.status).toLowerCase();
|
|
1624
|
+
if (test.outcome === 'flaky') currentStatus = 'flaky';
|
|
1605
1625
|
if (currentStatus && suite[currentStatus] !== undefined) {
|
|
1606
1626
|
suite[currentStatus]++;
|
|
1607
1627
|
}
|
|
1608
1628
|
if (currentStatus === "failed") suite.statusOverall = "failed";
|
|
1609
|
-
else if (currentStatus === "
|
|
1629
|
+
else if (currentStatus === "flaky" && suite.statusOverall !== "failed")
|
|
1630
|
+
suite.statusOverall = "flaky";
|
|
1631
|
+
else if (currentStatus === "skipped" && suite.statusOverall !== "failed" && suite.statusOverall !== "flaky")
|
|
1610
1632
|
suite.statusOverall = "skipped";
|
|
1611
1633
|
});
|
|
1612
1634
|
return Array.from(suitesMap.values());
|
|
@@ -1656,6 +1678,10 @@ function generateSuitesWidget(suitesData) {
|
|
|
1656
1678
|
<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>
|
|
1657
1679
|
${suite.failed}
|
|
1658
1680
|
</span>
|
|
1681
|
+
<span class="stat-pill flaky" title="Flaky">
|
|
1682
|
+
<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>
|
|
1683
|
+
${suite.flaky || 0}
|
|
1684
|
+
</span>
|
|
1659
1685
|
<span class="stat-pill skipped" title="Skipped">
|
|
1660
1686
|
<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>
|
|
1661
1687
|
${suite.skipped}
|
|
@@ -2060,6 +2086,7 @@ function generateSeverityDistributionChart(results) {
|
|
|
2060
2086
|
const data = {
|
|
2061
2087
|
passed: [0, 0, 0, 0, 0],
|
|
2062
2088
|
failed: [0, 0, 0, 0, 0],
|
|
2089
|
+
flaky: [0, 0, 0, 0, 0],
|
|
2063
2090
|
skipped: [0, 0, 0, 0, 0],
|
|
2064
2091
|
};
|
|
2065
2092
|
|
|
@@ -2078,6 +2105,8 @@ function generateSeverityDistributionChart(results) {
|
|
|
2078
2105
|
status === "interrupted"
|
|
2079
2106
|
) {
|
|
2080
2107
|
data.failed[index]++;
|
|
2108
|
+
} else if (status === "flaky") {
|
|
2109
|
+
data.flaky[index]++;
|
|
2081
2110
|
} else {
|
|
2082
2111
|
data.skipped[index]++;
|
|
2083
2112
|
}
|
|
@@ -2091,6 +2120,7 @@ function generateSeverityDistributionChart(results) {
|
|
|
2091
2120
|
const seriesData = [
|
|
2092
2121
|
{ name: "Passed", data: data.passed, color: "var(--success-color)" },
|
|
2093
2122
|
{ name: "Failed", data: data.failed, color: "var(--danger-color)" },
|
|
2123
|
+
{ name: "Flaky", data: data.flaky, color: "var(--neutral-500)" },
|
|
2094
2124
|
{ name: "Skipped", data: data.skipped, color: "var(--warning-color)" },
|
|
2095
2125
|
];
|
|
2096
2126
|
|
|
@@ -2204,17 +2234,14 @@ function generateHTML(reportData, trendData = null) {
|
|
|
2204
2234
|
return p.replace(new RegExp(`^${DEFAULT_OUTPUT_DIR}[\\\\/]`), "");
|
|
2205
2235
|
};
|
|
2206
2236
|
|
|
2207
|
-
|
|
2208
|
-
const passPercentage = Math.round((runSummary.passed / totalTestsOr1) * 100);
|
|
2209
|
-
const failPercentage = Math.round((runSummary.failed / totalTestsOr1) * 100);
|
|
2210
|
-
const skipPercentage = Math.round(
|
|
2211
|
-
((runSummary.skipped || 0) / totalTestsOr1) * 100,
|
|
2212
|
-
);
|
|
2237
|
+
|
|
2213
2238
|
const avgTestDuration =
|
|
2214
2239
|
runSummary.totalTests > 0
|
|
2215
2240
|
? formatDuration(runSummary.duration / runSummary.totalTests)
|
|
2216
2241
|
: "0.0s";
|
|
2217
2242
|
|
|
2243
|
+
const flakyCount = (results || []).filter(r => r.outcome === 'flaky').length;
|
|
2244
|
+
|
|
2218
2245
|
// Calculate retry statistics
|
|
2219
2246
|
const totalRetried = (results || []).reduce((acc, test) => {
|
|
2220
2247
|
if (test.retryHistory && test.retryHistory.length > 0) {
|
|
@@ -2227,19 +2254,30 @@ function generateHTML(reportData, trendData = null) {
|
|
|
2227
2254
|
let calculatedPassed = 0;
|
|
2228
2255
|
let calculatedFailed = 0;
|
|
2229
2256
|
let calculatedSkipped = 0;
|
|
2257
|
+
let calculatedFlaky = 0;
|
|
2230
2258
|
let calculatedTotal = 0;
|
|
2231
2259
|
|
|
2232
2260
|
(results || []).forEach(test => {
|
|
2233
2261
|
calculatedTotal++;
|
|
2234
|
-
//
|
|
2235
|
-
|
|
2236
|
-
|
|
2237
|
-
|
|
2262
|
+
// New Logic: If outcome is 'flaky', it overrides everything.
|
|
2263
|
+
let statusToUse = test.status;
|
|
2264
|
+
if (test.outcome === 'flaky') {
|
|
2265
|
+
statusToUse = 'flaky';
|
|
2266
|
+
} else if (test.status === 'flaky') {
|
|
2267
|
+
// Just in case outcome wasn't set but status was (unlikely with new reporter)
|
|
2268
|
+
statusToUse = 'flaky';
|
|
2269
|
+
} else if (test.retryHistory && test.retryHistory.length > 0 && test.final_status) {
|
|
2270
|
+
statusToUse = test.final_status;
|
|
2271
|
+
}
|
|
2272
|
+
|
|
2273
|
+
// Update test status in place for charts
|
|
2274
|
+
test.status = statusToUse;
|
|
2238
2275
|
|
|
2239
2276
|
const s = String(statusToUse).toLowerCase();
|
|
2240
2277
|
if (s === 'passed') calculatedPassed++;
|
|
2241
2278
|
else if (s === 'skipped') calculatedSkipped++;
|
|
2242
|
-
else
|
|
2279
|
+
else if (s === 'flaky') calculatedFlaky++;
|
|
2280
|
+
else calculatedFailed++; // failed, timedout, interrupted
|
|
2243
2281
|
});
|
|
2244
2282
|
|
|
2245
2283
|
// Override runSummary counts with our calculated ones if results exist
|
|
@@ -2247,9 +2285,18 @@ function generateHTML(reportData, trendData = null) {
|
|
|
2247
2285
|
runSummary.passed = calculatedPassed;
|
|
2248
2286
|
runSummary.failed = calculatedFailed;
|
|
2249
2287
|
runSummary.skipped = calculatedSkipped;
|
|
2288
|
+
runSummary.flaky = calculatedFlaky;
|
|
2250
2289
|
runSummary.totalTests = calculatedTotal;
|
|
2251
2290
|
}
|
|
2252
2291
|
|
|
2292
|
+
const totalTestsOr1 = runSummary.totalTests || 1;
|
|
2293
|
+
const passPercentage = Math.round((runSummary.passed / totalTestsOr1) * 100);
|
|
2294
|
+
const failPercentage = Math.round((runSummary.failed / totalTestsOr1) * 100);
|
|
2295
|
+
const skipPercentage = Math.round(
|
|
2296
|
+
((runSummary.skipped || 0) / totalTestsOr1) * 100,
|
|
2297
|
+
);
|
|
2298
|
+
const flakyPercentage = Math.round(((runSummary.flaky || 0) / totalTestsOr1) * 100);
|
|
2299
|
+
|
|
2253
2300
|
|
|
2254
2301
|
// Calculate browser distribution
|
|
2255
2302
|
const browserStats = (results || []).reduce((acc, test) => {
|
|
@@ -2654,7 +2701,7 @@ function generateHTML(reportData, trendData = null) {
|
|
|
2654
2701
|
? test.final_status
|
|
2655
2702
|
: test.status;
|
|
2656
2703
|
|
|
2657
|
-
const outcomeBadge = (test.outcome)
|
|
2704
|
+
const outcomeBadge = (test.outcome && test.outcome !== 'flaky')
|
|
2658
2705
|
? `<span class="outcome-badge ${test.outcome}">${test.outcome}</span>`
|
|
2659
2706
|
: '';
|
|
2660
2707
|
|
|
@@ -2970,12 +3017,17 @@ function generateHTML(reportData, trendData = null) {
|
|
|
2970
3017
|
}
|
|
2971
3018
|
}
|
|
2972
3019
|
|
|
3020
|
+
|
|
3021
|
+
.stat-pill.flaky { color: #4b5563; }
|
|
3022
|
+
|
|
2973
3023
|
.dashboard-grid {
|
|
2974
3024
|
display: grid;
|
|
2975
3025
|
grid-template-columns: repeat(4, 1fr);
|
|
2976
3026
|
gap: 0;
|
|
2977
3027
|
margin: 0 0 40px 0;
|
|
2978
3028
|
}
|
|
3029
|
+
.stats-pill.failed { color: var(--danger-dark); }
|
|
3030
|
+
.stats-pill.flaky { color: #4b5563; }
|
|
2979
3031
|
.browser-breakdown {
|
|
2980
3032
|
display: flex;
|
|
2981
3033
|
flex-direction: column;
|
|
@@ -3420,12 +3472,19 @@ function generateHTML(reportData, trendData = null) {
|
|
|
3420
3472
|
box-shadow: 0 4px 12px rgba(239, 68, 68, 0.2);
|
|
3421
3473
|
}
|
|
3422
3474
|
.summary-card.status-failed .value { color: #ef4444; }
|
|
3475
|
+
.summary-card.status-flaky::before { background: var(--neutral-500); }
|
|
3423
3476
|
.summary-card.status-skipped { background: rgba(245, 158, 11, 0.02); }
|
|
3424
3477
|
.summary-card.status-skipped:hover {
|
|
3425
3478
|
background: rgba(245, 158, 11, 0.15);
|
|
3426
3479
|
box-shadow: 0 4px 12px rgba(245, 158, 11, 0.2);
|
|
3427
3480
|
}
|
|
3428
3481
|
.summary-card.status-skipped .value { color: #f59e0b; }
|
|
3482
|
+
.summary-card.flaky-status { background: rgba(156, 163, 175, 0.05); }
|
|
3483
|
+
.summary-card.flaky-status:hover {
|
|
3484
|
+
background: rgba(156, 163, 175, 0.15);
|
|
3485
|
+
box-shadow: 0 4px 12px rgba(156, 163, 175, 0.2);
|
|
3486
|
+
}
|
|
3487
|
+
.summary-card.flaky-status .value { color: #64748b; }
|
|
3429
3488
|
.summary-card:not([class*='status-']) .value { color: #0f172a; }
|
|
3430
3489
|
.dashboard-bottom-row { display: grid; grid-template-columns: repeat(auto-fit, minmax(350px, 1fr)); gap: 28px; align-items: start; }
|
|
3431
3490
|
.dashboard-column {
|
|
@@ -3525,6 +3584,7 @@ function generateHTML(reportData, trendData = null) {
|
|
|
3525
3584
|
}
|
|
3526
3585
|
.suite-card.status-passed::before { background: var(--success-color); }
|
|
3527
3586
|
.suite-card.status-failed::before { background: var(--danger-color); }
|
|
3587
|
+
.suite-card.status-flaky::before { background: var(--neutral-500); }
|
|
3528
3588
|
.suite-card.status-skipped::before { background: var(--warning-color); }
|
|
3529
3589
|
|
|
3530
3590
|
/* Outcome Badge */
|
|
@@ -3570,8 +3630,9 @@ function generateHTML(reportData, trendData = null) {
|
|
|
3570
3630
|
}
|
|
3571
3631
|
.status-indicator-dot.status-passed { background-color: var(--success-color); box-shadow: 0 0 0 4px rgba(16, 185, 129, 0.15); }
|
|
3572
3632
|
.status-indicator-dot.status-failed { background-color: var(--danger-color); box-shadow: 0 0 0 4px rgba(239, 68, 68, 0.15); }
|
|
3633
|
+
.status-indicator-dot.status-flaky { background-color: var(--neutral-500); box-shadow: 0 0 0 4px rgba(107, 114, 128, 0.15); }
|
|
3573
3634
|
.status-indicator-dot.status-skipped { background-color: rgba(245, 158, 11, 0.1); color: var(--warning-dark); border: 1px solid rgba(245, 158, 11, 0.2); }
|
|
3574
|
-
.status-flaky { background-color:
|
|
3635
|
+
.status-flaky { background-color: #C0C0C0; color: #000000; border: 1px solid #A0A0A0; }
|
|
3575
3636
|
|
|
3576
3637
|
.browser-tag {
|
|
3577
3638
|
font-size: 0.8em;
|
|
@@ -3623,6 +3684,7 @@ function generateHTML(reportData, trendData = null) {
|
|
|
3623
3684
|
.stat-pill svg { width: 14px; height: 14px; }
|
|
3624
3685
|
.stat-pill.passed { color: var(--success-dark); }
|
|
3625
3686
|
.stat-pill.failed { color: var(--danger-dark); }
|
|
3687
|
+
.stat-pill.flaky { color: #4b5563; }
|
|
3626
3688
|
.stat-pill.skipped { color: var(--warning-dark); }
|
|
3627
3689
|
.filters {
|
|
3628
3690
|
display: flex;
|
|
@@ -4496,7 +4558,8 @@ function generateHTML(reportData, trendData = null) {
|
|
|
4496
4558
|
<div class="summary-card status-skipped"><h3>Skipped</h3><div class="value">${
|
|
4497
4559
|
runSummary.skipped || 0
|
|
4498
4560
|
}</div><div class="trend-percentage">${skipPercentage}%</div></div>
|
|
4499
|
-
<div class="summary-card"><h3>
|
|
4561
|
+
<div class="summary-card flaky-status"><h3>Flaky</h3><div class="value">${runSummary.flaky || 0}</div>
|
|
4562
|
+
<div class="trend-percentage">${flakyPercentage}%</div></div>
|
|
4500
4563
|
<div class="summary-card"><h3>Run Duration</h3><div class="value">${formatDuration(
|
|
4501
4564
|
runSummary.duration,
|
|
4502
4565
|
)}</div></div>
|
|
@@ -4533,6 +4596,7 @@ function generateHTML(reportData, trendData = null) {
|
|
|
4533
4596
|
[
|
|
4534
4597
|
{ label: "Passed", value: runSummary.passed },
|
|
4535
4598
|
{ label: "Failed", value: runSummary.failed },
|
|
4599
|
+
{ label: "Flaky", value: runSummary.flaky || 0 },
|
|
4536
4600
|
{ label: "Skipped", value: runSummary.skipped || 0 },
|
|
4537
4601
|
],
|
|
4538
4602
|
400,
|
|
@@ -4550,7 +4614,7 @@ function generateHTML(reportData, trendData = null) {
|
|
|
4550
4614
|
<div id="test-runs" class="tab-content">
|
|
4551
4615
|
<div class="filters">
|
|
4552
4616
|
<input type="text" id="filter-name" placeholder="Filter by test name/path..." style="border-color: black; border-style: outset;">
|
|
4553
|
-
<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>
|
|
4617
|
+
<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>
|
|
4554
4618
|
<select id="filter-browser"><option value="">All Browsers</option>${Array.from(
|
|
4555
4619
|
new Set(
|
|
4556
4620
|
(results || []).map((test) => test.browser || "unknown"),
|
|
@@ -5308,6 +5372,7 @@ async function main() {
|
|
|
5308
5372
|
passed: histRunReport.run.passed,
|
|
5309
5373
|
failed: histRunReport.run.failed,
|
|
5310
5374
|
skipped: histRunReport.run.skipped || 0,
|
|
5375
|
+
flaky: histRunReport.run.flaky || (histRunReport.results ? histRunReport.results.filter(r => r.status === 'flaky' || r.outcome === 'flaky').length : 0),
|
|
5311
5376
|
});
|
|
5312
5377
|
|
|
5313
5378
|
if (histRunReport.results && Array.isArray(histRunReport.results)) {
|
|
@@ -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: "var(--neutral-500)",
|
|
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 = "var(--neutral-500)";
|
|
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: "var(--neutral-500)" },
|
|
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: "var(--neutral-500)" },
|
|
2289
2319
|
{ name: "Skipped", data: data.skipped, color: "var(--warning-color)" },
|
|
2290
2320
|
];
|
|
2291
2321
|
|
|
@@ -2429,17 +2459,14 @@ 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
|
|
2444
2471
|
const totalRetried = (results || []).reduce((acc, test) => {
|
|
2445
2472
|
if (test.retryHistory && test.retryHistory.length > 0) {
|
|
@@ -2452,19 +2479,30 @@ function generateHTML(reportData, trendData = null) {
|
|
|
2452
2479
|
let calculatedPassed = 0;
|
|
2453
2480
|
let calculatedFailed = 0;
|
|
2454
2481
|
let calculatedSkipped = 0;
|
|
2482
|
+
let calculatedFlaky = 0;
|
|
2455
2483
|
let calculatedTotal = 0;
|
|
2456
2484
|
|
|
2457
2485
|
(results || []).forEach(test => {
|
|
2458
2486
|
calculatedTotal++;
|
|
2459
|
-
//
|
|
2460
|
-
|
|
2461
|
-
|
|
2462
|
-
|
|
2487
|
+
// New Logic: If outcome is 'flaky', it overrides everything.
|
|
2488
|
+
let statusToUse = test.status;
|
|
2489
|
+
if (test.outcome === 'flaky') {
|
|
2490
|
+
statusToUse = 'flaky';
|
|
2491
|
+
} else if (test.status === 'flaky') {
|
|
2492
|
+
// Just in case outcome wasn't set but status was (unlikely with new reporter)
|
|
2493
|
+
statusToUse = 'flaky';
|
|
2494
|
+
} else if (test.retryHistory && test.retryHistory.length > 0 && test.final_status) {
|
|
2495
|
+
statusToUse = test.final_status;
|
|
2496
|
+
}
|
|
2497
|
+
|
|
2498
|
+
// Update test status in place for charts
|
|
2499
|
+
test.status = statusToUse;
|
|
2463
2500
|
|
|
2464
2501
|
const s = String(statusToUse).toLowerCase();
|
|
2465
2502
|
if (s === 'passed') calculatedPassed++;
|
|
2466
2503
|
else if (s === 'skipped') calculatedSkipped++;
|
|
2467
|
-
else
|
|
2504
|
+
else if (s === 'flaky') calculatedFlaky++;
|
|
2505
|
+
else calculatedFailed++; // failed, timedout, interrupted
|
|
2468
2506
|
});
|
|
2469
2507
|
|
|
2470
2508
|
// Override runSummary counts with our calculated ones if results exist
|
|
@@ -2472,9 +2510,18 @@ function generateHTML(reportData, trendData = null) {
|
|
|
2472
2510
|
runSummary.passed = calculatedPassed;
|
|
2473
2511
|
runSummary.failed = calculatedFailed;
|
|
2474
2512
|
runSummary.skipped = calculatedSkipped;
|
|
2513
|
+
runSummary.flaky = calculatedFlaky;
|
|
2475
2514
|
runSummary.totalTests = calculatedTotal;
|
|
2476
2515
|
}
|
|
2477
2516
|
|
|
2517
|
+
const totalTestsOr1 = runSummary.totalTests || 1;
|
|
2518
|
+
const passPercentage = Math.round((runSummary.passed / totalTestsOr1) * 100);
|
|
2519
|
+
const failPercentage = Math.round((runSummary.failed / totalTestsOr1) * 100);
|
|
2520
|
+
const skipPercentage = Math.round(
|
|
2521
|
+
((runSummary.skipped || 0) / totalTestsOr1) * 100,
|
|
2522
|
+
);
|
|
2523
|
+
const flakyPercentage = Math.round(((runSummary.flaky || 0) / totalTestsOr1) * 100);
|
|
2524
|
+
|
|
2478
2525
|
|
|
2479
2526
|
// Calculate browser distribution
|
|
2480
2527
|
const browserStats = (results || []).reduce((acc, test) => {
|
|
@@ -2876,7 +2923,7 @@ function generateHTML(reportData, trendData = null) {
|
|
|
2876
2923
|
? test.final_status
|
|
2877
2924
|
: test.status;
|
|
2878
2925
|
|
|
2879
|
-
const outcomeBadge = (test.outcome)
|
|
2926
|
+
const outcomeBadge = (test.outcome && test.outcome !== 'flaky')
|
|
2880
2927
|
? `<span class="outcome-badge ${test.outcome}">${test.outcome}</span>`
|
|
2881
2928
|
: '';
|
|
2882
2929
|
|
|
@@ -3423,6 +3470,16 @@ function generateHTML(reportData, trendData = null) {
|
|
|
3423
3470
|
.summary-card.status-skipped .value {
|
|
3424
3471
|
color: #f59e0b;
|
|
3425
3472
|
}
|
|
3473
|
+
.summary-card.flaky-status {
|
|
3474
|
+
background: rgba(156, 163, 175, 0.08);
|
|
3475
|
+
}
|
|
3476
|
+
.summary-card.flaky-status:hover {
|
|
3477
|
+
background: rgba(156, 163, 175, 0.15);
|
|
3478
|
+
box-shadow: 0 4px 12px rgba(156, 163, 175, 0.2);
|
|
3479
|
+
}
|
|
3480
|
+
.summary-card.flaky-status .value {
|
|
3481
|
+
color: #9ca3af;
|
|
3482
|
+
}
|
|
3426
3483
|
.summary-card:not([class*='status-']) .value {
|
|
3427
3484
|
color: #f9fafb;
|
|
3428
3485
|
}
|
|
@@ -3545,6 +3602,7 @@ function generateHTML(reportData, trendData = null) {
|
|
|
3545
3602
|
}
|
|
3546
3603
|
.suite-card.status-passed::before { background: var(--success-color); }
|
|
3547
3604
|
.suite-card.status-failed::before { background: var(--danger-color); }
|
|
3605
|
+
.suite-card.status-flaky::before { background: var(--neutral-500); }
|
|
3548
3606
|
.suite-card.status-skipped::before { background: var(--warning-color); }
|
|
3549
3607
|
|
|
3550
3608
|
.suite-card.status-skipped::before { background: var(--warning-color); }
|
|
@@ -3647,6 +3705,7 @@ function generateHTML(reportData, trendData = null) {
|
|
|
3647
3705
|
.stat-pill svg { width: 14px; height: 14px; }
|
|
3648
3706
|
.stat-pill.passed { color: var(--success-dark); }
|
|
3649
3707
|
.stat-pill.failed { color: var(--danger-dark); }
|
|
3708
|
+
.stat-pill.flaky { color: #4b5563; }
|
|
3650
3709
|
.stat-pill.skipped { color: var(--warning-dark); }
|
|
3651
3710
|
color: #93c5fd;
|
|
3652
3711
|
padding: 6px 12px;
|
|
@@ -3842,9 +3901,9 @@ function generateHTML(reportData, trendData = null) {
|
|
|
3842
3901
|
background: var(--warning-color);
|
|
3843
3902
|
}
|
|
3844
3903
|
.status-badge.status-flaky {
|
|
3845
|
-
background:
|
|
3846
|
-
color:
|
|
3847
|
-
border: 1px solid
|
|
3904
|
+
background-color: #C0C0C0;
|
|
3905
|
+
color: #000000;
|
|
3906
|
+
border: 1px solid #A0A0A0;
|
|
3848
3907
|
}
|
|
3849
3908
|
.status-badge.status-unknown {
|
|
3850
3909
|
background: var(--dark-gray-color);
|
|
@@ -4480,7 +4539,8 @@ function generateHTML(reportData, trendData = null) {
|
|
|
4480
4539
|
background-color: #f59e0b;
|
|
4481
4540
|
}
|
|
4482
4541
|
.status-badge-small.status-flaky {
|
|
4483
|
-
background-color: #
|
|
4542
|
+
background-color: #C0C0C0;
|
|
4543
|
+
color: #000000;
|
|
4484
4544
|
}
|
|
4485
4545
|
.status-badge-small.status-unknown {
|
|
4486
4546
|
background-color: var(--dark-gray-color);
|
|
@@ -6182,7 +6242,8 @@ function generateHTML(reportData, trendData = null) {
|
|
|
6182
6242
|
<div class="summary-card status-skipped"><h3>Skipped</h3><div class="value">${
|
|
6183
6243
|
runSummary.skipped || 0
|
|
6184
6244
|
}</div><div class="trend-percentage">${skipPercentage}%</div></div>
|
|
6185
|
-
<div class="summary-card"><h3>
|
|
6245
|
+
<div class="summary-card flaky-status"><h3>Flaky</h3><div class="value">${runSummary.flaky || 0}</div>
|
|
6246
|
+
<div class="trend-percentage">${flakyPercentage}%</div></div>
|
|
6186
6247
|
<div class="summary-card"><h3>Run Duration</h3><div class="value">${formatDuration(
|
|
6187
6248
|
runSummary.duration,
|
|
6188
6249
|
)}</div></div>
|
|
@@ -6219,6 +6280,7 @@ function generateHTML(reportData, trendData = null) {
|
|
|
6219
6280
|
[
|
|
6220
6281
|
{ label: "Passed", value: runSummary.passed },
|
|
6221
6282
|
{ label: "Failed", value: runSummary.failed },
|
|
6283
|
+
{ label: "Flaky", value: runSummary.flaky || 0 },
|
|
6222
6284
|
{ label: "Skipped", value: runSummary.skipped || 0 },
|
|
6223
6285
|
],
|
|
6224
6286
|
400,
|
|
@@ -6235,7 +6297,7 @@ function generateHTML(reportData, trendData = null) {
|
|
|
6235
6297
|
<div id="test-runs" class="tab-content">
|
|
6236
6298
|
<div class="filters" style="border-color: black; border-style: groove;">
|
|
6237
6299
|
<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>
|
|
6300
|
+
<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
6301
|
<select id="filter-browser"><option value="">All Browsers</option>${Array.from(
|
|
6240
6302
|
new Set(
|
|
6241
6303
|
(results || []).map((test) => test.browser || "unknown"),
|
|
@@ -7175,6 +7237,7 @@ async function main() {
|
|
|
7175
7237
|
passed: histRunReport.run.passed,
|
|
7176
7238
|
failed: histRunReport.run.failed,
|
|
7177
7239
|
skipped: histRunReport.run.skipped || 0,
|
|
7240
|
+
flaky: histRunReport.run.flaky || (histRunReport.results ? histRunReport.results.filter(r => r.status === 'flaky' || r.outcome === 'flaky').length : 0),
|
|
7178
7241
|
});
|
|
7179
7242
|
|
|
7180
7243
|
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);
|