@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.
@@ -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.39",
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.js",
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.js",
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 { getOutputDir } from "./config-reader.mjs";
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 outputDir = await getOutputDir(customOutputDir);
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, DEFAULT_JSON_FILE);
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 { getOutputDir } from "./config-reader.mjs";
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 outputDir = await getOutputDir(customOutputDir);
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, DEFAULT_JSON_FILE); // Current run's main JSON
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 { getOutputDir } from "./config-reader.mjs";
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 outputDir = await getOutputDir(customOutputDir);
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, DEFAULT_JSON_FILE); // Current run's main JSON
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 { getOutputDir } from "./config-reader.mjs";
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 outputDir = await getOutputDir(customOutputDir);
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, CURRENT_RUN_JSON_FILE);
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
- const fs = require("fs");
4
- const path = require("path");
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 getReportDir() {
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
- try {
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, OUTPUT_FILE);
72
+ const jsonPath = path.join(shardDir, outputFile);
80
73
 
81
74
  if (!fs.existsSync(jsonPath)) {
82
- console.warn(` Warning: No ${OUTPUT_FILE} found in ${path.basename(shardDir)}`);
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 REPORT_DIR = await getReportDir();
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
- " Expected structure: <report-dir>/<shard-folder>/playwright-pulse-report.json",
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
 
@@ -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 { getOutputDir } from "./config-reader.mjs";
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 reportPath = path.join(reportDir, "playwright-pulse-report.json");
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 reportPath = path.join(reportDir, "playwright-pulse-report.json");
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 reportData = getPulseReportSummary(reportDir);
291
- const htmlContent = generateHtmlTable(reportData);
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 || "",