@arghajit/playwright-pulse-report 0.3.3 → 0.3.5
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/README.md +95 -85
- package/dist/lib/report-types.d.ts +2 -0
- package/dist/reporter/playwright-pulse-reporter.d.ts +18 -1
- package/dist/reporter/playwright-pulse-reporter.js +157 -129
- package/dist/reporter/tsconfig.reporter.tsbuildinfo +1 -0
- package/dist/types/index.d.ts +53 -9
- package/dist/utils/compression-utils.d.ts +19 -0
- package/dist/utils/compression-utils.js +112 -0
- package/package.json +18 -9
- package/scripts/config-reader.mjs +114 -124
- package/scripts/generate-email-report.mjs +96 -21
- package/scripts/generate-report.mjs +1172 -531
- package/scripts/generate-static-report.mjs +1269 -540
- package/scripts/generate-trend.mjs +8 -4
- package/scripts/{merge-pulse-report.js → merge-pulse-report.mjs} +64 -35
- package/scripts/merge-sequential-reports.mjs +172 -0
- package/scripts/sendReport.mjs +156 -202
- package/scripts/terminal-logo.mjs +51 -0
- 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
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import chalk from "chalk";
|
|
3
|
+
|
|
4
|
+
const logoRaw = ` :------------
|
|
5
|
+
--------------------
|
|
6
|
+
-- ------------------------
|
|
7
|
+
------ ----------------
|
|
8
|
+
----- -------------
|
|
9
|
+
------ ----------- ---------
|
|
10
|
+
------- -------- ------ ---------
|
|
11
|
+
------------- ---- ---- --- -----------
|
|
12
|
+
----------- --- ---- ----- ------------
|
|
13
|
+
---------- ------- --------------
|
|
14
|
+
---------------- ----------- -----
|
|
15
|
+
----- ----------- -----
|
|
16
|
+
------------- ------
|
|
17
|
+
-------------------------------
|
|
18
|
+
--------------------
|
|
19
|
+
--------------`;
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Plays the Pulse Logo animation.
|
|
23
|
+
* Exported so it can be triggered by other scripts in your bin configuration.
|
|
24
|
+
*/
|
|
25
|
+
export async function animate() {
|
|
26
|
+
// Just display the logo once without animation
|
|
27
|
+
// Terminal clearing doesn't work reliably across all environments
|
|
28
|
+
console.log(""); // Empty line for spacing
|
|
29
|
+
console.log(
|
|
30
|
+
logoRaw
|
|
31
|
+
.split("\n")
|
|
32
|
+
.map((line) => chalk.hex("#3f51b5")(line))
|
|
33
|
+
.join("\n"),
|
|
34
|
+
);
|
|
35
|
+
console.log(
|
|
36
|
+
chalk.white.bold(" P L A Y W R I G H T P U L S E R E P O R T"),
|
|
37
|
+
);
|
|
38
|
+
console.log(
|
|
39
|
+
chalk.gray(" ──────────────────────────────────────────────────"),
|
|
40
|
+
);
|
|
41
|
+
console.log(""); // Empty line after logo
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
// Check if the script is being run directly (e.g., `pulse-logo`)
|
|
45
|
+
const isDirectRun =
|
|
46
|
+
import.meta.url === `file://${process.argv[1]}` ||
|
|
47
|
+
process.argv[1]?.endsWith("terminal-logo.mjs");
|
|
48
|
+
|
|
49
|
+
if (isDirectRun) {
|
|
50
|
+
animate();
|
|
51
|
+
}
|
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
|
-
}
|
|
@@ -1,304 +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 __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
-
}) : function(o, v) {
|
|
16
|
-
o["default"] = v;
|
|
17
|
-
});
|
|
18
|
-
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
-
var ownKeys = function(o) {
|
|
20
|
-
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
-
var ar = [];
|
|
22
|
-
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
-
return ar;
|
|
24
|
-
};
|
|
25
|
-
return ownKeys(o);
|
|
26
|
-
};
|
|
27
|
-
return function (mod) {
|
|
28
|
-
if (mod && mod.__esModule) return mod;
|
|
29
|
-
var result = {};
|
|
30
|
-
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
-
__setModuleDefault(result, mod);
|
|
32
|
-
return result;
|
|
33
|
-
};
|
|
34
|
-
})();
|
|
35
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
-
exports.PlaywrightPulseReporter = void 0;
|
|
37
|
-
const fs = __importStar(require("fs/promises"));
|
|
38
|
-
const path = __importStar(require("path"));
|
|
39
|
-
// Helper to convert Playwright status to Pulse status
|
|
40
|
-
const convertStatus = (status) => {
|
|
41
|
-
if (status === "passed")
|
|
42
|
-
return "passed";
|
|
43
|
-
if (status === "failed" || status === "timedOut" || status === "interrupted")
|
|
44
|
-
return "failed";
|
|
45
|
-
return "skipped";
|
|
46
|
-
};
|
|
47
|
-
const TEMP_SHARD_FILE_PREFIX = ".pulse-shard-results-";
|
|
48
|
-
// Use standard ES module export
|
|
49
|
-
class PlaywrightPulseReporter {
|
|
50
|
-
constructor(options = {}) {
|
|
51
|
-
var _a;
|
|
52
|
-
this.results = []; // Holds results *per process* (main or shard)
|
|
53
|
-
this.baseOutputFile = "playwright-pulse-report.json";
|
|
54
|
-
this.isSharded = false;
|
|
55
|
-
this.shardIndex = undefined;
|
|
56
|
-
this.baseOutputFile = (_a = options.outputFile) !== null && _a !== void 0 ? _a : this.baseOutputFile;
|
|
57
|
-
// Initial outputDir setup (will be refined in onBegin)
|
|
58
|
-
const baseDir = options.outputDir
|
|
59
|
-
? path.resolve(options.outputDir)
|
|
60
|
-
: process.cwd();
|
|
61
|
-
this.outputDir = baseDir;
|
|
62
|
-
console.log(`PlaywrightPulseReporter: Initial Output dir configured to ${this.outputDir}`);
|
|
63
|
-
}
|
|
64
|
-
printsToStdio() {
|
|
65
|
-
return this.shardIndex === undefined || this.shardIndex === 0;
|
|
66
|
-
}
|
|
67
|
-
onBegin(config, suite) {
|
|
68
|
-
this.config = config;
|
|
69
|
-
this.suite = suite;
|
|
70
|
-
this.runStartTime = Date.now();
|
|
71
|
-
const totalShards = parseInt(process.env.PLAYWRIGHT_SHARD_TOTAL || "1", 10);
|
|
72
|
-
this.isSharded = totalShards > 1;
|
|
73
|
-
if (process.env.PLAYWRIGHT_SHARD_INDEX !== undefined) {
|
|
74
|
-
this.shardIndex = parseInt(process.env.PLAYWRIGHT_SHARD_INDEX, 10);
|
|
75
|
-
}
|
|
76
|
-
const configDir = this.config.rootDir;
|
|
77
|
-
this.outputDir = this.outputDir
|
|
78
|
-
? path.resolve(configDir, this.outputDir)
|
|
79
|
-
: path.resolve(configDir, "pulse-report");
|
|
80
|
-
console.log(`PlaywrightPulseReporter: Final Output dir resolved to ${this.outputDir}`);
|
|
81
|
-
if (this.shardIndex === undefined) {
|
|
82
|
-
// Main process
|
|
83
|
-
console.log(`PlaywrightPulseReporter: Starting test run with ${suite.allTests().length} tests${this.isSharded ? ` across ${totalShards} shards` : ""}. Outputting to ${this.outputDir}`);
|
|
84
|
-
this._cleanupTemporaryFiles().catch((err) => console.error("Pulse Reporter: Error cleaning up temp files:", err));
|
|
85
|
-
}
|
|
86
|
-
else {
|
|
87
|
-
// Shard process
|
|
88
|
-
console.log(`PlaywrightPulseReporter: Shard ${this.shardIndex + 1}/${totalShards} starting. Outputting temp results to ${this.outputDir}`);
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
onTestBegin(test) {
|
|
92
|
-
// Optional: Log test start
|
|
93
|
-
}
|
|
94
|
-
processStep(step, parentStatus) {
|
|
95
|
-
var _a;
|
|
96
|
-
const inherentStatus = parentStatus === "failed" || parentStatus === "skipped"
|
|
97
|
-
? parentStatus
|
|
98
|
-
: convertStatus(step.error ? "failed" : "passed");
|
|
99
|
-
const duration = step.duration;
|
|
100
|
-
const startTime = new Date(step.startTime);
|
|
101
|
-
const endTime = new Date(startTime.getTime() + Math.max(0, duration));
|
|
102
|
-
return {
|
|
103
|
-
id: `${step.title}-${startTime.toISOString()}-${duration}-${Math.random()
|
|
104
|
-
.toString(16)
|
|
105
|
-
.slice(2)}`,
|
|
106
|
-
title: step.title,
|
|
107
|
-
status: inherentStatus,
|
|
108
|
-
duration: duration,
|
|
109
|
-
startTime: startTime,
|
|
110
|
-
endTime: endTime,
|
|
111
|
-
errorMessage: (_a = step.error) === null || _a === void 0 ? void 0 : _a.message,
|
|
112
|
-
screenshot: undefined, // Placeholder
|
|
113
|
-
};
|
|
114
|
-
}
|
|
115
|
-
onTestEnd(test, result) {
|
|
116
|
-
var _a, _b, _c, _d, _e;
|
|
117
|
-
const testStatus = convertStatus(result.status);
|
|
118
|
-
const startTime = new Date(result.startTime);
|
|
119
|
-
const endTime = new Date(startTime.getTime() + result.duration);
|
|
120
|
-
const processAllSteps = (steps, parentTestStatus) => {
|
|
121
|
-
let processed = [];
|
|
122
|
-
for (const step of steps) {
|
|
123
|
-
const processedStep = this.processStep(step, parentTestStatus);
|
|
124
|
-
processed.push(processedStep);
|
|
125
|
-
if (step.steps.length > 0) {
|
|
126
|
-
processed = processed.concat(processAllSteps(step.steps, processedStep.status));
|
|
127
|
-
}
|
|
128
|
-
}
|
|
129
|
-
return processed;
|
|
130
|
-
};
|
|
131
|
-
let codeSnippet = undefined;
|
|
132
|
-
try {
|
|
133
|
-
if ((_a = test.location) === null || _a === void 0 ? void 0 : _a.file) {
|
|
134
|
-
codeSnippet = `Test defined at: ${test.location.file}:${test.location.line}:${test.location.column}`;
|
|
135
|
-
}
|
|
136
|
-
}
|
|
137
|
-
catch (e) {
|
|
138
|
-
console.warn(`Pulse Reporter: Could not extract code snippet for ${test.title}`, e);
|
|
139
|
-
}
|
|
140
|
-
const pulseResult = {
|
|
141
|
-
id: test.id ||
|
|
142
|
-
`${test.title}-${startTime.toISOString()}-${Math.random()
|
|
143
|
-
.toString(16)
|
|
144
|
-
.slice(2)}`,
|
|
145
|
-
runId: "TBD",
|
|
146
|
-
name: test.titlePath().join(" > "),
|
|
147
|
-
suiteName: test.parent.title,
|
|
148
|
-
status: testStatus,
|
|
149
|
-
duration: result.duration,
|
|
150
|
-
startTime: startTime,
|
|
151
|
-
endTime: endTime,
|
|
152
|
-
retries: result.retry,
|
|
153
|
-
steps: processAllSteps(result.steps, testStatus),
|
|
154
|
-
errorMessage: (_b = result.error) === null || _b === void 0 ? void 0 : _b.message,
|
|
155
|
-
stackTrace: (_c = result.error) === null || _c === void 0 ? void 0 : _c.stack,
|
|
156
|
-
codeSnippet: codeSnippet,
|
|
157
|
-
screenshot: (_d = result.attachments.find((a) => a.name === "screenshot")) === null || _d === void 0 ? void 0 : _d.path,
|
|
158
|
-
video: (_e = result.attachments.find((a) => a.name === "video")) === null || _e === void 0 ? void 0 : _e.path,
|
|
159
|
-
tags: test.tags.map((tag) => tag.startsWith("@") ? tag.substring(1) : tag),
|
|
160
|
-
};
|
|
161
|
-
this.results.push(pulseResult);
|
|
162
|
-
}
|
|
163
|
-
onError(error) {
|
|
164
|
-
var _a;
|
|
165
|
-
console.error(`PlaywrightPulseReporter: Error encountered (Shard: ${(_a = this.shardIndex) !== null && _a !== void 0 ? _a : "Main"}):`, error);
|
|
166
|
-
}
|
|
167
|
-
async _writeShardResults() {
|
|
168
|
-
if (this.shardIndex === undefined) {
|
|
169
|
-
console.warn("Pulse Reporter: _writeShardResults called in main process. Skipping.");
|
|
170
|
-
return;
|
|
171
|
-
}
|
|
172
|
-
const tempFilePath = path.join(this.outputDir, `${TEMP_SHARD_FILE_PREFIX}${this.shardIndex}.json`);
|
|
173
|
-
try {
|
|
174
|
-
await this._ensureDirExists(this.outputDir);
|
|
175
|
-
await fs.writeFile(tempFilePath, JSON.stringify(this.results, null, 2));
|
|
176
|
-
}
|
|
177
|
-
catch (error) {
|
|
178
|
-
console.error(`Pulse Reporter: Shard ${this.shardIndex} failed to write temporary results to ${tempFilePath}`, error);
|
|
179
|
-
}
|
|
180
|
-
}
|
|
181
|
-
async _mergeShardResults(finalRunData) {
|
|
182
|
-
console.log("Pulse Reporter: Merging results from shards...");
|
|
183
|
-
let allResults = [];
|
|
184
|
-
const totalShards = parseInt(process.env.PLAYWRIGHT_SHARD_TOTAL || "1", 10);
|
|
185
|
-
for (let i = 0; i < totalShards; i++) {
|
|
186
|
-
const tempFilePath = path.join(this.outputDir, `${TEMP_SHARD_FILE_PREFIX}${i}.json`);
|
|
187
|
-
try {
|
|
188
|
-
const content = await fs.readFile(tempFilePath, "utf-8");
|
|
189
|
-
const shardResults = JSON.parse(content);
|
|
190
|
-
shardResults.forEach((r) => (r.runId = finalRunData.id));
|
|
191
|
-
allResults = allResults.concat(shardResults);
|
|
192
|
-
}
|
|
193
|
-
catch (error) {
|
|
194
|
-
if (error && error.code === "ENOENT") {
|
|
195
|
-
console.warn(`Pulse Reporter: Shard results file not found: ${tempFilePath}.`);
|
|
196
|
-
}
|
|
197
|
-
else {
|
|
198
|
-
console.warn(`Pulse Reporter: Could not read or parse results from shard ${i} (${tempFilePath}). Error: ${error}`);
|
|
199
|
-
}
|
|
200
|
-
}
|
|
201
|
-
}
|
|
202
|
-
console.log(`Pulse Reporter: Merged a total of ${allResults.length} results from ${totalShards} shards.`);
|
|
203
|
-
finalRunData.passed = allResults.filter((r) => r.status === "passed").length;
|
|
204
|
-
finalRunData.failed = allResults.filter((r) => r.status === "failed").length;
|
|
205
|
-
finalRunData.skipped = allResults.filter((r) => r.status === "skipped").length;
|
|
206
|
-
finalRunData.totalTests = allResults.length;
|
|
207
|
-
return {
|
|
208
|
-
run: finalRunData,
|
|
209
|
-
results: allResults,
|
|
210
|
-
metadata: { generatedAt: new Date().toISOString() },
|
|
211
|
-
};
|
|
212
|
-
}
|
|
213
|
-
async _cleanupTemporaryFiles() {
|
|
214
|
-
try {
|
|
215
|
-
await this._ensureDirExists(this.outputDir);
|
|
216
|
-
const files = await fs.readdir(this.outputDir);
|
|
217
|
-
const tempFiles = files.filter((f) => f.startsWith(TEMP_SHARD_FILE_PREFIX));
|
|
218
|
-
if (tempFiles.length > 0) {
|
|
219
|
-
console.log(`Pulse Reporter: Cleaning up ${tempFiles.length} temporary shard files...`);
|
|
220
|
-
await Promise.all(tempFiles.map((f) => fs.unlink(path.join(this.outputDir, f))));
|
|
221
|
-
}
|
|
222
|
-
}
|
|
223
|
-
catch (error) {
|
|
224
|
-
if (error && error.code !== "ENOENT") {
|
|
225
|
-
console.error("Pulse Reporter: Error cleaning up temporary files:", error);
|
|
226
|
-
}
|
|
227
|
-
}
|
|
228
|
-
}
|
|
229
|
-
async _ensureDirExists(dirPath) {
|
|
230
|
-
try {
|
|
231
|
-
await fs.mkdir(dirPath, { recursive: true });
|
|
232
|
-
}
|
|
233
|
-
catch (error) {
|
|
234
|
-
if (error && error.code !== "EEXIST") {
|
|
235
|
-
console.error(`Pulse Reporter: Failed to ensure directory exists: ${dirPath}`, error);
|
|
236
|
-
throw error;
|
|
237
|
-
}
|
|
238
|
-
}
|
|
239
|
-
}
|
|
240
|
-
async onEnd(result) {
|
|
241
|
-
var _a, _b, _c, _d, _e, _f;
|
|
242
|
-
if (this.shardIndex !== undefined) {
|
|
243
|
-
await this._writeShardResults();
|
|
244
|
-
console.log(`PlaywrightPulseReporter: Shard ${this.shardIndex + 1} finished.`);
|
|
245
|
-
return;
|
|
246
|
-
}
|
|
247
|
-
const runEndTime = Date.now();
|
|
248
|
-
const duration = runEndTime - this.runStartTime;
|
|
249
|
-
const runId = `run-${this.runStartTime}-${Math.random()
|
|
250
|
-
.toString(16)
|
|
251
|
-
.slice(2)}`;
|
|
252
|
-
const runData = {
|
|
253
|
-
id: runId,
|
|
254
|
-
timestamp: new Date(this.runStartTime),
|
|
255
|
-
totalTests: 0,
|
|
256
|
-
passed: 0,
|
|
257
|
-
failed: 0,
|
|
258
|
-
skipped: 0,
|
|
259
|
-
duration,
|
|
260
|
-
};
|
|
261
|
-
let finalReport;
|
|
262
|
-
if (this.isSharded) {
|
|
263
|
-
finalReport = await this._mergeShardResults(runData);
|
|
264
|
-
}
|
|
265
|
-
else {
|
|
266
|
-
this.results.forEach((r) => (r.runId = runId));
|
|
267
|
-
runData.passed = this.results.filter((r) => r.status === "passed").length;
|
|
268
|
-
runData.failed = this.results.filter((r) => r.status === "failed").length;
|
|
269
|
-
runData.skipped = this.results.filter((r) => r.status === "skipped").length;
|
|
270
|
-
runData.totalTests = this.results.length;
|
|
271
|
-
finalReport = {
|
|
272
|
-
run: runData,
|
|
273
|
-
results: this.results,
|
|
274
|
-
metadata: { generatedAt: new Date().toISOString() },
|
|
275
|
-
};
|
|
276
|
-
}
|
|
277
|
-
const finalRunStatus = ((_b = (_a = finalReport.run) === null || _a === void 0 ? void 0 : _a.failed) !== null && _b !== void 0 ? _b : 0 > 0) ? "failed" : "passed";
|
|
278
|
-
console.log(`PlaywrightPulseReporter: Test run finished with overall status: ${finalRunStatus}`);
|
|
279
|
-
console.log(` Passed: ${(_c = finalReport.run) === null || _c === void 0 ? void 0 : _c.passed}, Failed: ${(_d = finalReport.run) === null || _d === void 0 ? void 0 : _d.failed}, Skipped: ${(_e = finalReport.run) === null || _e === void 0 ? void 0 : _e.skipped}`);
|
|
280
|
-
console.log(` Total tests: ${(_f = finalReport.run) === null || _f === void 0 ? void 0 : _f.totalTests}`);
|
|
281
|
-
console.log(` Total time: ${(duration / 1000).toFixed(2)}s`);
|
|
282
|
-
const finalOutputPath = path.join(this.outputDir, this.baseOutputFile);
|
|
283
|
-
try {
|
|
284
|
-
await this._ensureDirExists(this.outputDir);
|
|
285
|
-
await fs.writeFile(finalOutputPath, JSON.stringify(finalReport, (key, value) => {
|
|
286
|
-
if (value instanceof Date) {
|
|
287
|
-
return value.toISOString();
|
|
288
|
-
}
|
|
289
|
-
return value;
|
|
290
|
-
}, 2));
|
|
291
|
-
console.log(`PlaywrightPulseReporter: Final report written to ${finalOutputPath}`);
|
|
292
|
-
}
|
|
293
|
-
catch (error) {
|
|
294
|
-
console.error(`PlaywrightPulseReporter: Failed to write final report to ${finalOutputPath}`, error);
|
|
295
|
-
}
|
|
296
|
-
finally {
|
|
297
|
-
if (this.isSharded) {
|
|
298
|
-
await this._cleanupTemporaryFiles();
|
|
299
|
-
}
|
|
300
|
-
}
|
|
301
|
-
}
|
|
302
|
-
}
|
|
303
|
-
exports.PlaywrightPulseReporter = PlaywrightPulseReporter;
|
|
304
|
-
// No module.exports needed for ES modules
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|