Skip to content

Commit 2e857f1

Browse files
feat: Slack plugin improvements (#3499)
1 parent 18d0775 commit 2e857f1

File tree

1 file changed

+93
-64
lines changed

1 file changed

+93
-64
lines changed

packages/artillery-plugin-slack/index.js

Lines changed: 93 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -52,14 +52,18 @@ class SlackPlugin {
5252
this.exitCode = 1;
5353
}
5454
this.ensureChecks.failed += 1;
55-
this.ensureChecks.checkList.push(
56-
`:x: \`${check.original}\`${check.strict ? '' : ' (optional) '}`
57-
);
55+
this.ensureChecks.checkList.push({
56+
text: check.original,
57+
passed: false,
58+
optional: !check.strict
59+
});
5860
} else {
5961
this.ensureChecks.passed += 1;
60-
this.ensureChecks.checkList.push(
61-
`:white_check_mark: \`${check.original}\``
62-
);
62+
this.ensureChecks.checkList.push({
63+
text: check.original,
64+
passed: true,
65+
optional: false
66+
});
6367
}
6468
});
6569

@@ -95,106 +99,131 @@ class SlackPlugin {
9599
for (const [key, value] of Object.entries(report.counters).filter(
96100
([key, value]) => key.startsWith('errors.')
97101
)) {
98-
errorList.push(`${key.replace('errors.', '')}: ${value}`);
102+
errorList.push(`${key.replace('errors.', '')} (${value})`);
99103
}
100104
return errorList;
101105
}
102106

103107
assembleSlackPayload(report, ensureChecks) {
104108
const errorList = this.getErrors(report);
105109
const duration = report.lastMetricAt - report.firstMetricAt;
106-
const introText =
110+
const headerText =
107111
this.exitCode === 0
108112
? '🟢 Artillery test run finished'
109113
: '🔴 Artillery test run failed';
110114

111115
const payloadTemplate = {
112-
text: introText,
116+
text: headerText,
113117
blocks: [
114118
{
115-
type: 'rich_text',
116-
elements: [
117-
{
118-
type: 'rich_text_section',
119-
elements: [
120-
{
121-
type: 'text',
122-
text: introText,
123-
style: {
124-
bold: true
125-
}
126-
}
127-
]
128-
}
129-
]
130-
},
131-
{
132-
type: 'section',
119+
type: 'header',
133120
text: {
134-
type: 'mrkdwn',
135-
text: `Duration: ${this.formatDuration(duration)}`
121+
type: 'plain_text',
122+
text: headerText,
123+
emoji: true
136124
}
137125
}
138126
]
139127
};
140128

141-
if (this.cloudEnabled) {
142-
payloadTemplate.blocks.push({
143-
type: 'section',
144-
text: {
145-
type: 'mrkdwn',
146-
text: `<${this.cloudTestRunUrl}>`
147-
}
148-
});
129+
let errorsText;
130+
if (errorList.length === 0) {
131+
errorsText = '*Errors*\nNone';
132+
} else {
133+
// Only show first 10 errors to avoid Slack message length limit
134+
const maxErrors = 10;
135+
const trimmedList = errorList.slice(0, maxErrors);
136+
137+
if (errorList.length > maxErrors) {
138+
trimmedList.push(`➕ ${errorList.length - maxErrors} more…`);
139+
}
140+
141+
errorsText = `*Errors (${errorList.length})*\n\`\`\`\n${trimmedList.join(
142+
'\n'
143+
)}\n\`\`\``;
149144
}
150145

151146
const metricBlocks = [
152-
{
153-
type: 'divider'
154-
},
155147
{
156148
type: 'section',
157149
fields: [
158150
{
159151
type: 'mrkdwn',
160-
text: `*${report.counters['vusers.completed']} / ${report.counters['vusers.created']}*\nVUs completed / created`
152+
text: `*VUs*\n${report.counters['vusers.completed']} completed / ${report.counters['vusers.created']} created`
161153
},
162154
{
163155
type: 'mrkdwn',
164-
text: `*Errors*\n${
165-
errorList.length !== 0 ? errorList.join('\n') : '0'
166-
}`
156+
text: `*Duration*\n${this.formatDuration(duration)}`
167157
}
168158
]
169-
},
170-
{
171-
type: 'divider'
172159
}
173160
];
174161

162+
let checksText = '*Checks*\nNone defined';
163+
175164
if (this.ensureChecks) {
176-
metricBlocks.push(
177-
...[
178-
{
179-
type: 'section',
180-
fields: [
181-
{
182-
type: 'mrkdwn',
183-
text: `*Checks (${ensureChecks.passed} / ${
184-
ensureChecks.total
185-
})*\n${this.ensureChecks.checkList.join('\n')}`
186-
}
187-
]
188-
},
165+
// Show summary if more than 10 checks to avoid Slack message length limit
166+
if (this.ensureChecks.total > 10) {
167+
let summaryText = '';
168+
169+
if (ensureChecks.passed > 0) {
170+
summaryText += `🟢 ${ensureChecks.passed} checks passed\n`;
171+
}
172+
173+
if (ensureChecks.failed > 0) {
174+
summaryText += `🔴 ${ensureChecks.failed} checks failed`;
175+
}
176+
177+
summaryText = summaryText.trim();
178+
checksText = `*Checks (${ensureChecks.passed}/${ensureChecks.total})*\n\`\`\`\n${summaryText}\n\`\`\``;
179+
} else {
180+
const formattedChecks = this.ensureChecks.checkList.map(
181+
(check) =>
182+
`${check.passed ? '🟢' : '🔴'} ${check.text}${
183+
check.optional ? ' (optional)' : ''
184+
}`
185+
);
186+
187+
checksText = `*Checks (${ensureChecks.passed} / ${
188+
ensureChecks.total
189+
})*\n\`\`\`\n${formattedChecks.join('\n')}\n\`\`\``;
190+
}
191+
}
192+
193+
metricBlocks.push({
194+
type: 'section',
195+
fields: [
196+
{
197+
type: 'mrkdwn',
198+
text: checksText
199+
},
200+
{
201+
type: 'mrkdwn',
202+
text: errorsText
203+
}
204+
]
205+
});
206+
207+
payloadTemplate.blocks = payloadTemplate.blocks.concat(metricBlocks);
208+
209+
if (this.cloudEnabled) {
210+
payloadTemplate.blocks.push({
211+
type: 'actions',
212+
elements: [
189213
{
190-
type: 'divider'
214+
type: 'button',
215+
text: {
216+
type: 'plain_text',
217+
text: 'See report on Artillery Cloud',
218+
emoji: true
219+
},
220+
url: this.cloudTestRunUrl,
221+
style: 'primary'
191222
}
192223
]
193-
);
224+
});
194225
}
195226

196-
payloadTemplate.blocks = payloadTemplate.blocks.concat(metricBlocks);
197-
198227
return JSON.stringify(payloadTemplate);
199228
}
200229

0 commit comments

Comments
 (0)