playwright-slack-report 1.1.21 → 1.1.22
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 +28 -0
- package/dist/src/SlackReporter.d.ts +1 -0
- package/dist/src/SlackReporter.js +56 -22
- package/dist/src/SlackWebhookClient.d.ts +15 -0
- package/dist/src/SlackWebhookClient.js +42 -0
- package/package.json +3 -2
package/README.md
CHANGED
|
@@ -42,7 +42,35 @@ Modify your `playwright.config.ts` file to include the following:
|
|
|
42
42
|
["dot"], // other reporters
|
|
43
43
|
],
|
|
44
44
|
```
|
|
45
|
+
# Option A - send your results via a Slack webhook
|
|
45
46
|
|
|
47
|
+
Enable incoming webhooks in your Slack workspace by following the steps as per Slack's documentation:
|
|
48
|
+
|
|
49
|
+
https://api.slack.com/messaging/webhooks
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
Once you have enabled incoming webhooks, you will need to copy the webhook URL and specify it in the config:
|
|
54
|
+
|
|
55
|
+
```typescript
|
|
56
|
+
reporter: [
|
|
57
|
+
[
|
|
58
|
+
"./node_modules/playwright-slack-report/dist/src/SlackReporter.js",
|
|
59
|
+
{
|
|
60
|
+
slackWebHookUrl: "https://hooks.slack.com/services/T00000000/B00000000/XXXXXXXXXXXXXXXXXXXXXXXX",
|
|
61
|
+
sendResults: "always", // "always" , "on-failure", "off"
|
|
62
|
+
},
|
|
63
|
+
],
|
|
64
|
+
["dot"], // other reporters
|
|
65
|
+
],
|
|
66
|
+
```
|
|
67
|
+
### Note I:
|
|
68
|
+
You will most likely need to have Slack administrator rights to perform the steps above.
|
|
69
|
+
|
|
70
|
+
### Note II:
|
|
71
|
+
Sending failure details in a thread is not supported when using webhooks. You will need to use Option B below.
|
|
72
|
+
|
|
73
|
+
# Option B
|
|
46
74
|
Run your tests by providing your `SLACK_BOT_USER_OAUTH_TOKEN` as an environment variable or specifying `slackOAuthToken` option in the config:
|
|
47
75
|
|
|
48
76
|
`SLACK_BOT_USER_OAUTH_TOKEN=[your Slack bot user OAUTH token] npx playwright test`
|
|
@@ -2,8 +2,10 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
const web_api_1 = require("@slack/web-api");
|
|
4
4
|
const https_proxy_agent_1 = require("https-proxy-agent");
|
|
5
|
+
const webhook_1 = require("@slack/webhook");
|
|
5
6
|
const ResultsParser_1 = require("./ResultsParser");
|
|
6
7
|
const SlackClient_1 = require("./SlackClient");
|
|
8
|
+
const SlackWebhookClient_1 = require("./SlackWebhookClient");
|
|
7
9
|
class SlackReporter {
|
|
8
10
|
customLayout;
|
|
9
11
|
customLayoutAsync;
|
|
@@ -15,6 +17,7 @@ class SlackReporter {
|
|
|
15
17
|
slackChannels = [];
|
|
16
18
|
slackLogLevel;
|
|
17
19
|
slackOAuthToken;
|
|
20
|
+
slackWebHookUrl;
|
|
18
21
|
disableUnfurl;
|
|
19
22
|
proxy;
|
|
20
23
|
browsers = [];
|
|
@@ -29,7 +32,12 @@ class SlackReporter {
|
|
|
29
32
|
}
|
|
30
33
|
else {
|
|
31
34
|
// eslint-disable-next-line max-len
|
|
32
|
-
this.browsers = fullConfig.projects.map((obj) => ({
|
|
35
|
+
this.browsers = fullConfig.projects.map((obj) => ({
|
|
36
|
+
projectName: obj.name,
|
|
37
|
+
browser: obj.use.browserName
|
|
38
|
+
? obj.use.browserName
|
|
39
|
+
: obj.use.defaultBrowserType,
|
|
40
|
+
}));
|
|
33
41
|
}
|
|
34
42
|
if (slackReporterConfig) {
|
|
35
43
|
this.meta = slackReporterConfig.meta || [];
|
|
@@ -37,8 +45,10 @@ class SlackReporter {
|
|
|
37
45
|
this.customLayout = slackReporterConfig.layout;
|
|
38
46
|
this.customLayoutAsync = slackReporterConfig.layoutAsync;
|
|
39
47
|
this.slackChannels = slackReporterConfig.channels;
|
|
40
|
-
this.maxNumberOfFailuresToShow
|
|
48
|
+
this.maxNumberOfFailuresToShow
|
|
49
|
+
= slackReporterConfig.maxNumberOfFailuresToShow || 10;
|
|
41
50
|
this.slackOAuthToken = slackReporterConfig.slackOAuthToken || undefined;
|
|
51
|
+
this.slackWebHookUrl = slackReporterConfig.slackWebHookUrl || undefined;
|
|
42
52
|
this.disableUnfurl = slackReporterConfig.disableUnfurl || false;
|
|
43
53
|
this.showInThread = slackReporterConfig.showInThread || false;
|
|
44
54
|
this.slackLogLevel = slackReporterConfig.slackLogLevel || web_api_1.LogLevel.DEBUG;
|
|
@@ -66,40 +76,64 @@ class SlackReporter {
|
|
|
66
76
|
return;
|
|
67
77
|
}
|
|
68
78
|
const agent = this.proxy ? new https_proxy_agent_1.HttpsProxyAgent(this.proxy) : undefined;
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
const result = await slackClient.sendMessage({
|
|
74
|
-
options: {
|
|
75
|
-
channelIds: this.slackChannels,
|
|
79
|
+
if (this.slackWebHookUrl) {
|
|
80
|
+
const webhook = new webhook_1.IncomingWebhook(this.slackWebHookUrl, { agent });
|
|
81
|
+
const slackWebhookClient = new SlackWebhookClient_1.default(webhook);
|
|
82
|
+
const webhookResult = await slackWebhookClient.sendMessage({
|
|
76
83
|
customLayout: this.customLayout,
|
|
77
84
|
customLayoutAsync: this.customLayoutAsync,
|
|
78
85
|
maxNumberOfFailures: this.maxNumberOfFailuresToShow,
|
|
79
86
|
disableUnfurl: this.disableUnfurl,
|
|
80
87
|
summaryResults: resultSummary,
|
|
81
|
-
showInThread: this.showInThread,
|
|
82
|
-
},
|
|
83
|
-
});
|
|
84
|
-
// eslint-disable-next-line no-console
|
|
85
|
-
console.log(JSON.stringify(result, null, 2));
|
|
86
|
-
if (this.showInThread && resultSummary.failures.length > 0) {
|
|
87
|
-
await slackClient.attachDetailsToThread({
|
|
88
|
-
channelIds: this.slackChannels,
|
|
89
|
-
ts: result[0].ts,
|
|
90
|
-
summaryResults: resultSummary,
|
|
91
|
-
maxNumberOfFailures: this.maxNumberOfFailuresToShow,
|
|
92
88
|
});
|
|
89
|
+
// eslint-disable-next-line no-console
|
|
90
|
+
console.log(JSON.stringify(webhookResult, null, 2));
|
|
91
|
+
}
|
|
92
|
+
else {
|
|
93
|
+
const slackClient = new SlackClient_1.default(new web_api_1.WebClient(this.slackOAuthToken || process.env.SLACK_BOT_USER_OAUTH_TOKEN, {
|
|
94
|
+
logLevel: this.slackLogLevel || web_api_1.LogLevel.DEBUG,
|
|
95
|
+
agent,
|
|
96
|
+
}));
|
|
97
|
+
const result = await slackClient.sendMessage({
|
|
98
|
+
options: {
|
|
99
|
+
channelIds: this.slackChannels,
|
|
100
|
+
customLayout: this.customLayout,
|
|
101
|
+
customLayoutAsync: this.customLayoutAsync,
|
|
102
|
+
maxNumberOfFailures: this.maxNumberOfFailuresToShow,
|
|
103
|
+
disableUnfurl: this.disableUnfurl,
|
|
104
|
+
summaryResults: resultSummary,
|
|
105
|
+
showInThread: this.showInThread,
|
|
106
|
+
},
|
|
107
|
+
});
|
|
108
|
+
// eslint-disable-next-line no-console
|
|
109
|
+
console.log(JSON.stringify(result, null, 2));
|
|
110
|
+
if (this.showInThread && resultSummary.failures.length > 0) {
|
|
111
|
+
await slackClient.attachDetailsToThread({
|
|
112
|
+
channelIds: this.slackChannels,
|
|
113
|
+
ts: result[0].ts,
|
|
114
|
+
summaryResults: resultSummary,
|
|
115
|
+
maxNumberOfFailures: this.maxNumberOfFailuresToShow,
|
|
116
|
+
});
|
|
117
|
+
}
|
|
93
118
|
}
|
|
94
119
|
}
|
|
95
120
|
preChecks() {
|
|
96
121
|
if (this.sendResults === 'off') {
|
|
97
122
|
return { okToProceed: false, message: '❌ Slack reporter is disabled' };
|
|
98
123
|
}
|
|
99
|
-
if (!this.
|
|
124
|
+
if (!this.slackWebHookUrl
|
|
125
|
+
&& !this.slackOAuthToken
|
|
126
|
+
&& !process.env.SLACK_BOT_USER_OAUTH_TOKEN) {
|
|
127
|
+
return {
|
|
128
|
+
okToProceed: false,
|
|
129
|
+
message: '❌ Neither slack webhook url, slackOAuthToken nor process.env.SLACK_BOT_USER_OAUTH_TOKEN were found',
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
if (this.slackWebHookUrl
|
|
133
|
+
&& (process.env.SLACK_BOT_USER_OAUTH_TOKEN || this.slackOAuthToken)) {
|
|
100
134
|
return {
|
|
101
135
|
okToProceed: false,
|
|
102
|
-
message: '❌
|
|
136
|
+
message: '❌ You can only enable a single option, either provide a slack webhook url, slackOAuthToken or process.env.SLACK_BOT_USER_OAUTH_TOKEN were found',
|
|
103
137
|
};
|
|
104
138
|
}
|
|
105
139
|
if (!this.sendResults
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { IncomingWebhook } from '@slack/webhook';
|
|
2
|
+
import { SummaryResults } from '.';
|
|
3
|
+
export default class SlackWebhookClient {
|
|
4
|
+
private webhook;
|
|
5
|
+
constructor(webhook: IncomingWebhook);
|
|
6
|
+
sendMessage({ customLayout, customLayoutAsync, maxNumberOfFailures, summaryResults, disableUnfurl, }: {
|
|
7
|
+
customLayout: Function | undefined;
|
|
8
|
+
customLayoutAsync: Function | undefined;
|
|
9
|
+
maxNumberOfFailures: number;
|
|
10
|
+
summaryResults: SummaryResults;
|
|
11
|
+
disableUnfurl: boolean;
|
|
12
|
+
}): Promise<{
|
|
13
|
+
outcome: string;
|
|
14
|
+
}>;
|
|
15
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const LayoutGenerator_1 = require("./LayoutGenerator");
|
|
4
|
+
class SlackWebhookClient {
|
|
5
|
+
webhook;
|
|
6
|
+
constructor(webhook) {
|
|
7
|
+
this.webhook = webhook;
|
|
8
|
+
}
|
|
9
|
+
async sendMessage({ customLayout, customLayoutAsync, maxNumberOfFailures, summaryResults, disableUnfurl, }) {
|
|
10
|
+
let blocks;
|
|
11
|
+
if (customLayout) {
|
|
12
|
+
blocks = customLayout(summaryResults);
|
|
13
|
+
}
|
|
14
|
+
else if (customLayoutAsync) {
|
|
15
|
+
blocks = await customLayoutAsync(summaryResults);
|
|
16
|
+
}
|
|
17
|
+
else {
|
|
18
|
+
blocks = await (0, LayoutGenerator_1.generateBlocks)(summaryResults, maxNumberOfFailures);
|
|
19
|
+
}
|
|
20
|
+
let result;
|
|
21
|
+
try {
|
|
22
|
+
result = await this.webhook.send({
|
|
23
|
+
blocks,
|
|
24
|
+
unfurl_links: !disableUnfurl,
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
catch (error) {
|
|
28
|
+
return {
|
|
29
|
+
outcome: `error: ${JSON.stringify(error, null, 2)}`,
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
if (result && result.text === 'ok') {
|
|
33
|
+
return {
|
|
34
|
+
outcome: result.text,
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
return {
|
|
38
|
+
outcome: '😵 Failed to send webhook message, ensure your webhook url is valid',
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
exports.default = SlackWebhookClient;
|
package/package.json
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"dependencies": {
|
|
3
3
|
"@slack/web-api": "^6.8.1",
|
|
4
|
+
"@slack/webhook": "^6.1.0",
|
|
4
5
|
"https-proxy-agent": "^7.0.1"
|
|
5
6
|
},
|
|
6
7
|
"devDependencies": {
|
|
@@ -18,7 +19,7 @@
|
|
|
18
19
|
"eslint-plugin-prettier": "^4.2.1",
|
|
19
20
|
"nyc": "^15.1.0",
|
|
20
21
|
"prettier": "^2.7.1",
|
|
21
|
-
"ts-
|
|
22
|
+
"ts-sinon": "^2.0.2",
|
|
22
23
|
"typescript": "^4.7.4"
|
|
23
24
|
},
|
|
24
25
|
"scripts": {
|
|
@@ -28,7 +29,7 @@
|
|
|
28
29
|
"lint": "npx eslint . --ext .ts"
|
|
29
30
|
},
|
|
30
31
|
"name": "playwright-slack-report",
|
|
31
|
-
"version": "1.1.
|
|
32
|
+
"version": "1.1.22",
|
|
32
33
|
"main": "index.js",
|
|
33
34
|
"types": "dist/index.d.ts",
|
|
34
35
|
"repository": "git@github.com:ryanrosello-og/playwright-slack-report.git",
|