@arghajit/dummy 0.1.0-beta-18 → 0.1.0-beta-19

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.
@@ -45,11 +45,10 @@ const ATTACHMENTS_SUBDIR = "attachments"; // Consistent subdirectory name
45
45
  * @param config The reporter configuration options.
46
46
  */
47
47
  function attachFiles(testId, pwResult, pulseResult, config) {
48
- const baseReportDir = config.outputDir || "pulse-report"; // Base output directory
49
- // Ensure attachments are relative to the main outputDir
50
- const attachmentsBaseDir = path.resolve(baseReportDir, ATTACHMENTS_SUBDIR); // Absolute path for FS operations
51
- const attachmentsSubFolder = testId.replace(/[^a-zA-Z0-9_-]/g, "_"); // Sanitize testId for folder name
52
- const testAttachmentsDir = path.join(attachmentsBaseDir, attachmentsSubFolder); // e.g., pulse-report/attachments/test_id_abc
48
+ const baseReportDir = config.outputDir || "pulse-report";
49
+ const attachmentsBaseDir = path.resolve(baseReportDir, ATTACHMENTS_SUBDIR);
50
+ const attachmentsSubFolder = testId.replace(/[^a-zA-Z0-9_-]/g, "_");
51
+ const testAttachmentsDir = path.join(attachmentsBaseDir, attachmentsSubFolder);
53
52
  try {
54
53
  if (!fs.existsSync(testAttachmentsDir)) {
55
54
  fs.mkdirSync(testAttachmentsDir, { recursive: true });
@@ -57,53 +56,49 @@ function attachFiles(testId, pwResult, pulseResult, config) {
57
56
  }
58
57
  catch (error) {
59
58
  console.error(`Pulse Reporter: Failed to create attachments directory: ${testAttachmentsDir}`, error);
60
- return; // Stop processing if directory creation fails
59
+ return;
61
60
  }
62
61
  if (!pwResult.attachments)
63
62
  return;
64
- const { base64Images } = config; // Get base64 embedding option
65
- pulseResult.screenshots = []; // Initialize screenshots array
63
+ const { base64Images } = config;
64
+ // --- MODIFICATION: Initialize all attachment arrays to prevent errors ---
65
+ pulseResult.screenshots = [];
66
+ pulseResult.videoPath = [];
67
+ pulseResult.attachments = [];
66
68
  pwResult.attachments.forEach((attachment) => {
67
69
  const { contentType, name, path: attachmentPath, body } = attachment;
68
- // Skip attachments without path or body
69
70
  if (!attachmentPath && !body) {
70
71
  console.warn(`Pulse Reporter: Attachment "${name}" for test ${testId} has no path or body. Skipping.`);
71
72
  return;
72
73
  }
73
- // Determine filename
74
- const safeName = name.replace(/[^a-zA-Z0-9_.-]/g, "_"); // Sanitize original name
74
+ const safeName = name.replace(/[^a-zA-Z0-9_.-]/g, "_");
75
75
  const extension = attachmentPath
76
76
  ? path.extname(attachmentPath)
77
77
  : `.${getFileExtension(contentType)}`;
78
78
  const baseFilename = attachmentPath
79
79
  ? path.basename(attachmentPath, extension)
80
80
  : safeName;
81
- // Ensure unique filename within the test's attachment folder
82
81
  const fileName = `${baseFilename}_${Date.now()}${extension}`;
83
- // Relative path for storing in JSON (relative to baseReportDir)
84
82
  const relativePath = path.join(ATTACHMENTS_SUBDIR, attachmentsSubFolder, fileName);
85
- // Full path for file system operations
86
83
  const fullPath = path.join(testAttachmentsDir, fileName);
87
84
  if (contentType === null || contentType === void 0 ? void 0 : contentType.startsWith("image/")) {
88
- // Handle all image types consistently
89
85
  handleImage(attachmentPath, body, base64Images, fullPath, relativePath, pulseResult, name);
90
86
  }
91
87
  else if (name === "video" || (contentType === null || contentType === void 0 ? void 0 : contentType.startsWith("video/"))) {
92
- handleAttachment(attachmentPath, body, fullPath, relativePath, "videoPath", pulseResult);
88
+ handleAttachment(attachmentPath, body, fullPath, relativePath, "videoPath", pulseResult, attachment);
93
89
  }
94
90
  else if (name === "trace" || contentType === "application/zip") {
95
- // Trace files are zips
96
- handleAttachment(attachmentPath, body, fullPath, relativePath, "tracePath", pulseResult);
91
+ handleAttachment(attachmentPath, body, fullPath, relativePath, "tracePath", pulseResult, attachment);
97
92
  }
98
93
  else {
99
- // Handle other generic attachments if needed (e.g., log files)
100
- // console.log(`Pulse Reporter: Processing generic attachment "${name}" (Type: ${contentType}) for test ${testId}`);
101
- // handleAttachment(attachmentPath, body, fullPath, relativePath, 'otherAttachments', pulseResult); // Example for storing other types
94
+ // --- MODIFICATION: Enabled handling for all other file types ---
95
+ handleAttachment(attachmentPath, body, fullPath, relativePath, "attachments", pulseResult, attachment);
102
96
  }
103
97
  });
104
98
  }
105
99
  /**
106
100
  * Handles image attachments, either embedding as base64 or copying the file.
101
+ * (This function is unchanged)
107
102
  */
108
103
  function handleImage(attachmentPath, body, base64Embed, fullPath, relativePath, pulseResult, attachmentName) {
109
104
  let screenshotData = undefined;
@@ -123,14 +118,10 @@ function handleImage(attachmentPath, body, base64Embed, fullPath, relativePath,
123
118
  }
124
119
  }
125
120
  else if (body) {
126
- // Always embed if only body is available
127
121
  screenshotData = `data:image/${getFileExtension(attachmentName)};base64,${body.toString("base64")}`;
128
122
  if (!base64Embed) {
129
- // Optionally save the buffer to a file even if embedding is off,
130
- // but the primary representation will be base64.
131
123
  try {
132
124
  fs.writeFileSync(fullPath, body);
133
- // console.log(`Pulse Reporter: Saved screenshot buffer to ${fullPath}`);
134
125
  }
135
126
  catch (error) {
136
127
  console.error(`Pulse Reporter: Failed to save screenshot buffer: ${fullPath}. Error: ${error.message}`);
@@ -147,21 +138,36 @@ function handleImage(attachmentPath, body, base64Embed, fullPath, relativePath,
147
138
  /**
148
139
  * Handles non-image attachments by copying the file or writing the buffer.
149
140
  */
150
- function handleAttachment(attachmentPath, body, fullPath, relativePath, resultKey, // Add more keys if needed
151
- pulseResult) {
141
+ function handleAttachment(attachmentPath, body, fullPath, relativePath, resultKey, // MODIFIED: Added 'attachments'
142
+ pulseResult, originalAttachment // MODIFIED: Pass original attachment
143
+ ) {
144
+ var _a, _b;
152
145
  try {
153
146
  if (attachmentPath) {
154
147
  fs.copyFileSync(attachmentPath, fullPath);
155
- pulseResult[resultKey] = relativePath;
156
148
  }
157
149
  else if (body) {
158
150
  fs.writeFileSync(fullPath, body);
159
- pulseResult[resultKey] = relativePath; // Store relative path even if from buffer
151
+ }
152
+ // --- MODIFICATION: Logic to handle different properties correctly ---
153
+ switch (resultKey) {
154
+ case "videoPath":
155
+ (_a = pulseResult.videoPath) === null || _a === void 0 ? void 0 : _a.push(relativePath);
156
+ break;
157
+ case "tracePath":
158
+ pulseResult.tracePath = relativePath;
159
+ break;
160
+ case "attachments":
161
+ (_b = pulseResult.attachments) === null || _b === void 0 ? void 0 : _b.push({
162
+ name: originalAttachment.name,
163
+ path: relativePath,
164
+ contentType: originalAttachment.contentType,
165
+ });
166
+ break;
160
167
  }
161
168
  }
162
169
  catch (error) {
163
170
  console.error(`Pulse Reporter: Failed to copy/write attachment to ${fullPath}. Error: ${error.message}`);
164
- // Don't set the path in pulseResult if saving failed
165
171
  }
166
172
  }
167
173
  /**
@@ -172,8 +178,7 @@ pulseResult) {
172
178
  function getFileExtension(contentType) {
173
179
  var _a;
174
180
  if (!contentType)
175
- return "bin"; // Default binary extension
176
- // More robust mapping
181
+ return "bin";
177
182
  const extensions = {
178
183
  "image/png": "png",
179
184
  "image/jpeg": "jpg",
@@ -182,9 +187,12 @@ function getFileExtension(contentType) {
182
187
  "image/svg+xml": "svg",
183
188
  "video/webm": "webm",
184
189
  "video/mp4": "mp4",
185
- "application/zip": "zip", // For traces
190
+ "application/zip": "zip",
186
191
  "text/plain": "txt",
187
192
  "application/json": "json",
193
+ "text/html": "html",
194
+ "application/pdf": "pdf",
195
+ "text/csv": "csv",
188
196
  };
189
197
  return (extensions[contentType.toLowerCase()] ||
190
198
  ((_a = contentType.split("/")[1]) === null || _a === void 0 ? void 0 : _a.split("+")[0]) ||
@@ -1,5 +1,4 @@
1
1
  "use strict";
2
- // input_file_0.ts
3
2
  var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
4
3
  if (k2 === undefined) k2 = k;
5
4
  var desc = Object.getOwnPropertyDescriptor(m, k);
@@ -38,8 +37,7 @@ exports.PlaywrightPulseReporter = void 0;
38
37
  const fs = __importStar(require("fs/promises"));
39
38
  const path = __importStar(require("path"));
40
39
  const crypto_1 = require("crypto");
41
- const attachment_utils_1 = require("./attachment-utils"); // Use relative path
42
- const ua_parser_js_1 = require("ua-parser-js"); // Added UAParser import
40
+ const ua_parser_js_1 = require("ua-parser-js");
43
41
  const os = __importStar(require("os"));
44
42
  const convertStatus = (status, testCase) => {
45
43
  if ((testCase === null || testCase === void 0 ? void 0 : testCase.expectedStatus) === "failed") {
@@ -111,8 +109,8 @@ class PlaywrightPulseReporter {
111
109
  }
112
110
  getBrowserDetails(test) {
113
111
  var _a, _b, _c, _d;
114
- const project = (_a = test.parent) === null || _a === void 0 ? void 0 : _a.project(); // project() can return undefined if not in a project context
115
- const projectConfig = project === null || project === void 0 ? void 0 : project.use; // This is where options like userAgent, defaultBrowserType are
112
+ const project = (_a = test.parent) === null || _a === void 0 ? void 0 : _a.project();
113
+ const projectConfig = project === null || project === void 0 ? void 0 : project.use;
116
114
  const userAgent = projectConfig === null || projectConfig === void 0 ? void 0 : projectConfig.userAgent;
117
115
  const configuredBrowserType = (_b = projectConfig === null || projectConfig === void 0 ? void 0 : projectConfig.browserName) === null || _b === void 0 ? void 0 : _b.toLowerCase();
118
116
  const parser = new ua_parser_js_1.UAParser(userAgent);
@@ -120,20 +118,18 @@ class PlaywrightPulseReporter {
120
118
  let browserName = result.browser.name;
121
119
  const browserVersion = result.browser.version
122
120
  ? ` v${result.browser.version.split(".")[0]}`
123
- : ""; // Major version
121
+ : "";
124
122
  const osName = result.os.name ? ` on ${result.os.name}` : "";
125
123
  const osVersion = result.os.version
126
124
  ? ` ${result.os.version.split(".")[0]}`
127
- : ""; // Major version
128
- const deviceType = result.device.type; // "mobile", "tablet", etc.
125
+ : "";
126
+ const deviceType = result.device.type;
129
127
  let finalString;
130
- // If UAParser couldn't determine browser name, fallback to configured type
131
128
  if (browserName === undefined) {
132
129
  browserName = configuredBrowserType;
133
130
  finalString = `${browserName}`;
134
131
  }
135
132
  else {
136
- // Specific refinements for mobile based on parsed OS and device type
137
133
  if (deviceType === "mobile" || deviceType === "tablet") {
138
134
  if ((_c = result.os.name) === null || _c === void 0 ? void 0 : _c.toLowerCase().includes("android")) {
139
135
  if (browserName.toLowerCase().includes("chrome"))
@@ -144,10 +140,10 @@ class PlaywrightPulseReporter {
144
140
  browserName = "Android WebView";
145
141
  else if (browserName &&
146
142
  !browserName.toLowerCase().includes("mobile")) {
147
- // Keep it as is, e.g. "Samsung Browser" is specific enough
143
+ // Keep it as is
148
144
  }
149
145
  else {
150
- browserName = "Android Browser"; // default for android if not specific
146
+ browserName = "Android Browser";
151
147
  }
152
148
  }
153
149
  else if ((_d = result.os.name) === null || _d === void 0 ? void 0 : _d.toLowerCase().includes("ios")) {
@@ -178,10 +174,9 @@ class PlaywrightPulseReporter {
178
174
  if (step.location) {
179
175
  codeLocation = `${path.relative(this.config.rootDir, step.location.file)}:${step.location.line}:${step.location.column}`;
180
176
  }
181
- let stepTitle = step.title;
182
177
  return {
183
178
  id: `${testId}_step_${startTime.toISOString()}-${duration}-${(0, crypto_1.randomUUID)()}`,
184
- title: stepTitle,
179
+ title: step.title,
185
180
  status: stepStatus,
186
181
  duration: duration,
187
182
  startTime: startTime,
@@ -200,21 +195,16 @@ class PlaywrightPulseReporter {
200
195
  };
201
196
  }
202
197
  async onTestEnd(test, result) {
203
- var _a, _b, _c, _d, _e, _f, _g, _h;
198
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l;
204
199
  const project = (_a = test.parent) === null || _a === void 0 ? void 0 : _a.project();
205
200
  const browserDetails = this.getBrowserDetails(test);
206
201
  const testStatus = convertStatus(result.status, test);
207
202
  const startTime = new Date(result.startTime);
208
203
  const endTime = new Date(startTime.getTime() + result.duration);
209
- const testIdForFiles = test.id ||
210
- `${test
211
- .titlePath()
212
- .join("_")
213
- .replace(/[^a-zA-Z0-9]/g, "_")}_${startTime.getTime()}`;
214
204
  const processAllSteps = async (steps) => {
215
205
  let processed = [];
216
206
  for (const step of steps) {
217
- const processedStep = await this.processStep(step, testIdForFiles, browserDetails, test);
207
+ const processedStep = await this.processStep(step, test.id, browserDetails, test);
218
208
  processed.push(processedStep);
219
209
  if (step.steps && step.steps.length > 0) {
220
210
  processedStep.steps = await processAllSteps(step.steps);
@@ -232,39 +222,14 @@ class PlaywrightPulseReporter {
232
222
  catch (e) {
233
223
  console.warn(`Pulse Reporter: Could not extract code snippet for ${test.title}`, e);
234
224
  }
235
- const stdoutMessages = [];
236
- if (result.stdout && result.stdout.length > 0) {
237
- result.stdout.forEach((item) => {
238
- stdoutMessages.push(typeof item === "string" ? item : item.toString());
239
- });
240
- }
241
- const stderrMessages = [];
242
- if (result.stderr && result.stderr.length > 0) {
243
- result.stderr.forEach((item) => {
244
- stderrMessages.push(typeof item === "string" ? item : item.toString());
245
- });
246
- }
247
- const uniqueTestId = test.id;
248
- // --- REFINED THIS SECTION for testData ---
225
+ const stdoutMessages = result.stdout.map((item) => typeof item === "string" ? item : item.toString());
226
+ const stderrMessages = result.stderr.map((item) => typeof item === "string" ? item : item.toString());
249
227
  const maxWorkers = this.config.workers;
250
- let mappedWorkerId;
251
- // First, check for the special case where a test is not assigned a worker (e.g., global setup failure).
252
- if (result.workerIndex === -1) {
253
- mappedWorkerId = -1; // Keep it as -1 to clearly identify this special case.
254
- }
255
- else if (maxWorkers && maxWorkers > 0) {
256
- // If there's a valid worker, map it to the concurrency slot...
257
- const zeroBasedId = result.workerIndex % maxWorkers;
258
- // ...and then shift it to be 1-based (1 to n).
259
- mappedWorkerId = zeroBasedId + 1;
260
- }
261
- else {
262
- // Fallback for when maxWorkers is not defined: just use the original index (and shift to 1-based).
263
- mappedWorkerId = result.workerIndex + 1;
264
- }
228
+ let mappedWorkerId = result.workerIndex === -1
229
+ ? -1
230
+ : (result.workerIndex % (maxWorkers > 0 ? maxWorkers : 1)) + 1;
265
231
  const testSpecificData = {
266
232
  workerId: mappedWorkerId,
267
- uniqueWorkerIndex: result.workerIndex, // We'll keep the original for diagnostics
268
233
  totalWorkers: maxWorkers,
269
234
  configFile: this.config.configFile,
270
235
  metadata: this.config.metadata
@@ -272,7 +237,7 @@ class PlaywrightPulseReporter {
272
237
  : undefined,
273
238
  };
274
239
  const pulseResult = {
275
- id: uniqueTestId,
240
+ id: test.id,
276
241
  runId: "TBD",
277
242
  name: test.titlePath().join(" > "),
278
243
  suiteName: (project === null || project === void 0 ? void 0 : project.name) || ((_e = this.config.projects[0]) === null || _e === void 0 ? void 0 : _e.name) || "Default Suite",
@@ -288,20 +253,46 @@ class PlaywrightPulseReporter {
288
253
  codeSnippet: codeSnippet,
289
254
  tags: test.tags.map((tag) => tag.startsWith("@") ? tag.substring(1) : tag),
290
255
  screenshots: [],
291
- videoPath: undefined,
256
+ videoPath: [], // MODIFIED: Initialized as an array
292
257
  tracePath: undefined,
258
+ attachments: [], // NEW: Initialized
293
259
  stdout: stdoutMessages.length > 0 ? stdoutMessages : undefined,
294
260
  stderr: stderrMessages.length > 0 ? stderrMessages : undefined,
295
- // --- UPDATED THESE LINES from testSpecificData ---
296
261
  ...testSpecificData,
297
262
  };
298
- try {
299
- (0, attachment_utils_1.attachFiles)(testIdForFiles, result, pulseResult, this.options);
300
- }
301
- catch (attachError) {
302
- console.error(`Pulse Reporter: Error processing attachments for test ${pulseResult.name} (ID: ${testIdForFiles}): ${attachError.message}`);
263
+ // --- NEW SELF-CONTAINED ATTACHMENT PROCESSING LOGIC ---
264
+ for (const attachment of result.attachments) {
265
+ if (!attachment.path)
266
+ continue;
267
+ try {
268
+ const attachmentFileName = path.basename(attachment.path);
269
+ const relativeDestPath = path.join(ATTACHMENTS_SUBDIR, attachmentFileName);
270
+ const absoluteDestPath = path.join(this.outputDir, relativeDestPath);
271
+ await this._ensureDirExists(path.dirname(absoluteDestPath));
272
+ await fs.copyFile(attachment.path, absoluteDestPath);
273
+ if (attachment.contentType.startsWith("image/")) {
274
+ (_j = pulseResult.screenshots) === null || _j === void 0 ? void 0 : _j.push(relativeDestPath);
275
+ }
276
+ else if (attachment.contentType.startsWith("video/")) {
277
+ (_k = pulseResult.videoPath) === null || _k === void 0 ? void 0 : _k.push(relativeDestPath); // MODIFIED: Push to videoPath array
278
+ }
279
+ else if (attachment.name === "trace") {
280
+ pulseResult.tracePath = relativeDestPath;
281
+ }
282
+ else {
283
+ // NEW: Handle all other file types
284
+ (_l = pulseResult.attachments) === null || _l === void 0 ? void 0 : _l.push({
285
+ name: attachment.name,
286
+ path: relativeDestPath,
287
+ contentType: attachment.contentType,
288
+ });
289
+ }
290
+ }
291
+ catch (err) {
292
+ console.error(`Pulse Reporter: Failed to process attachment "${attachment.name}" for test ${pulseResult.name}. Error: ${err.message}`);
293
+ }
303
294
  }
304
- const existingTestIndex = this.results.findIndex((r) => r.id === uniqueTestId);
295
+ const existingTestIndex = this.results.findIndex((r) => r.id === test.id);
305
296
  if (existingTestIndex !== -1) {
306
297
  if (pulseResult.retries >= this.results[existingTestIndex].retries) {
307
298
  this.results[existingTestIndex] = pulseResult;
@@ -323,10 +314,10 @@ class PlaywrightPulseReporter {
323
314
  host: os.hostname(),
324
315
  os: `${os.platform()} ${os.release()}`,
325
316
  cpu: {
326
- model: os.cpus()[0] ? os.cpus()[0].model : "N/A", // Handle cases with no CPU info
317
+ model: os.cpus()[0] ? os.cpus()[0].model : "N/A",
327
318
  cores: os.cpus().length,
328
319
  },
329
- memory: `${(os.totalmem() / 1024 ** 3).toFixed(2)}GB`, // Total RAM in GB
320
+ memory: `${(os.totalmem() / 1024 ** 3).toFixed(2)}GB`,
330
321
  node: process.version,
331
322
  v8: process.versions.v8,
332
323
  cwd: process.cwd(),
@@ -418,15 +409,13 @@ class PlaywrightPulseReporter {
418
409
  }
419
410
  }
420
411
  async onEnd(result) {
421
- var _a, _b, _c;
422
412
  if (this.shardIndex !== undefined) {
423
413
  await this._writeShardResults();
424
414
  return;
425
415
  }
426
416
  const runEndTime = Date.now();
427
417
  const duration = runEndTime - this.runStartTime;
428
- const runId = `run-${this.runStartTime}-581d5ad8-ce75-4ca5-94a6-ed29c466c815`; // Need not to change
429
- // --- CALLING _getEnvDetails HERE ---
418
+ const runId = `run-${this.runStartTime}-581d5ad8-ce75-4ca5-94a6-ed29c466c815`;
430
419
  const environmentDetails = this._getEnvDetails();
431
420
  const runData = {
432
421
  id: runId,
@@ -436,13 +425,11 @@ class PlaywrightPulseReporter {
436
425
  failed: 0,
437
426
  skipped: 0,
438
427
  duration,
439
- // --- ADDED environmentDetails HERE ---
440
428
  environment: environmentDetails,
441
429
  };
442
- let finalReport = undefined; // Initialize as undefined
430
+ let finalReport = undefined;
443
431
  if (this.isSharded) {
444
432
  finalReport = await this._mergeShardResults(runData);
445
- // Ensured environment details are on the final merged runData if not already
446
433
  if (finalReport && finalReport.run && !finalReport.run.environment) {
447
434
  finalReport.run.environment = environmentDetails;
448
435
  }
@@ -470,67 +457,8 @@ class PlaywrightPulseReporter {
470
457
  }
471
458
  if (!finalReport) {
472
459
  console.error("PlaywrightPulseReporter: CRITICAL - finalReport object was not generated. Cannot create summary.");
473
- const errorSummary = `
474
- PlaywrightPulseReporter: Run Finished
475
- -----------------------------------------
476
- Overall Status: ERROR (Report data missing)
477
- Total Tests: N/A
478
- Passed: N/A
479
- Failed: N/A
480
- Skipped: N/A
481
- Duration: N/A
482
- -----------------------------------------`;
483
- if (this.printsToStdio()) {
484
- console.log(errorSummary);
485
- }
486
- const errorReport = {
487
- run: {
488
- id: runId,
489
- timestamp: new Date(this.runStartTime),
490
- totalTests: 0,
491
- passed: 0,
492
- failed: 0,
493
- skipped: 0,
494
- duration: duration,
495
- environment: environmentDetails,
496
- },
497
- results: [],
498
- metadata: {
499
- generatedAt: new Date().toISOString(),
500
- },
501
- };
502
- const finalOutputPathOnError = path.join(this.outputDir, this.baseOutputFile);
503
- try {
504
- await this._ensureDirExists(this.outputDir);
505
- await fs.writeFile(finalOutputPathOnError, JSON.stringify(errorReport, null, 2));
506
- console.warn(`PlaywrightPulseReporter: Wrote an error report to ${finalOutputPathOnError} as finalReport was missing.`);
507
- }
508
- catch (writeError) {
509
- console.error(`PlaywrightPulseReporter: Failed to write error report: ${writeError.message}`);
510
- }
511
460
  return;
512
461
  }
513
- const reportRunData = finalReport.run;
514
- const finalRunStatus = ((_a = reportRunData === null || reportRunData === void 0 ? void 0 : reportRunData.failed) !== null && _a !== void 0 ? _a : 0) > 0
515
- ? "failed"
516
- : ((_b = reportRunData === null || reportRunData === void 0 ? void 0 : reportRunData.totalTests) !== null && _b !== void 0 ? _b : 0) === 0 && result.status !== "passed"
517
- ? result.status === "interrupted"
518
- ? "interrupted"
519
- : "no tests or error"
520
- : "passed";
521
- const summary = `
522
- PlaywrightPulseReporter: Run Finished
523
- -----------------------------------------
524
- Overall Status: ${finalRunStatus.toUpperCase()}
525
- Total Tests: ${(reportRunData === null || reportRunData === void 0 ? void 0 : reportRunData.totalTests) || 0}
526
- Passed: ${reportRunData === null || reportRunData === void 0 ? void 0 : reportRunData.passed}
527
- Failed: ${reportRunData === null || reportRunData === void 0 ? void 0 : reportRunData.failed}
528
- Skipped: ${reportRunData === null || reportRunData === void 0 ? void 0 : reportRunData.skipped}
529
- Duration: ${(((_c = reportRunData === null || reportRunData === void 0 ? void 0 : reportRunData.duration) !== null && _c !== void 0 ? _c : 0) / 1000).toFixed(2)}s
530
- -----------------------------------------`;
531
- if (this.printsToStdio()) {
532
- console.log(summary);
533
- }
534
462
  const finalOutputPath = path.join(this.outputDir, this.baseOutputFile);
535
463
  try {
536
464
  await this._ensureDirExists(this.outputDir);
@@ -32,8 +32,13 @@ export interface TestResult {
32
32
  runId: string;
33
33
  browser: string;
34
34
  screenshots?: string[];
35
- videoPath?: string;
35
+ videoPath?: string[];
36
36
  tracePath?: string;
37
+ attachments?: {
38
+ name: string;
39
+ path: string;
40
+ contentType: string;
41
+ }[];
37
42
  stdout?: string[];
38
43
  stderr?: string[];
39
44
  workerId?: number;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@arghajit/dummy",
3
3
  "author": "Arghajit Singha",
4
- "version": "0.1.0-beta-18",
4
+ "version": "0.1.0-beta-19",
5
5
  "description": "A Playwright reporter and dashboard for visualizing test results.",
6
6
  "keywords": [
7
7
  "playwright",
@@ -11,6 +11,7 @@
11
11
  "reporting",
12
12
  "nextjs",
13
13
  "playwright-pulse",
14
+ "playwright-pulse-report",
14
15
  "report",
15
16
  "email-report",
16
17
  "send-report",
@@ -46,7 +47,8 @@
46
47
  "report:generate": "node ./scripts/generate-report.mjs",
47
48
  "report:merge": "node ./scripts/merge-pulse-report.js",
48
49
  "report:email": "node ./scripts/sendReport.mjs",
49
- "report:minify": "node ./scripts/generate-email-report.mjs"
50
+ "report:minify": "node ./scripts/generate-email-report.mjs",
51
+ "generate-trend": "node ./scripts/generate-trend.mjs"
50
52
  },
51
53
  "dependencies": {
52
54
  "archiver": "^7.0.1",