@reportforge/playwright-pdf 0.12.0 → 0.13.1
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 +114 -106
- package/README.md +86 -83
- package/dist/cli/index.js +5 -2
- package/dist/index.d.mts +6 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.js +56 -6
- package/dist/index.mjs +52 -2
- package/package.json +11 -2
package/dist/index.mjs
CHANGED
|
@@ -10455,6 +10455,9 @@ var channelConfigSchema = external_exports.object({
|
|
|
10455
10455
|
on: external_exports.enum(["always", "failure", "success"]).default("always"),
|
|
10456
10456
|
enabled: external_exports.boolean().default(false)
|
|
10457
10457
|
});
|
|
10458
|
+
var discordChannelConfigSchema = channelConfigSchema.extend({
|
|
10459
|
+
attachPdf: external_exports.boolean().default(false)
|
|
10460
|
+
});
|
|
10458
10461
|
var emailChannelConfigSchema = external_exports.object({
|
|
10459
10462
|
to: external_exports.array(external_exports.string().email('Each "to" entry must be a valid email')).min(1, '"to" must have at least one address'),
|
|
10460
10463
|
on: external_exports.enum(["always", "failure", "success"]).default("always"),
|
|
@@ -10464,7 +10467,7 @@ var emailChannelConfigSchema = external_exports.object({
|
|
|
10464
10467
|
var notifyConfigSchema = external_exports.object({
|
|
10465
10468
|
slack: channelConfigSchema.optional(),
|
|
10466
10469
|
teams: channelConfigSchema.optional(),
|
|
10467
|
-
discord:
|
|
10470
|
+
discord: discordChannelConfigSchema.optional(),
|
|
10468
10471
|
email: emailChannelConfigSchema.optional()
|
|
10469
10472
|
}).optional();
|
|
10470
10473
|
var failureAnalysisConfigSchema = external_exports.object({
|
|
@@ -13281,6 +13284,8 @@ init_esm_shims();
|
|
|
13281
13284
|
|
|
13282
13285
|
// src/notify/NotificationSender.ts
|
|
13283
13286
|
init_esm_shims();
|
|
13287
|
+
import { readFile as readFile2 } from "fs/promises";
|
|
13288
|
+
import { basename as basename3 } from "path";
|
|
13284
13289
|
|
|
13285
13290
|
// src/notify/formatters/slack.ts
|
|
13286
13291
|
init_esm_shims();
|
|
@@ -13530,6 +13535,7 @@ var FORMATTERS = {
|
|
|
13530
13535
|
teams: buildTeamsPayload,
|
|
13531
13536
|
discord: buildDiscordPayload
|
|
13532
13537
|
};
|
|
13538
|
+
var DISCORD_MAX_UPLOAD_BYTES = 25 * 1024 * 1024;
|
|
13533
13539
|
var NotificationSender = class {
|
|
13534
13540
|
async sendAll(reportData, notifyConfig, pdfPaths) {
|
|
13535
13541
|
const result = { sent: [], skipped: [], failed: [] };
|
|
@@ -13542,6 +13548,9 @@ var NotificationSender = class {
|
|
|
13542
13548
|
return Promise.resolve();
|
|
13543
13549
|
}
|
|
13544
13550
|
const payload = FORMATTERS[name](reportData.stats, pdfPaths, reportTitle);
|
|
13551
|
+
if (name === "discord" && notifyConfig.discord?.attachPdf && pdfPaths.length > 0) {
|
|
13552
|
+
return this.postDiscordWithPdf(channel.url, payload, pdfPaths[0], result);
|
|
13553
|
+
}
|
|
13545
13554
|
return this.post(name, channel.url, payload, result);
|
|
13546
13555
|
})
|
|
13547
13556
|
);
|
|
@@ -13583,6 +13592,47 @@ var NotificationSender = class {
|
|
|
13583
13592
|
})
|
|
13584
13593
|
);
|
|
13585
13594
|
}
|
|
13595
|
+
/**
|
|
13596
|
+
* Posts the summary to a Discord webhook with the PDF as a multipart file
|
|
13597
|
+
* upload (`payload_json` + `files[0]`). Any problem — unreadable file, PDF
|
|
13598
|
+
* over Discord's upload cap, or a failed upload — falls back to the plain
|
|
13599
|
+
* JSON summary post so the notification still lands; only the fallback's
|
|
13600
|
+
* outcome is recorded in the result. Attaches the first PDF only (matches
|
|
13601
|
+
* the email channel's multi-template behaviour).
|
|
13602
|
+
*/
|
|
13603
|
+
async postDiscordWithPdf(url, payload, pdfPath, result) {
|
|
13604
|
+
let file;
|
|
13605
|
+
try {
|
|
13606
|
+
file = await readFile2(pdfPath);
|
|
13607
|
+
if (file.byteLength > DISCORD_MAX_UPLOAD_BYTES) {
|
|
13608
|
+
const mb = (file.byteLength / 1024 / 1024).toFixed(1);
|
|
13609
|
+
throw new Error(`PDF is ${mb}MB \u2014 over Discord's upload limit`);
|
|
13610
|
+
}
|
|
13611
|
+
} catch (err) {
|
|
13612
|
+
logger.warn(
|
|
13613
|
+
`[notify] discord: ${err instanceof Error ? err.message : String(err)} \u2014 sending summary without the PDF`
|
|
13614
|
+
);
|
|
13615
|
+
return this.post("discord", url, payload, result);
|
|
13616
|
+
}
|
|
13617
|
+
const form = new FormData();
|
|
13618
|
+
form.append("payload_json", JSON.stringify(payload));
|
|
13619
|
+
form.append("files[0]", new Blob([new Uint8Array(file)], { type: "application/pdf" }), basename3(pdfPath));
|
|
13620
|
+
const controller = new AbortController();
|
|
13621
|
+
const timeoutId = setTimeout(() => controller.abort(), 3e4);
|
|
13622
|
+
try {
|
|
13623
|
+
const res = await fetch(url, { method: "POST", body: form, signal: controller.signal });
|
|
13624
|
+
if (!res.ok) throw new Error(`HTTP ${res.status}`);
|
|
13625
|
+
logger.info("[notify] discord: sent (PDF attached)");
|
|
13626
|
+
result.sent.push("discord");
|
|
13627
|
+
} catch (err) {
|
|
13628
|
+
logger.warn(
|
|
13629
|
+
`[notify] discord: upload failed (${err instanceof Error ? err.message : String(err)}) \u2014 retrying without the PDF`
|
|
13630
|
+
);
|
|
13631
|
+
return this.post("discord", url, payload, result);
|
|
13632
|
+
} finally {
|
|
13633
|
+
clearTimeout(timeoutId);
|
|
13634
|
+
}
|
|
13635
|
+
}
|
|
13586
13636
|
async post(name, url, payload, result) {
|
|
13587
13637
|
const controller = new AbortController();
|
|
13588
13638
|
const timeoutId = setTimeout(() => controller.abort(), 1e4);
|
|
@@ -13952,7 +14002,7 @@ var PdfReporter = class {
|
|
|
13952
14002
|
this.liveConsole = false;
|
|
13953
14003
|
this.options = parseOptions(rawOptions);
|
|
13954
14004
|
this.dataCollector = new DataCollector(this.options.capture);
|
|
13955
|
-
const version = true ? "0.
|
|
14005
|
+
const version = true ? "0.13.1" : "0.x";
|
|
13956
14006
|
logger.info(`@reportforge/playwright-pdf v${version} initialised`);
|
|
13957
14007
|
this.licenseClient = new LicenseClient({
|
|
13958
14008
|
licenseKey: this.options.licenseKey,
|
package/package.json
CHANGED
|
@@ -1,15 +1,21 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@reportforge/playwright-pdf",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "0.13.1",
|
|
4
|
+
"description": "Playwright Test reporter that generates designed PDF reports: minimal, detailed, and executive templates with CI/CD integrations",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "ReportForge",
|
|
7
|
+
"homepage": "https://reportforge.org",
|
|
7
8
|
"repository": {
|
|
8
9
|
"type": "git",
|
|
9
10
|
"url": "https://github.com/muralidharan92/reportforge"
|
|
10
11
|
},
|
|
12
|
+
"bugs": {
|
|
13
|
+
"url": "https://github.com/muralidharan92/reportforge/issues",
|
|
14
|
+
"email": "support@reportforge.org"
|
|
15
|
+
},
|
|
11
16
|
"keywords": [
|
|
12
17
|
"playwright",
|
|
18
|
+
"playwright-test",
|
|
13
19
|
"playwright-reporter",
|
|
14
20
|
"playwright-pdf",
|
|
15
21
|
"playwright-report",
|
|
@@ -17,6 +23,9 @@
|
|
|
17
23
|
"reporter",
|
|
18
24
|
"test-report",
|
|
19
25
|
"test-results",
|
|
26
|
+
"test-automation",
|
|
27
|
+
"e2e",
|
|
28
|
+
"qa",
|
|
20
29
|
"pdf-report",
|
|
21
30
|
"pdf-generator",
|
|
22
31
|
"ci",
|