playwright-slack-report-burak 1.2.2 → 1.2.3
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/dist/src/LayoutGenerator.d.ts +2 -1
- package/dist/src/LayoutGenerator.js +104 -22
- package/dist/src/ResultsParser.d.ts +2 -3
- package/dist/src/ResultsParser.js +3 -20
- package/dist/src/SlackClient.d.ts +8 -0
- package/dist/src/SlackClient.js +24 -0
- package/dist/src/SlackReporter.js +11 -2
- package/dist/src/index.d.ts +3 -15
- package/package.json +1 -1
|
@@ -2,4 +2,5 @@ import { KnownBlock, Block } from '@slack/types';
|
|
|
2
2
|
import { SummaryResults } from '.';
|
|
3
3
|
declare const generateBlocks: (summaryResults: SummaryResults, maxNumberOfFailures: number) => Promise<Array<KnownBlock | Block>>;
|
|
4
4
|
declare const generateFailures: (summaryResults: SummaryResults, maxNumberOfFailures: number) => Promise<Array<KnownBlock | Block>>;
|
|
5
|
-
|
|
5
|
+
declare const generateFailuresReasons: (summaryResults: SummaryResults, maxNumberOfFailures: number) => Promise<Array<KnownBlock | Block>>;
|
|
6
|
+
export { generateBlocks, generateFailures, generateFailuresReasons };
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.generateFailures = exports.
|
|
3
|
+
exports.generateFailures = exports.generateFailuresReasons = exports.generateBlocks = void 0;
|
|
4
4
|
const generateBlocks = async (summaryResults, maxNumberOfFailures) => {
|
|
5
5
|
const meta = [];
|
|
6
6
|
const header = {
|
|
@@ -35,34 +35,116 @@ const generateBlocks = async (summaryResults, maxNumberOfFailures) => {
|
|
|
35
35
|
return [header, summary, ...meta, ...fails];
|
|
36
36
|
};
|
|
37
37
|
exports.generateBlocks = generateBlocks;
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
38
|
+
|
|
39
|
+
/*
|
|
40
|
+
Currently unused but can be used to move failed test name list from main
|
|
41
|
+
message to thread when there are too many for the main message.
|
|
42
|
+
*/
|
|
43
|
+
const generateFailures = async (summaryResults) => {
|
|
44
|
+
const thread = [];
|
|
45
|
+
const failedNamesTitle = [];
|
|
46
|
+
const skippedNamesTitle = [];
|
|
47
|
+
const failsList = [];
|
|
48
|
+
const skipsList = [];
|
|
49
|
+
let previousTestName = undefined;
|
|
50
|
+
let previousSuiteName = undefined;
|
|
51
|
+
|
|
52
|
+
// Create a list for names of failed test cases
|
|
53
|
+
for (const result of summaryResults.tests) {
|
|
54
|
+
if (result.status === 'failed' || result.status === 'timedOut') {
|
|
55
|
+
const testName = result.name;
|
|
56
|
+
const suiteName = result.suiteName;
|
|
57
|
+
const parts = result.suiteName.split('/')[result.suiteName.split('/').length-1].replace('.spec.ts', '');
|
|
58
|
+
const backSlashedParts = parts.split('\\')[parts.split('\\').length-1];
|
|
59
|
+
if (testName !== previousTestName || (testName === previousSuiteName && suiteName !== previousSuiteName) ) {
|
|
60
|
+
failsList.push(testName + ' (' + backSlashedParts + ')');
|
|
61
|
+
previousTestName = testName;
|
|
62
|
+
previousSuiteName = suiteName;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
54
65
|
}
|
|
55
|
-
|
|
56
|
-
|
|
66
|
+
previousTestName = undefined;
|
|
67
|
+
previousSuiteName = undefined;
|
|
68
|
+
|
|
69
|
+
// Create a list for names of skipped test cases
|
|
70
|
+
for (const result of summaryResults.tests) {
|
|
71
|
+
if (result.status === 'skipped') {
|
|
72
|
+
const testName = result.name;
|
|
73
|
+
const suiteName = result.suiteName;
|
|
74
|
+
const parts = result.suiteName.split('/')[result.suiteName.split('/').length-1].replace('.spec.ts', '');
|
|
75
|
+
const backSlashedParts = parts.split('\\')[parts.split('\\').length-1];
|
|
76
|
+
if (testName !== previousTestName || (testName === previousSuiteName && suiteName !== previousSuiteName) ) {
|
|
77
|
+
skipsList.push(testName + ' (' + backSlashedParts + ')');
|
|
78
|
+
previousTestName = testName;
|
|
79
|
+
previousSuiteName = suiteName;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
previousTestName = undefined;
|
|
84
|
+
previousSuiteName = undefined;
|
|
85
|
+
|
|
86
|
+
// Decide on Titles For Listing Failures & Skips
|
|
87
|
+
if (summaryResults.failed === 1) {
|
|
88
|
+
failedNamesTitle[0] = '\n*Failed Test Case:*\n';
|
|
89
|
+
}
|
|
90
|
+
if (summaryResults.failed > 1) {
|
|
91
|
+
failedNamesTitle[0] = '\n*Failed Test Cases:*\n';
|
|
92
|
+
}
|
|
93
|
+
if (summaryResults.skipped === 1) {
|
|
94
|
+
skippedNamesTitle[0] = '\n*Skipped Test Case:*\n';
|
|
95
|
+
}
|
|
96
|
+
if (summaryResults.skipped > 1) {
|
|
97
|
+
skippedNamesTitle[0] = '\n*Skipped Test Cases:*\n';
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
thread.push({
|
|
101
|
+
type: 'section',
|
|
102
|
+
text: {
|
|
103
|
+
type: 'mrkdwn',
|
|
104
|
+
text: `${failedNamesTitle}${failsList.map((value, index) => `*${index + 1}.* ${value}`).join('\n')}` + // List of Failed Test Cases
|
|
105
|
+
`\n${skippedNamesTitle}${skipsList.map((value, index) => `*${index + 1}.* ${value}`).join('\n')} `, // List of Skipped Test Cases
|
|
106
|
+
},
|
|
107
|
+
})
|
|
108
|
+
return [
|
|
109
|
+
...thread,
|
|
110
|
+
];
|
|
111
|
+
};
|
|
112
|
+
|
|
113
|
+
const generateFailuresReasons = async (summaryResults) => {
|
|
114
|
+
const failedNamesTitle = [];
|
|
115
|
+
const failsList = [];
|
|
116
|
+
|
|
117
|
+
for (let i = 0; i < summaryResults.failures.length; i += 1) {
|
|
118
|
+
const { failureReason, test, suiteName } = summaryResults.failures[i];
|
|
119
|
+
const parts = suiteName.split('/')[suiteName.split('/').length-1].replace('.spec.ts', '');
|
|
120
|
+
const backSlashedParts = parts.split('\\')[parts.split('\\').length-1];
|
|
121
|
+
failsList.push({
|
|
57
122
|
type: 'section',
|
|
58
123
|
text: {
|
|
59
124
|
type: 'mrkdwn',
|
|
60
|
-
text:
|
|
125
|
+
text: `${i+1}. ${test.split(' [')[0]} (${backSlashedParts})\n\`\`\`${failureReason}\`\`\``,
|
|
61
126
|
},
|
|
62
127
|
});
|
|
63
128
|
}
|
|
129
|
+
|
|
130
|
+
// Decide on Titles For Listing Failures & Skips
|
|
131
|
+
if (summaryResults.failed === 1) {
|
|
132
|
+
failedNamesTitle[0] = '\n*Failure Reason:*\n';
|
|
133
|
+
}
|
|
134
|
+
if (summaryResults.failed > 1) {
|
|
135
|
+
failedNamesTitle[0] = '\n*Failure Reasons:*\n';
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
failsList.unshift({
|
|
139
|
+
type: 'section',
|
|
140
|
+
text: {
|
|
141
|
+
type: 'mrkdwn',
|
|
142
|
+
text: `${failedNamesTitle}`
|
|
143
|
+
},
|
|
144
|
+
})
|
|
64
145
|
return [
|
|
65
|
-
...
|
|
146
|
+
...failsList,
|
|
66
147
|
];
|
|
67
148
|
};
|
|
68
|
-
exports.generateFailures = generateFailures;
|
|
149
|
+
exports.generateFailures = generateFailures;
|
|
150
|
+
exports.generateFailuresReasons = generateFailuresReasons;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/// <reference types="node" />
|
|
2
|
-
import { failure, flaky, pass,
|
|
2
|
+
import { failure, flaky, pass, SummaryResults } from '.';
|
|
3
3
|
export declare type testResult = {
|
|
4
4
|
suiteName: string;
|
|
5
5
|
name: string;
|
|
@@ -35,8 +35,7 @@ export default class ResultsParser {
|
|
|
35
35
|
getFailures(): Promise<Array<failure>>;
|
|
36
36
|
getFlakes(): Promise<Array<flaky>>;
|
|
37
37
|
getPasses(): Promise<Array<pass>>;
|
|
38
|
-
|
|
39
|
-
static getTestName(failedTest: any): any;
|
|
38
|
+
static getTestName(failedTest: any): any;
|
|
40
39
|
updateResults(data: {
|
|
41
40
|
testSuite: any;
|
|
42
41
|
}): void;
|
|
@@ -17,7 +17,6 @@ class ResultsParser {
|
|
|
17
17
|
const failures = await this.getFailures();
|
|
18
18
|
const flakes = await this.getFlakes();
|
|
19
19
|
let passes = await this.getPasses();
|
|
20
|
-
const skippers = await this.getSkippers();
|
|
21
20
|
/*if (this.separateFlakyTests) {
|
|
22
21
|
passes = this.doSeparateFlakyTests(passes, flakes);
|
|
23
22
|
}*/
|
|
@@ -26,16 +25,16 @@ class ResultsParser {
|
|
|
26
25
|
failed: failures.length,
|
|
27
26
|
flaky: (this.separateFlakyTests && flakes.length > 0) ?
|
|
28
27
|
flakes.length : 0,
|
|
29
|
-
skipped:
|
|
28
|
+
skipped: 0,
|
|
30
29
|
failures,
|
|
31
30
|
tests: [],
|
|
32
31
|
};
|
|
33
32
|
for (const suite of this.result) {
|
|
34
33
|
summary.tests = summary.tests.concat(suite.testSuite.tests);
|
|
35
34
|
for (const test of suite.testSuite.tests) {
|
|
36
|
-
|
|
35
|
+
if (test.status === 'skipped') {
|
|
37
36
|
summary.skipped += 1;
|
|
38
|
-
}
|
|
37
|
+
}
|
|
39
38
|
}
|
|
40
39
|
}
|
|
41
40
|
return summary;
|
|
@@ -86,22 +85,6 @@ class ResultsParser {
|
|
|
86
85
|
}
|
|
87
86
|
return passes;
|
|
88
87
|
}
|
|
89
|
-
|
|
90
|
-
async getSkippers() {
|
|
91
|
-
const skippers = [];
|
|
92
|
-
for (const suite of this.result) {
|
|
93
|
-
for (const test of suite.testSuite.tests) {
|
|
94
|
-
if (test.status === 'skipped') {
|
|
95
|
-
skippers.push({
|
|
96
|
-
test: ResultsParser.getTestName(test),
|
|
97
|
-
});
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
}
|
|
101
|
-
return skippers;
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
|
|
105
88
|
static getTestName(failedTest) {
|
|
106
89
|
const testName = failedTest.name;
|
|
107
90
|
if (failedTest.browser && failedTest.projectName) {
|
|
@@ -33,5 +33,13 @@ export default class SlackClient {
|
|
|
33
33
|
disableUnfurl?: boolean;
|
|
34
34
|
fakeRequest?: Function;
|
|
35
35
|
}): Promise<any[]>;
|
|
36
|
+
attachDetailsToThreadReasons({ channelIds, ts, summaryResults, maxNumberOfFailures, disableUnfurl, fakeRequest, }: {
|
|
37
|
+
channelIds: Array<string>;
|
|
38
|
+
ts: string;
|
|
39
|
+
summaryResults: SummaryResults;
|
|
40
|
+
maxNumberOfFailures: number;
|
|
41
|
+
disableUnfurl?: boolean;
|
|
42
|
+
fakeRequest?: Function;
|
|
43
|
+
}): Promise<any[]>;
|
|
36
44
|
static doPostRequest(slackWebClient: WebClient, channel: string, blocks: Array<KnownBlock | Block>, unfurl: boolean, threadTimestamp?: string): Promise<ChatPostMessageResponse>;
|
|
37
45
|
}
|
package/dist/src/SlackClient.js
CHANGED
|
@@ -87,6 +87,30 @@ class SlackClient {
|
|
|
87
87
|
}
|
|
88
88
|
return result;
|
|
89
89
|
}
|
|
90
|
+
async attachDetailsToThreadReasons({ channelIds, ts, summaryResults, maxNumberOfFailures, disableUnfurl, fakeRequest, }) {
|
|
91
|
+
const result = [];
|
|
92
|
+
const blocks = await (0, LayoutGenerator_1.generateFailuresReasons)(summaryResults, maxNumberOfFailures);
|
|
93
|
+
for (const channel of channelIds) {
|
|
94
|
+
// under test
|
|
95
|
+
let chatResponse;
|
|
96
|
+
if (fakeRequest) {
|
|
97
|
+
chatResponse = await fakeRequest();
|
|
98
|
+
}
|
|
99
|
+
else {
|
|
100
|
+
chatResponse = await SlackClient.doPostRequest(this.slackWebClient, channel, blocks, disableUnfurl, ts);
|
|
101
|
+
}
|
|
102
|
+
if (chatResponse.ok) {
|
|
103
|
+
// eslint-disable-next-line no-console
|
|
104
|
+
console.log(`✅ Message sent to ${channel} within thread ${ts}`);
|
|
105
|
+
result.push({
|
|
106
|
+
channel,
|
|
107
|
+
outcome: `✅ Message sent to ${channel} within thread ${ts}`,
|
|
108
|
+
ts: chatResponse.ts,
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
return result;
|
|
113
|
+
}
|
|
90
114
|
static async doPostRequest(slackWebClient, channel, blocks, unfurl, threadTimestamp) {
|
|
91
115
|
const chatResponse = await slackWebClient.chat.postMessage({
|
|
92
116
|
channel,
|
|
@@ -111,8 +111,8 @@ class SlackReporter {
|
|
|
111
111
|
});
|
|
112
112
|
// eslint-disable-next-line no-console
|
|
113
113
|
console.log(JSON.stringify(result, null, 2));
|
|
114
|
-
if (this.showInThread && resultSummary.failures.length > 0) {
|
|
115
|
-
for (let i = 0; i < result.length; i += 1) {
|
|
114
|
+
if (this.showInThread && (resultSummary.failures.length > 0 || resultSummary.skipped > 0)) {
|
|
115
|
+
/* for (let i = 0; i < result.length; i += 1) {
|
|
116
116
|
// eslint-disable-next-line no-await-in-loop
|
|
117
117
|
await slackClient.attachDetailsToThread({
|
|
118
118
|
channelIds: [result[i].channel],
|
|
@@ -120,6 +120,15 @@ class SlackReporter {
|
|
|
120
120
|
summaryResults: resultSummary,
|
|
121
121
|
maxNumberOfFailures: this.maxNumberOfFailuresToShow,
|
|
122
122
|
});
|
|
123
|
+
}*/
|
|
124
|
+
for (let i = 0; i < result.length; i += 1) {
|
|
125
|
+
// eslint-disable-next-line no-await-in-loop
|
|
126
|
+
await slackClient.attachDetailsToThreadReasons({
|
|
127
|
+
channelIds: [result[i].channel],
|
|
128
|
+
ts: result[i].ts,
|
|
129
|
+
summaryResults: resultSummary,
|
|
130
|
+
maxNumberOfFailures: this.maxNumberOfFailuresToShow,
|
|
131
|
+
});
|
|
123
132
|
}
|
|
124
133
|
}
|
|
125
134
|
}
|
package/dist/src/index.d.ts
CHANGED
|
@@ -2,11 +2,9 @@
|
|
|
2
2
|
export declare type SummaryResults = {
|
|
3
3
|
passed: number;
|
|
4
4
|
failed: number;
|
|
5
|
-
flaky: number
|
|
5
|
+
flaky: number;
|
|
6
6
|
skipped: number;
|
|
7
7
|
failures: Array<failure>;
|
|
8
|
-
skippers: Array<skipper>;
|
|
9
|
-
flakers: Array<flaker>;
|
|
10
8
|
meta?: Array<{
|
|
11
9
|
key: string;
|
|
12
10
|
value: string;
|
|
@@ -32,23 +30,13 @@ export declare type SummaryResults = {
|
|
|
32
30
|
export declare type failure = {
|
|
33
31
|
test: string;
|
|
34
32
|
failureReason: string;
|
|
33
|
+
retries: number;
|
|
34
|
+
suiteName: string;
|
|
35
35
|
};
|
|
36
|
-
|
|
37
|
-
export declare type skipper = {
|
|
38
|
-
test: string;
|
|
39
|
-
skipperReason: string;
|
|
40
|
-
};
|
|
41
|
-
|
|
42
|
-
export declare type flaker = {
|
|
43
|
-
test: string;
|
|
44
|
-
flakerReason: string;
|
|
45
|
-
};
|
|
46
|
-
|
|
47
36
|
export declare type flaky = {
|
|
48
37
|
test: string;
|
|
49
38
|
retry: number;
|
|
50
39
|
};
|
|
51
|
-
|
|
52
40
|
export declare type pass = {
|
|
53
41
|
test: string;
|
|
54
42
|
};
|
package/package.json
CHANGED
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
"lint-fix": "npx eslint . --ext .ts --fix"
|
|
31
31
|
},
|
|
32
32
|
"name": "playwright-slack-report-burak",
|
|
33
|
-
"version": "1.2.
|
|
33
|
+
"version": "1.2.3",
|
|
34
34
|
"main": "index.js",
|
|
35
35
|
"types": "dist/index.d.ts",
|
|
36
36
|
"repository": "git@github.com:ryanrosello-og/playwright-slack-report.git",
|