@arghajit/dummy 0.1.0
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 +259 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.js +26 -0
- package/dist/lib/report-types.d.ts +8 -0
- package/dist/lib/report-types.js +2 -0
- package/dist/playwright-pulse-reporter.d.ts +26 -0
- package/dist/playwright-pulse-reporter.js +304 -0
- package/dist/reporter/attachment-utils.d.ts +10 -0
- package/dist/reporter/attachment-utils.js +192 -0
- package/dist/reporter/index.d.ts +5 -0
- package/dist/reporter/index.js +9 -0
- package/dist/reporter/lib/report-types.d.ts +8 -0
- package/dist/reporter/lib/report-types.js +2 -0
- package/dist/reporter/playwright-pulse-reporter.d.ts +27 -0
- package/dist/reporter/playwright-pulse-reporter.js +454 -0
- package/dist/reporter/reporter/playwright-pulse-reporter.d.ts +1 -0
- package/dist/reporter/reporter/playwright-pulse-reporter.js +398 -0
- package/dist/reporter/types/index.d.ts +52 -0
- package/dist/reporter/types/index.js +2 -0
- package/dist/types/index.d.ts +65 -0
- package/dist/types/index.js +2 -0
- package/package.json +73 -0
- package/screenshots/127-0-0-1-5500-pulse-report-output-playwright-pulse-static-report-html-i-Phone-14-Pro-Max-1.png +0 -0
- package/screenshots/127-0-0-1-5500-pulse-report-output-playwright-pulse-static-report-html-i-Phone-14-Pro-Max.png +0 -0
- package/screenshots/Email-report.jpg +0 -0
- package/screenshots/Users-arghajitsingha-Downloads-pulse-report-1-playwright-pulse-static-report-html-1.png +0 -0
- package/screenshots/Users-arghajitsingha-Downloads-pulse-report-1-playwright-pulse-static-report-html-2.png +0 -0
- package/screenshots/Users-arghajitsingha-Downloads-pulse-report-1-playwright-pulse-static-report-html.png +0 -0
- package/screenshots/image.png +0 -0
- package/scripts/generate-static-report.mjs +2279 -0
- package/scripts/generate-trend.mjs +165 -0
- package/scripts/merge-pulse-report.js +81 -0
- package/scripts/sendReport.js +335 -0
|
@@ -0,0 +1,192 @@
|
|
|
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.attachFiles = attachFiles;
|
|
37
|
+
const path = __importStar(require("path"));
|
|
38
|
+
const fs = __importStar(require("fs")); // Use synchronous methods for simplicity in this context
|
|
39
|
+
const ATTACHMENTS_SUBDIR = "attachments"; // Consistent subdirectory name
|
|
40
|
+
/**
|
|
41
|
+
* Processes attachments from a Playwright TestResult and updates the PulseTestResult.
|
|
42
|
+
* @param testId A unique identifier for the test, used for folder naming.
|
|
43
|
+
* @param pwResult The TestResult object from Playwright.
|
|
44
|
+
* @param pulseResult The internal test result structure to update.
|
|
45
|
+
* @param config The reporter configuration options.
|
|
46
|
+
*/
|
|
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
|
|
53
|
+
try {
|
|
54
|
+
if (!fs.existsSync(testAttachmentsDir)) {
|
|
55
|
+
fs.mkdirSync(testAttachmentsDir, { recursive: true });
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
catch (error) {
|
|
59
|
+
console.error(`Pulse Reporter: Failed to create attachments directory: ${testAttachmentsDir}`, error);
|
|
60
|
+
return; // Stop processing if directory creation fails
|
|
61
|
+
}
|
|
62
|
+
if (!pwResult.attachments)
|
|
63
|
+
return;
|
|
64
|
+
const { base64Images } = config; // Get base64 embedding option
|
|
65
|
+
pulseResult.screenshots = []; // Initialize screenshots array
|
|
66
|
+
pwResult.attachments.forEach((attachment) => {
|
|
67
|
+
const { contentType, name, path: attachmentPath, body } = attachment;
|
|
68
|
+
// Skip attachments without path or body
|
|
69
|
+
if (!attachmentPath && !body) {
|
|
70
|
+
console.warn(`Pulse Reporter: Attachment "${name}" for test ${testId} has no path or body. Skipping.`);
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
// Determine filename
|
|
74
|
+
const safeName = name.replace(/[^a-zA-Z0-9_.-]/g, "_"); // Sanitize original name
|
|
75
|
+
const extension = attachmentPath
|
|
76
|
+
? path.extname(attachmentPath)
|
|
77
|
+
: `.${getFileExtension(contentType)}`;
|
|
78
|
+
const baseFilename = attachmentPath
|
|
79
|
+
? path.basename(attachmentPath, extension)
|
|
80
|
+
: safeName;
|
|
81
|
+
// Ensure unique filename within the test's attachment folder
|
|
82
|
+
const fileName = `${baseFilename}_${Date.now()}${extension}`;
|
|
83
|
+
// Relative path for storing in JSON (relative to baseReportDir)
|
|
84
|
+
const relativePath = path.join(ATTACHMENTS_SUBDIR, attachmentsSubFolder, fileName);
|
|
85
|
+
// Full path for file system operations
|
|
86
|
+
const fullPath = path.join(testAttachmentsDir, fileName);
|
|
87
|
+
if (contentType === null || contentType === void 0 ? void 0 : contentType.startsWith("image/")) {
|
|
88
|
+
// Handle all image types consistently
|
|
89
|
+
handleImage(attachmentPath, body, base64Images, fullPath, relativePath, pulseResult, name);
|
|
90
|
+
}
|
|
91
|
+
else if (name === "video" || (contentType === null || contentType === void 0 ? void 0 : contentType.startsWith("video/"))) {
|
|
92
|
+
handleAttachment(attachmentPath, body, fullPath, relativePath, "videoPath", pulseResult);
|
|
93
|
+
}
|
|
94
|
+
else if (name === "trace" || contentType === "application/zip") {
|
|
95
|
+
// Trace files are zips
|
|
96
|
+
handleAttachment(attachmentPath, body, fullPath, relativePath, "tracePath", pulseResult);
|
|
97
|
+
}
|
|
98
|
+
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
|
|
102
|
+
}
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Handles image attachments, either embedding as base64 or copying the file.
|
|
107
|
+
*/
|
|
108
|
+
function handleImage(attachmentPath, body, base64Embed, fullPath, relativePath, pulseResult, attachmentName) {
|
|
109
|
+
let screenshotData = undefined;
|
|
110
|
+
if (attachmentPath) {
|
|
111
|
+
try {
|
|
112
|
+
if (base64Embed) {
|
|
113
|
+
const fileContent = fs.readFileSync(attachmentPath, "base64");
|
|
114
|
+
screenshotData = `data:image/${getFileExtension(attachmentName)};base64,${fileContent}`;
|
|
115
|
+
}
|
|
116
|
+
else {
|
|
117
|
+
fs.copyFileSync(attachmentPath, fullPath);
|
|
118
|
+
screenshotData = relativePath;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
catch (error) {
|
|
122
|
+
console.error(`Pulse Reporter: Failed to read/copy screenshot file: ${attachmentPath}. Error: ${error.message}`);
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
else if (body) {
|
|
126
|
+
// Always embed if only body is available
|
|
127
|
+
screenshotData = `data:image/${getFileExtension(attachmentName)};base64,${body.toString("base64")}`;
|
|
128
|
+
if (!base64Embed) {
|
|
129
|
+
// Optionally save the buffer to a file even if embedding is off,
|
|
130
|
+
// but the primary representation will be base64.
|
|
131
|
+
try {
|
|
132
|
+
fs.writeFileSync(fullPath, body);
|
|
133
|
+
// console.log(`Pulse Reporter: Saved screenshot buffer to ${fullPath}`);
|
|
134
|
+
}
|
|
135
|
+
catch (error) {
|
|
136
|
+
console.error(`Pulse Reporter: Failed to save screenshot buffer: ${fullPath}. Error: ${error.message}`);
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
if (screenshotData) {
|
|
141
|
+
if (!pulseResult.screenshots) {
|
|
142
|
+
pulseResult.screenshots = [];
|
|
143
|
+
}
|
|
144
|
+
pulseResult.screenshots.push(screenshotData);
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* Handles non-image attachments by copying the file or writing the buffer.
|
|
149
|
+
*/
|
|
150
|
+
function handleAttachment(attachmentPath, body, fullPath, relativePath, resultKey, // Add more keys if needed
|
|
151
|
+
pulseResult) {
|
|
152
|
+
try {
|
|
153
|
+
if (attachmentPath) {
|
|
154
|
+
fs.copyFileSync(attachmentPath, fullPath);
|
|
155
|
+
pulseResult[resultKey] = relativePath;
|
|
156
|
+
}
|
|
157
|
+
else if (body) {
|
|
158
|
+
fs.writeFileSync(fullPath, body);
|
|
159
|
+
pulseResult[resultKey] = relativePath; // Store relative path even if from buffer
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
catch (error) {
|
|
163
|
+
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
|
+
}
|
|
166
|
+
}
|
|
167
|
+
/**
|
|
168
|
+
* Determines a file extension based on content type.
|
|
169
|
+
* @param contentType The MIME type string.
|
|
170
|
+
* @returns A file extension string.
|
|
171
|
+
*/
|
|
172
|
+
function getFileExtension(contentType) {
|
|
173
|
+
var _a;
|
|
174
|
+
if (!contentType)
|
|
175
|
+
return "bin"; // Default binary extension
|
|
176
|
+
// More robust mapping
|
|
177
|
+
const extensions = {
|
|
178
|
+
"image/png": "png",
|
|
179
|
+
"image/jpeg": "jpg",
|
|
180
|
+
"image/gif": "gif",
|
|
181
|
+
"image/webp": "webp",
|
|
182
|
+
"image/svg+xml": "svg",
|
|
183
|
+
"video/webm": "webm",
|
|
184
|
+
"video/mp4": "mp4",
|
|
185
|
+
"application/zip": "zip", // For traces
|
|
186
|
+
"text/plain": "txt",
|
|
187
|
+
"application/json": "json",
|
|
188
|
+
};
|
|
189
|
+
return (extensions[contentType.toLowerCase()] ||
|
|
190
|
+
((_a = contentType.split("/")[1]) === null || _a === void 0 ? void 0 : _a.split("+")[0]) ||
|
|
191
|
+
"bin");
|
|
192
|
+
}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { PlaywrightPulseReporter } from "./playwright-pulse-reporter";
|
|
2
|
+
export default PlaywrightPulseReporter;
|
|
3
|
+
export { PlaywrightPulseReporter };
|
|
4
|
+
export type { PlaywrightPulseReport } from "../lib/report-types";
|
|
5
|
+
export type { TestResult, TestRun, TestStep, TestStatus } from "../types";
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.PlaywrightPulseReporter = void 0;
|
|
4
|
+
// src/reporter/index.ts
|
|
5
|
+
const playwright_pulse_reporter_1 = require("./playwright-pulse-reporter");
|
|
6
|
+
Object.defineProperty(exports, "PlaywrightPulseReporter", { enumerable: true, get: function () { return playwright_pulse_reporter_1.PlaywrightPulseReporter; } });
|
|
7
|
+
// Export the reporter class as the default export for CommonJS compatibility
|
|
8
|
+
// and also as a named export for potential ES module consumers.
|
|
9
|
+
exports.default = playwright_pulse_reporter_1.PlaywrightPulseReporter;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { FullConfig, FullResult, Reporter, Suite, TestCase, TestResult as PwTestResult } from "@playwright/test/reporter";
|
|
2
|
+
import type { PlaywrightPulseReporterOptions } from "../types";
|
|
3
|
+
export declare class PlaywrightPulseReporter implements Reporter {
|
|
4
|
+
private config;
|
|
5
|
+
private suite;
|
|
6
|
+
private results;
|
|
7
|
+
private runStartTime;
|
|
8
|
+
private options;
|
|
9
|
+
private outputDir;
|
|
10
|
+
private attachmentsDir;
|
|
11
|
+
private baseOutputFile;
|
|
12
|
+
private isSharded;
|
|
13
|
+
private shardIndex;
|
|
14
|
+
constructor(options?: PlaywrightPulseReporterOptions);
|
|
15
|
+
printsToStdio(): boolean;
|
|
16
|
+
onBegin(config: FullConfig, suite: Suite): void;
|
|
17
|
+
onTestBegin(test: TestCase): void;
|
|
18
|
+
private processStep;
|
|
19
|
+
onTestEnd(test: TestCase, result: PwTestResult): Promise<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
|
+
}
|
|
27
|
+
export default PlaywrightPulseReporter;
|