@arghajit/dummy 0.3.39 → 0.3.40
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/reporter/playwright-pulse-reporter.d.ts +0 -1
- package/dist/reporter/playwright-pulse-reporter.js +0 -26
- package/package.json +3 -3
- package/scripts/generate-email-report.mjs +6 -4
- package/scripts/generate-report.mjs +6 -4
- package/scripts/generate-static-report.mjs +6 -13
- package/scripts/generate-trend.mjs +6 -4
- package/scripts/{merge-pulse-report.js → merge-pulse-report.mjs} +21 -26
- package/scripts/sendReport.mjs +12 -7
|
@@ -44,7 +44,6 @@ export declare class PlaywrightPulseReporter implements Reporter {
|
|
|
44
44
|
*
|
|
45
45
|
* Cleaning up at `onBegin` time guarantees each run starts with a fresh slate.
|
|
46
46
|
*/
|
|
47
|
-
private _cleanupStaleRunReports;
|
|
48
47
|
private _ensureDirExists;
|
|
49
48
|
onEnd(result: FullResult): Promise<void>;
|
|
50
49
|
}
|
|
@@ -109,13 +109,6 @@ class PlaywrightPulseReporter {
|
|
|
109
109
|
await this._cleanupTemporaryFiles();
|
|
110
110
|
}
|
|
111
111
|
}
|
|
112
|
-
// When not resetting on each run, clear stale individual run files
|
|
113
|
-
// from previous sessions. Without this, _mergeAllRunReports() reads
|
|
114
|
-
// ALL accumulated files and de-duplicates by test.id, which collapses
|
|
115
|
-
// results from different sessions into fewer entries than expected.
|
|
116
|
-
if (!this.resetOnEachRun) {
|
|
117
|
-
await this._cleanupStaleRunReports();
|
|
118
|
-
}
|
|
119
112
|
})
|
|
120
113
|
.catch((err) => console.error("Pulse Reporter: Error during initialization:", err));
|
|
121
114
|
}
|
|
@@ -524,25 +517,6 @@ class PlaywrightPulseReporter {
|
|
|
524
517
|
*
|
|
525
518
|
* Cleaning up at `onBegin` time guarantees each run starts with a fresh slate.
|
|
526
519
|
*/
|
|
527
|
-
async _cleanupStaleRunReports() {
|
|
528
|
-
const pulseResultsDir = path.join(this.outputDir, this.individualReportsSubDir);
|
|
529
|
-
try {
|
|
530
|
-
const files = await fs.readdir(pulseResultsDir);
|
|
531
|
-
const staleFiles = files.filter((f) => f.startsWith("playwright-pulse-report-") && f.endsWith(".json"));
|
|
532
|
-
if (staleFiles.length > 0) {
|
|
533
|
-
await Promise.all(staleFiles.map((f) => fs.unlink(path.join(pulseResultsDir, f))));
|
|
534
|
-
if (this.printsToStdio()) {
|
|
535
|
-
console.log(`PlaywrightPulseReporter: Cleaned up ${staleFiles.length} stale run report(s) from ${pulseResultsDir}`);
|
|
536
|
-
}
|
|
537
|
-
}
|
|
538
|
-
}
|
|
539
|
-
catch (error) {
|
|
540
|
-
// ENOENT simply means no previous runs exist — that's fine
|
|
541
|
-
if ((error === null || error === void 0 ? void 0 : error.code) !== "ENOENT") {
|
|
542
|
-
console.warn("Pulse Reporter: Warning during cleanup of stale run reports:", error.message);
|
|
543
|
-
}
|
|
544
|
-
}
|
|
545
|
-
}
|
|
546
520
|
async _ensureDirExists(dirPath) {
|
|
547
521
|
try {
|
|
548
522
|
await fs.mkdir(dirPath, { recursive: true });
|
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.40",
|
|
5
5
|
"description": "A Playwright reporter and dashboard for visualizing test results.",
|
|
6
6
|
"homepage": "https://arghajit47.github.io/playwright-pulse/",
|
|
7
7
|
"repository": {
|
|
@@ -38,7 +38,7 @@
|
|
|
38
38
|
"logo": "node scripts/terminal-logo.mjs",
|
|
39
39
|
"generate-pulse-report": "scripts/generate-static-report.mjs",
|
|
40
40
|
"generate-report": "scripts/generate-report.mjs",
|
|
41
|
-
"merge-pulse-report": "scripts/merge-pulse-report.
|
|
41
|
+
"merge-pulse-report": "scripts/merge-pulse-report.mjs",
|
|
42
42
|
"send-email": "scripts/sendReport.mjs",
|
|
43
43
|
"generate-email-report": "scripts/generate-email-report.mjs",
|
|
44
44
|
"generate-trend": "scripts/generate-trend.mjs",
|
|
@@ -56,7 +56,7 @@
|
|
|
56
56
|
"prepublishOnly": "npm run build:reporter",
|
|
57
57
|
"report:static": "node ./scripts/generate-static-report.mjs",
|
|
58
58
|
"report:generate": "node ./scripts/generate-report.mjs",
|
|
59
|
-
"report:merge": "node ./scripts/merge-pulse-report.
|
|
59
|
+
"report:merge": "node ./scripts/merge-pulse-report.mjs",
|
|
60
60
|
"report:email": "node ./scripts/sendReport.mjs",
|
|
61
61
|
"report:minify": "node ./scripts/generate-email-report.mjs",
|
|
62
62
|
"generate-trend": "node ./scripts/generate-trend.mjs"
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
import * as fs from "fs/promises";
|
|
4
4
|
import path from "path";
|
|
5
|
-
import {
|
|
5
|
+
import { getReporterConfig } from "./config-reader.mjs";
|
|
6
6
|
import { animate } from "./terminal-logo.mjs";
|
|
7
7
|
import { mergeSequentialReportsIfNeeded } from "./merge-sequential-reports.mjs";
|
|
8
8
|
|
|
@@ -25,7 +25,6 @@ try {
|
|
|
25
25
|
}
|
|
26
26
|
|
|
27
27
|
const DEFAULT_OUTPUT_DIR = "pulse-report";
|
|
28
|
-
const DEFAULT_JSON_FILE = "playwright-pulse-report.json";
|
|
29
28
|
const MINIFIED_HTML_FILE = "pulse-email-summary.html"; // New minified report
|
|
30
29
|
|
|
31
30
|
const args = process.argv.slice(2);
|
|
@@ -758,9 +757,12 @@ async function main() {
|
|
|
758
757
|
await animate();
|
|
759
758
|
}
|
|
760
759
|
|
|
761
|
-
const
|
|
760
|
+
const config = await getReporterConfig(customOutputDir);
|
|
761
|
+
const outputDir = config.outputDir;
|
|
762
|
+
const outputFile = config.outputFile;
|
|
763
|
+
|
|
762
764
|
await mergeSequentialReportsIfNeeded(outputDir);
|
|
763
|
-
const reportJsonPath = path.resolve(outputDir,
|
|
765
|
+
const reportJsonPath = path.resolve(outputDir, outputFile);
|
|
764
766
|
const minifiedReportHtmlPath = path.resolve(outputDir, MINIFIED_HTML_FILE); // Path for the new minified HTML
|
|
765
767
|
|
|
766
768
|
console.log(chalk.blue(`Generating email report...`));
|
|
@@ -5,7 +5,7 @@ import { readFileSync, existsSync as fsExistsSync } from "fs";
|
|
|
5
5
|
import path from "path";
|
|
6
6
|
import { fork } from "child_process";
|
|
7
7
|
import { fileURLToPath } from "url";
|
|
8
|
-
import {
|
|
8
|
+
import { getReporterConfig } from "./config-reader.mjs";
|
|
9
9
|
import { animate } from "./terminal-logo.mjs";
|
|
10
10
|
import { mergeSequentialReportsIfNeeded } from "./merge-sequential-reports.mjs";
|
|
11
11
|
|
|
@@ -53,7 +53,6 @@ try {
|
|
|
53
53
|
}
|
|
54
54
|
// Default configuration
|
|
55
55
|
const DEFAULT_OUTPUT_DIR = "pulse-report";
|
|
56
|
-
const DEFAULT_JSON_FILE = "playwright-pulse-report.json";
|
|
57
56
|
const DEFAULT_HTML_FILE = "playwright-pulse-report.html";
|
|
58
57
|
// Helper functions
|
|
59
58
|
export function ansiToHtml(text) {
|
|
@@ -5298,9 +5297,12 @@ async function main() {
|
|
|
5298
5297
|
"generate-trend.mjs", // Keeping the filename as per your request
|
|
5299
5298
|
);
|
|
5300
5299
|
|
|
5301
|
-
const
|
|
5300
|
+
const config = await getReporterConfig(customOutputDir);
|
|
5301
|
+
const outputDir = config.outputDir;
|
|
5302
|
+
const outputFile = config.outputFile;
|
|
5303
|
+
|
|
5302
5304
|
await mergeSequentialReportsIfNeeded(outputDir);
|
|
5303
|
-
const reportJsonPath = path.resolve(outputDir,
|
|
5305
|
+
const reportJsonPath = path.resolve(outputDir, outputFile); // Current run's main JSON
|
|
5304
5306
|
const reportHtmlPath = path.resolve(outputDir, DEFAULT_HTML_FILE);
|
|
5305
5307
|
|
|
5306
5308
|
const historyDir = path.join(outputDir, "history"); // Directory for historical JSON files
|
|
@@ -5,7 +5,7 @@ import { readFileSync, existsSync as fsExistsSync } from "fs";
|
|
|
5
5
|
import path from "path";
|
|
6
6
|
import { fork } from "child_process";
|
|
7
7
|
import { fileURLToPath } from "url";
|
|
8
|
-
import {
|
|
8
|
+
import { getReporterConfig } from "./config-reader.mjs";
|
|
9
9
|
import { animate } from "./terminal-logo.mjs";
|
|
10
10
|
import { mergeSequentialReportsIfNeeded } from "./merge-sequential-reports.mjs";
|
|
11
11
|
|
|
@@ -56,18 +56,8 @@ try {
|
|
|
56
56
|
};
|
|
57
57
|
}
|
|
58
58
|
|
|
59
|
-
/**
|
|
60
|
-
* @constant {string} DEFAULT_OUTPUT_DIR
|
|
61
|
-
* The default directory where the report will be generated.
|
|
62
|
-
*/
|
|
63
59
|
const DEFAULT_OUTPUT_DIR = "pulse-report";
|
|
64
60
|
|
|
65
|
-
/**
|
|
66
|
-
* @constant {string} DEFAULT_JSON_FILE
|
|
67
|
-
* The default name for the JSON file containing the test data.
|
|
68
|
-
*/
|
|
69
|
-
const DEFAULT_JSON_FILE = "playwright-pulse-report.json";
|
|
70
|
-
|
|
71
61
|
/**
|
|
72
62
|
* @constant {string} DEFAULT_HTML_FILE
|
|
73
63
|
* The default name for the generated HTML report file.
|
|
@@ -7163,9 +7153,12 @@ async function main() {
|
|
|
7163
7153
|
"generate-trend.mjs", // Keeping the filename as per your request
|
|
7164
7154
|
);
|
|
7165
7155
|
|
|
7166
|
-
const
|
|
7156
|
+
const config = await getReporterConfig(customOutputDir);
|
|
7157
|
+
const outputDir = config.outputDir;
|
|
7158
|
+
const outputFile = config.outputFile;
|
|
7159
|
+
|
|
7167
7160
|
await mergeSequentialReportsIfNeeded(outputDir);
|
|
7168
|
-
const reportJsonPath = path.resolve(outputDir,
|
|
7161
|
+
const reportJsonPath = path.resolve(outputDir, outputFile); // Current run's main JSON
|
|
7169
7162
|
const reportHtmlPath = path.resolve(outputDir, DEFAULT_HTML_FILE);
|
|
7170
7163
|
|
|
7171
7164
|
const historyDir = path.join(outputDir, "history"); // Directory for historical JSON files
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import * as fs from "fs/promises";
|
|
3
3
|
import path from "path";
|
|
4
|
-
import {
|
|
4
|
+
import { getReporterConfig } from "./config-reader.mjs";
|
|
5
5
|
import { mergeSequentialReportsIfNeeded } from "./merge-sequential-reports.mjs";
|
|
6
6
|
|
|
7
7
|
// Use dynamic import for chalk as it's ESM only for prettier console logs
|
|
@@ -19,7 +19,6 @@ try {
|
|
|
19
19
|
}
|
|
20
20
|
|
|
21
21
|
const DEFAULT_OUTPUT_DIR = "pulse-report";
|
|
22
|
-
const CURRENT_RUN_JSON_FILE = "playwright-pulse-report.json"; // Source of the current run data
|
|
23
22
|
const HISTORY_SUBDIR = "history"; // Subdirectory for historical JSON files
|
|
24
23
|
const HISTORY_FILE_PREFIX = "trend-";
|
|
25
24
|
const MAX_HISTORY_FILES = 15; // Store last 15 runs
|
|
@@ -34,9 +33,12 @@ for (let i = 0; i < args.length; i++) {
|
|
|
34
33
|
}
|
|
35
34
|
|
|
36
35
|
async function archiveCurrentRunData() {
|
|
37
|
-
const
|
|
36
|
+
const config = await getReporterConfig(customOutputDir);
|
|
37
|
+
const outputDir = config.outputDir;
|
|
38
|
+
const outputFile = config.outputFile;
|
|
39
|
+
|
|
38
40
|
await mergeSequentialReportsIfNeeded(outputDir);
|
|
39
|
-
const currentRunJsonPath = path.join(outputDir,
|
|
41
|
+
const currentRunJsonPath = path.join(outputDir, outputFile);
|
|
40
42
|
const historyDir = path.join(outputDir, HISTORY_SUBDIR);
|
|
41
43
|
|
|
42
44
|
try {
|
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
3
|
+
import * as fs from "fs";
|
|
4
|
+
import path from "path";
|
|
5
|
+
import { getReporterConfig } from "./config-reader.mjs";
|
|
6
|
+
import { animate } from "./terminal-logo.mjs";
|
|
7
|
+
import { mergeSequentialReportsIfNeeded } from "./merge-sequential-reports.mjs";
|
|
5
8
|
|
|
6
9
|
const args = process.argv.slice(2);
|
|
7
10
|
let customOutputDir = null;
|
|
@@ -13,33 +16,23 @@ for (let i = 0; i < args.length; i++) {
|
|
|
13
16
|
}
|
|
14
17
|
}
|
|
15
18
|
|
|
16
|
-
const OUTPUT_FILE = "playwright-pulse-report.json";
|
|
17
|
-
|
|
18
19
|
/**
|
|
19
|
-
* Securely resolves the report directory.
|
|
20
|
-
* Prevents Path Traversal by ensuring the output directory
|
|
21
|
-
* is contained within the current working directory.
|
|
20
|
+
* Securely resolves the report directory and config.
|
|
22
21
|
*/
|
|
23
|
-
async function
|
|
22
|
+
async function getFullConfig() {
|
|
23
|
+
const config = await getReporterConfig(customOutputDir);
|
|
24
|
+
|
|
24
25
|
if (customOutputDir) {
|
|
25
26
|
const resolvedPath = path.resolve(process.cwd(), customOutputDir);
|
|
26
|
-
|
|
27
27
|
if (!resolvedPath.startsWith(process.cwd())) {
|
|
28
28
|
console.error(
|
|
29
29
|
"⛔ Security Error: Custom output directory must be within the current project root.",
|
|
30
30
|
);
|
|
31
31
|
process.exit(1);
|
|
32
32
|
}
|
|
33
|
-
|
|
34
|
-
return resolvedPath;
|
|
35
33
|
}
|
|
36
34
|
|
|
37
|
-
|
|
38
|
-
const { getOutputDir } = await import("./config-reader.mjs");
|
|
39
|
-
return await getOutputDir();
|
|
40
|
-
} catch (error) {
|
|
41
|
-
return path.resolve(process.cwd(), "pulse-report");
|
|
42
|
-
}
|
|
35
|
+
return config;
|
|
43
36
|
}
|
|
44
37
|
|
|
45
38
|
/**
|
|
@@ -54,14 +47,14 @@ function getShardDirectories(dir) {
|
|
|
54
47
|
|
|
55
48
|
return fs
|
|
56
49
|
.readdirSync(dir, { withFileTypes: true })
|
|
57
|
-
.filter((dirent) => dirent.isDirectory() && dirent.name !== "attachments")
|
|
50
|
+
.filter((dirent) => dirent.isDirectory() && dirent.name !== "attachments" && dirent.name !== "pulse-results")
|
|
58
51
|
.map((dirent) => path.join(dir, dirent.name));
|
|
59
52
|
}
|
|
60
53
|
|
|
61
54
|
/**
|
|
62
55
|
* Merges JSON reports from all shard directories.
|
|
63
56
|
*/
|
|
64
|
-
function mergeReports(shardDirs) {
|
|
57
|
+
function mergeReports(shardDirs, outputFile) {
|
|
65
58
|
let combinedRun = {
|
|
66
59
|
totalTests: 0,
|
|
67
60
|
passed: 0,
|
|
@@ -76,10 +69,10 @@ function mergeReports(shardDirs) {
|
|
|
76
69
|
let allEnvironments = [];
|
|
77
70
|
|
|
78
71
|
for (const shardDir of shardDirs) {
|
|
79
|
-
const jsonPath = path.join(shardDir,
|
|
72
|
+
const jsonPath = path.join(shardDir, outputFile);
|
|
80
73
|
|
|
81
74
|
if (!fs.existsSync(jsonPath)) {
|
|
82
|
-
console.warn(` Warning: No ${
|
|
75
|
+
console.warn(` Warning: No ${outputFile} found in ${path.basename(shardDir)}`);
|
|
83
76
|
continue;
|
|
84
77
|
}
|
|
85
78
|
|
|
@@ -181,15 +174,17 @@ function cleanupShardDirectories(shardDirs) {
|
|
|
181
174
|
|
|
182
175
|
// Main execution
|
|
183
176
|
(async () => {
|
|
184
|
-
const { animate } = await import("./terminal-logo.mjs");
|
|
185
|
-
const { mergeSequentialReportsIfNeeded } = await import("./merge-sequential-reports.mjs");
|
|
186
177
|
await animate();
|
|
187
178
|
|
|
188
|
-
const
|
|
179
|
+
const config = await getFullConfig();
|
|
180
|
+
const REPORT_DIR = config.outputDir;
|
|
181
|
+
const OUTPUT_FILE = config.outputFile;
|
|
182
|
+
|
|
189
183
|
await mergeSequentialReportsIfNeeded(REPORT_DIR);
|
|
190
184
|
|
|
191
185
|
console.log(`\n🔄 Playwright Pulse - Merge Reports (Sharding Mode)\n`);
|
|
192
186
|
console.log(` Report directory: ${REPORT_DIR}`);
|
|
187
|
+
console.log(` Output file: ${OUTPUT_FILE}`);
|
|
193
188
|
if (customOutputDir) {
|
|
194
189
|
console.log(` (from CLI argument)`);
|
|
195
190
|
} else {
|
|
@@ -203,7 +198,7 @@ function cleanupShardDirectories(shardDirs) {
|
|
|
203
198
|
if (shardDirs.length === 0) {
|
|
204
199
|
console.log("❌ No shard directories found.");
|
|
205
200
|
console.log(
|
|
206
|
-
|
|
201
|
+
` Expected structure: <report-dir>/<shard-folder>/${OUTPUT_FILE}`,
|
|
207
202
|
);
|
|
208
203
|
process.exit(0);
|
|
209
204
|
}
|
|
@@ -216,7 +211,7 @@ function cleanupShardDirectories(shardDirs) {
|
|
|
216
211
|
|
|
217
212
|
// 2. Merge JSON Reports
|
|
218
213
|
console.log(`🔀 Merging reports...`);
|
|
219
|
-
const merged = mergeReports(shardDirs);
|
|
214
|
+
const merged = mergeReports(shardDirs, OUTPUT_FILE);
|
|
220
215
|
console.log(` ✓ Merged ${shardDirs.length} report(s)`);
|
|
221
216
|
console.log();
|
|
222
217
|
|
package/scripts/sendReport.mjs
CHANGED
|
@@ -11,7 +11,7 @@ import { fileURLToPath } from "url";
|
|
|
11
11
|
import { animate } from "./terminal-logo.mjs";
|
|
12
12
|
import { fork } from "child_process";
|
|
13
13
|
import "dotenv/config";
|
|
14
|
-
import {
|
|
14
|
+
import { getReporterConfig } from "./config-reader.mjs";
|
|
15
15
|
import { mergeSequentialReportsIfNeeded } from "./merge-sequential-reports.mjs";
|
|
16
16
|
|
|
17
17
|
let chalk;
|
|
@@ -43,8 +43,10 @@ for (let i = 0; i < args.length; i++) {
|
|
|
43
43
|
let fetch;
|
|
44
44
|
let projectName;
|
|
45
45
|
|
|
46
|
-
function getUUID(reportDir) {
|
|
47
|
-
const
|
|
46
|
+
async function getUUID(reportDir) {
|
|
47
|
+
const config = await getReporterConfig(customOutputDir);
|
|
48
|
+
const outputFile = config.outputFile;
|
|
49
|
+
const reportPath = path.join(reportDir, outputFile);
|
|
48
50
|
console.log("Report path:", reportPath);
|
|
49
51
|
|
|
50
52
|
if (!fsExistsSync(reportPath)) {
|
|
@@ -66,8 +68,10 @@ function formatDuration(ms) {
|
|
|
66
68
|
return `${(ms / 3600000).toFixed(1)}h`;
|
|
67
69
|
}
|
|
68
70
|
|
|
69
|
-
const getPulseReportSummary = (reportDir) => {
|
|
70
|
-
const
|
|
71
|
+
const getPulseReportSummary = async (reportDir) => {
|
|
72
|
+
const config = await getReporterConfig(customOutputDir);
|
|
73
|
+
const outputFile = config.outputFile;
|
|
74
|
+
const reportPath = path.join(reportDir, outputFile);
|
|
71
75
|
|
|
72
76
|
if (!fsExistsSync(reportPath)) {
|
|
73
77
|
throw new Error("Pulse report file not found.");
|
|
@@ -287,8 +291,9 @@ const sendEmail = async (credentials, reportDir) => {
|
|
|
287
291
|
|
|
288
292
|
try {
|
|
289
293
|
console.log("Starting the sendEmail function...");
|
|
290
|
-
const
|
|
291
|
-
const
|
|
294
|
+
const uuid = await getUUID(reportDir);
|
|
295
|
+
const summary = await getPulseReportSummary(reportDir);
|
|
296
|
+
const htmlContent = generateHtmlTable(summary);
|
|
292
297
|
|
|
293
298
|
const recipients = [
|
|
294
299
|
process.env.RECIPIENT_EMAIL_1 || "",
|