@empiricalrun/playwright-utils 0.14.17 → 0.14.18
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/CHANGELOG.md +6 -0
- package/dist/reporter/custom.d.ts +2 -0
- package/dist/reporter/custom.d.ts.map +1 -1
- package/dist/reporter/custom.js +94 -43
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -42,6 +42,7 @@ declare class HtmlReporter implements ReporterV2 {
|
|
|
42
42
|
private uploadExecutionQueue;
|
|
43
43
|
private uploadWaitingQueue;
|
|
44
44
|
private uploadMaxQueueSize;
|
|
45
|
+
private haveSeenAttachments;
|
|
45
46
|
private processQueue;
|
|
46
47
|
private waitForAllTasksToFinish;
|
|
47
48
|
private _buildResult;
|
|
@@ -55,6 +56,7 @@ declare class HtmlReporter implements ReporterV2 {
|
|
|
55
56
|
onTestBegin(): void;
|
|
56
57
|
version(): "v2";
|
|
57
58
|
onTestEnd(test: TestCasePublic, result: TestResultPublic): void;
|
|
59
|
+
private processTestAttachment;
|
|
58
60
|
onConfigure(config: FullConfig): void;
|
|
59
61
|
onBegin(suite: Suite): void;
|
|
60
62
|
_resolveOptions(): {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"custom.d.ts","sourceRoot":"","sources":["../../src/reporter/custom.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAMH,OAAO,KAAK,EACV,UAAU,EACV,UAAU,
|
|
1
|
+
{"version":3,"file":"custom.d.ts","sourceRoot":"","sources":["../../src/reporter/custom.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAMH,OAAO,KAAK,EACV,UAAU,EACV,UAAU,EAMV,KAAK,EACL,QAAQ,IAAI,cAAc,EAC1B,SAAS,EACT,UAAU,IAAI,gBAAgB,EAE/B,MAAM,2BAA2B,CAAC;AAGnC,OAAO,EAML,UAAU,EAMX,MAAM,2BAA2B,CAAC;AAiBnC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAiC/C,QAAA,MAAM,iBAAiB,UAAoC,CAAC;AAC5D,KAAK,oBAAoB,GAAG,CAAC,OAAO,iBAAiB,CAAC,CAAC,MAAM,CAAC,CAAC;AAM/D,KAAK,mBAAmB,GAAG;IACzB,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,IAAI,CAAC,EAAE,oBAAoB,CAAC;IAC5B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACxB,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB,CAAC;AA6BF,cAAM,YAAa,YAAW,UAAU;IACtC,OAAO,CAAC,MAAM,CAAc;IAC5B,OAAO,CAAC,KAAK,CAAS;IACtB,OAAO,CAAC,QAAQ,CAAsB;IACtC,OAAO,CAAC,aAAa,CAAU;IAC/B,OAAO,CAAC,mBAAmB,CAAU;IACrC,OAAO,CAAC,KAAK,CAAqB;IAClC,OAAO,CAAC,KAAK,CAAqB;IAClC,OAAO,CAAC,KAAK,CAAqB;IAClC,OAAO,CAAC,oBAAoB,CAAiC;IAC7D,OAAO,CAAC,kBAAkB,CAAyC;IACnE,OAAO,CAAC,kBAAkB,CAEpB;IACN,OAAO,CAAC,mBAAmB,CAAqB;IAEhD,OAAO,CAAC,YAAY;YA4BN,uBAAuB;IAQrC,OAAO,CAAC,YAAY,CAEN;IACd,OAAO,CAAC,eAAe,CAAmB;gBAE9B,OAAO,EAAE,mBAAmB;IAIxC,aAAa;IAIb,QAAQ;IAER,QAAQ;IAER,WAAW;IAEX,SAAS;IAET,WAAW;IAEX,OAAO,IAAI,IAAI;IAIf,SAAS,CAAC,IAAI,EAAE,cAAc,EAAE,MAAM,EAAE,gBAAgB;IAUxD,OAAO,CAAC,qBAAqB;IAoD7B,WAAW,CAAC,MAAM,EAAE,UAAU;IAI9B,OAAO,CAAC,KAAK,EAAE,KAAK;IAYpB,eAAe,IAAI;QACjB,YAAY,EAAE,MAAM,CAAC;QACrB,IAAI,EAAE,oBAAoB,CAAC;QAC3B,kBAAkB,EAAE,MAAM,CAAC;QAC3B,IAAI,EAAE,MAAM,GAAG,SAAS,CAAC;QACzB,IAAI,EAAE,MAAM,GAAG,SAAS,CAAC;KAC1B;IAsBD,eAAe,CAAC,SAAS,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO;IASxD,OAAO,CAAC,KAAK,EAAE,SAAS,GAAG,IAAI;IAIzB,KAAK,CAAC,MAAM,EAAE,UAAU;IA+IxB,MAAM;CA8Bb;AAwED,wBAAsB,cAAc,CAClC,YAAY,EAAE,MAAM,GAAG,SAAS,EAChC,IAAI,GAAE,MAAoB,EAC1B,IAAI,CAAC,EAAE,MAAM,EACb,MAAM,CAAC,EAAE,MAAM,iBAqBhB;AAED,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,MAAM,GAAG,UAAU,CAsBhE;AAqiBD,eAAe,YAAY,CAAC"}
|
package/dist/reporter/custom.js
CHANGED
|
@@ -75,6 +75,7 @@ class HtmlReporter {
|
|
|
75
75
|
uploadMaxQueueSize = process.env.UPLOAD_MAX_QUEUE_SIZE
|
|
76
76
|
? parseInt(process.env.UPLOAD_MAX_QUEUE_SIZE)
|
|
77
77
|
: 2;
|
|
78
|
+
haveSeenAttachments = new Set();
|
|
78
79
|
processQueue() {
|
|
79
80
|
try {
|
|
80
81
|
while (this.uploadExecutionQueue.length <= this.uploadMaxQueueSize &&
|
|
@@ -125,55 +126,60 @@ class HtmlReporter {
|
|
|
125
126
|
onTestEnd(test, result) {
|
|
126
127
|
try {
|
|
127
128
|
result.attachments.forEach(async (attachment) => {
|
|
128
|
-
|
|
129
|
-
return;
|
|
130
|
-
const folder = path_1.default.relative(this._outputFolder + "/data", attachment.path);
|
|
131
|
-
const folderName = folder.split("/")[0];
|
|
132
|
-
// on test gen run, we don't have PROJECT_NAME or TEST_RUN_GITHUB_ACTION_ID so we skip uploading since we anyways handle uploads for that, this is a stopgap
|
|
133
|
-
if (!process.env.PROJECT_NAME ||
|
|
134
|
-
!process.env.TEST_RUN_GITHUB_ACTION_ID) {
|
|
135
|
-
return;
|
|
136
|
-
}
|
|
137
|
-
try {
|
|
138
|
-
const uploadTask = async () => (0, r2_uploader_1.uploadDirectory)({
|
|
139
|
-
fileList: [attachment.path],
|
|
140
|
-
sourceDir: this._outputFolder + "/data/" + folderName,
|
|
141
|
-
destinationDir: process.env.PROJECT_NAME +
|
|
142
|
-
"/" +
|
|
143
|
-
process.env.TEST_RUN_GITHUB_ACTION_ID +
|
|
144
|
-
"/data/" +
|
|
145
|
-
folderName,
|
|
146
|
-
uploadBucket: "test-report",
|
|
147
|
-
});
|
|
148
|
-
if (this.uploadExecutionQueue.length <= this.uploadMaxQueueSize) {
|
|
149
|
-
const promise = uploadTask()
|
|
150
|
-
.catch((e) => {
|
|
151
|
-
logger_1.logger.error("Upload failed for", attachment.path, e);
|
|
152
|
-
// this.retryTask(uploadTask); // Retry logic
|
|
153
|
-
})
|
|
154
|
-
.finally(() => {
|
|
155
|
-
// this is a list of promises which we dont want to await right now
|
|
156
|
-
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
|
157
|
-
this.uploadExecutionQueue = this.uploadExecutionQueue.filter((p) => p !== promise);
|
|
158
|
-
this.processQueue(); // Keep processing queue
|
|
159
|
-
});
|
|
160
|
-
this.uploadExecutionQueue.push(promise);
|
|
161
|
-
}
|
|
162
|
-
else {
|
|
163
|
-
logger_1.logger.debug("Queuing upload task ", attachment.path);
|
|
164
|
-
this.uploadWaitingQueue.push(uploadTask);
|
|
165
|
-
}
|
|
166
|
-
}
|
|
167
|
-
catch (e) {
|
|
168
|
-
logger_1.logger.error("Error while uploading attachment", e);
|
|
169
|
-
// tests shouldn't stop no matter whatever error we get
|
|
170
|
-
}
|
|
129
|
+
return this.processTestAttachment(attachment);
|
|
171
130
|
});
|
|
172
131
|
}
|
|
173
132
|
catch (e) {
|
|
174
133
|
logger_1.logger.error("Error while processing attachments for test", e);
|
|
175
134
|
}
|
|
176
135
|
}
|
|
136
|
+
processTestAttachment(attachment) {
|
|
137
|
+
if (!attachment.path)
|
|
138
|
+
return;
|
|
139
|
+
if (this.haveSeenAttachments.has(attachment.path))
|
|
140
|
+
return;
|
|
141
|
+
this.haveSeenAttachments.add(attachment.path);
|
|
142
|
+
const folder = path_1.default.relative(this._outputFolder + "/data", attachment.path);
|
|
143
|
+
const folderName = folder.split("/")[0];
|
|
144
|
+
// on test gen run, we don't have PROJECT_NAME or TEST_RUN_GITHUB_ACTION_ID so we skip uploading since we anyways handle uploads for that, this is a stopgap
|
|
145
|
+
if (!process.env.PROJECT_NAME || !process.env.TEST_RUN_GITHUB_ACTION_ID) {
|
|
146
|
+
return;
|
|
147
|
+
}
|
|
148
|
+
try {
|
|
149
|
+
const uploadTask = async () => (0, r2_uploader_1.uploadDirectory)({
|
|
150
|
+
fileList: [attachment.path],
|
|
151
|
+
sourceDir: this._outputFolder + "/data/" + folderName,
|
|
152
|
+
destinationDir: process.env.PROJECT_NAME +
|
|
153
|
+
"/" +
|
|
154
|
+
process.env.TEST_RUN_GITHUB_ACTION_ID +
|
|
155
|
+
"/data/" +
|
|
156
|
+
folderName,
|
|
157
|
+
uploadBucket: "test-report",
|
|
158
|
+
});
|
|
159
|
+
if (this.uploadExecutionQueue.length <= this.uploadMaxQueueSize) {
|
|
160
|
+
const promise = uploadTask()
|
|
161
|
+
.catch((e) => {
|
|
162
|
+
logger_1.logger.error("Upload failed for", attachment.path, e);
|
|
163
|
+
// this.retryTask(uploadTask); // Retry logic
|
|
164
|
+
})
|
|
165
|
+
.finally(() => {
|
|
166
|
+
// this is a list of promises which we dont want to await right now
|
|
167
|
+
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
|
168
|
+
this.uploadExecutionQueue = this.uploadExecutionQueue.filter((p) => p !== promise);
|
|
169
|
+
this.processQueue(); // Keep processing queue
|
|
170
|
+
});
|
|
171
|
+
this.uploadExecutionQueue.push(promise);
|
|
172
|
+
}
|
|
173
|
+
else {
|
|
174
|
+
logger_1.logger.debug("Queuing upload task ", attachment.path);
|
|
175
|
+
this.uploadWaitingQueue.push(uploadTask);
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
catch (e) {
|
|
179
|
+
logger_1.logger.error("Error while uploading attachment", e);
|
|
180
|
+
// tests shouldn't stop no matter whatever error we get
|
|
181
|
+
}
|
|
182
|
+
}
|
|
177
183
|
onConfigure(config) {
|
|
178
184
|
this.config = config;
|
|
179
185
|
}
|
|
@@ -231,6 +237,15 @@ class HtmlReporter {
|
|
|
231
237
|
try {
|
|
232
238
|
logger_1.logger.debug("uploading path", this._outputFolder);
|
|
233
239
|
logger_1.logger.debug("file list", listFilesRecursively(this._outputFolder));
|
|
240
|
+
const summaryJsonPath = path_1.default.join(this._outputFolder, "summary.json");
|
|
241
|
+
if (fs_1.default.existsSync(summaryJsonPath)) {
|
|
242
|
+
logger_1.logger.debug("reading json to ensure all attachments are processed");
|
|
243
|
+
const summaryJson = JSON.parse(fs_1.default.readFileSync(summaryJsonPath, "utf-8"));
|
|
244
|
+
const attachments = getAttachmentsFromJSONReport(summaryJson);
|
|
245
|
+
attachments.forEach(async (attachment) => {
|
|
246
|
+
return this.processTestAttachment(attachment);
|
|
247
|
+
});
|
|
248
|
+
}
|
|
234
249
|
const tracePath = this._outputFolder + "/trace";
|
|
235
250
|
const traceExists = fs_1.default.existsSync(tracePath);
|
|
236
251
|
logger_1.logger.debug("trace exists:", traceExists);
|
|
@@ -333,6 +348,42 @@ class HtmlReporter {
|
|
|
333
348
|
}
|
|
334
349
|
}
|
|
335
350
|
}
|
|
351
|
+
function getAttachmentsFromJSONReport(report) {
|
|
352
|
+
const { suites } = report;
|
|
353
|
+
return getAttachmentsFromSuites(suites);
|
|
354
|
+
}
|
|
355
|
+
function getAttachmentsFromSuites(suites) {
|
|
356
|
+
if (!suites)
|
|
357
|
+
return [];
|
|
358
|
+
if (!suites.length)
|
|
359
|
+
return [];
|
|
360
|
+
let allAttachments = [];
|
|
361
|
+
suites.forEach((currentSuite) => {
|
|
362
|
+
const { specs } = currentSuite;
|
|
363
|
+
const { suites } = currentSuite;
|
|
364
|
+
const attachmentsFromSuites = getAttachmentsFromSuites(suites);
|
|
365
|
+
const attachmentsFromSpecs = getAttachmentsFromSpecs(specs);
|
|
366
|
+
allAttachments = allAttachments.concat(attachmentsFromSuites, attachmentsFromSpecs);
|
|
367
|
+
});
|
|
368
|
+
return allAttachments;
|
|
369
|
+
}
|
|
370
|
+
function getAttachmentsFromSpecs(specs) {
|
|
371
|
+
if (!specs)
|
|
372
|
+
return [];
|
|
373
|
+
if (!specs.length)
|
|
374
|
+
return [];
|
|
375
|
+
let allAttachments = [];
|
|
376
|
+
specs.forEach((spec) => {
|
|
377
|
+
spec.tests.forEach((test) => {
|
|
378
|
+
const { results } = test;
|
|
379
|
+
results.forEach((result) => {
|
|
380
|
+
const { attachments } = result;
|
|
381
|
+
allAttachments = allAttachments.concat(attachments);
|
|
382
|
+
});
|
|
383
|
+
});
|
|
384
|
+
});
|
|
385
|
+
return allAttachments;
|
|
386
|
+
}
|
|
336
387
|
function reportFolderFromEnv() {
|
|
337
388
|
// Note: PLAYWRIGHT_HTML_REPORT is for backwards compatibility.
|
|
338
389
|
const envValue = false;
|