@moroo/wdio-slack-reporter
![webdriverio](https://img.shields.io/static/v1?color=EA5906&label=WebdriverIO&message=%3E=6.0&logo=webdriverio)
Reporter from WebdriverIO using Incoming webhook and Web API to send results to Slack.
This package is Compatible with WebdriverIO version 6.x and above.
Slack notification screenshot
![Notification Image Notification](https://raw.githubusercontent.com/morooLee/wdio-slack-reporter/master/docs/Notification.png)
WebdriverIO 4.x or lower Compatibility
This project is Compatible with WebdriverIO version 6.x and above.
If you are using 4.x or lower, use to wdio-slack-reporter.
Installation
The easiest way is to keep @moroo/wdio-slack-reporter
as a devDependency in your package.json
.
{
"devDependencies": {
"@moroo/wdio-slack-reporter": "8.1.0"
}
}
You can simple do it by:
npm install @moroo/wdio-slack-reporter --save-dev
yarn add -D @moroo/wdio-slack-reporter
Instructions on how to install WebdriverIO
can be found here.
Configuration
At the top of the wdio.conf.js-file, add:
ES6
import SlackReporter from '@moroo/wdio-slack-reporter';
In order to use the reporter you need to add slack to your reporters array in wdio.conf.js
export.config = {
reporters: [
[
SlackReporter,
{
slackOptions: {
type: 'web-api',
channel: process.env.SLACK_CHANNEL || 'Cxxxxxxxxxx',
slackBotToken: process.env.SLACK_BOT_TOKEN || 'xoxb-xxxxxxxxxx-xxxxxx...',
},
}
],
],
};
Configuration Options
The following configuration options are supported.
For notifications to be sent, You must set webhook
or web-api
.
If both web-api
and webhook
are set, web-api
is used.
Webhook (Incoming Webhook)
webhook (Required
)
Incoming Webhook of the slack channel to which notifications should be sent. If the URL is not configured, notifications will not be sent.
- Scope:
webhook
- Type:
string
slackName (Optional
)
The value of username will appear in the slack notification as the user who sent it.
- Scope:
webhook
- Type:
string
- Default:
"WebdriverIO Reporter"
slackIconUrl (Optional
)
The url of the Icon to be displayed in the slack
- Scope:
webhook
- Type:
string
- Default:
"https://webdriver.io/img/webdriverio.png"
Web API (Slack Bot)
slackBotToken (Required
)
Web API of the slack channel to which notifications should be sent. A bot user token is required. Bot access tokens always begin with xoxb
.
The bot token requires the OAuth scope of chat:write
, files:write
.
See below for more details.
- Scope:
web-api
- Type:
string
channel (Required
)
Channel, private group, or IM channel to send message to. Can be an encoded ID, or a name. See below for more details.
"How to find channel ID" - stackoverflow -
- Scope:
web-api
- Type:
string
uploadScreenshotOfFailedCase (Optional
)
Set this option to true to attach a screenshot to the failed case.
- Scope:
web-api
- Type:
boolean
- Default:
true
notifyDetailResultThread (Optional
)
This option only works when the notifyTestFinishMessage option is true.
Set this option to true if you want to add thread with details of results to notification of test results posted to Slack.
- Scope:
web-api
- Type:
boolean
- Default:
true
filterForDetailResults (Optional
)
This option only works when the notifyDetailResultThread option is true.
Add the filter you want to this option to the array and the detailed results will be filtered out in Slack and sent to the thread.
(If there are no filters (array is empty or undefined), all filters are applied.)
Filter list: passed
, failed
, pending
, skipped
- Scope:
web-api
- Type:
array (passed | failed | pending | skipped)
- Default:
['passed', 'failed', 'pending', 'skipped']
createScreenshotPayload (Optional
)
This option customizes the payload that is uploaded of the screenshot for the failure of the test.
- Scope:
web-api
- Type:
function
createResultDetailPayload (Optional
)
This option customizes the payload that is notified of the detailed results of the test.
- Scope:
web-api
- Type:
function
Common
title (Optional
)
Set this option to the test title.
- Scope:
webhook
, web-api
- Type:
string
resultsUrl (Optional
)
Provide a link to the test results. It is a clickable link in the notification.
- Scope:
webhook
, web-api
- Type:
string
notifyTestStartMessage (Optional
)
Set this option to true to send notifications test start.
- Scope:
webhook
, web-api
- Type:
boolean
- Default:
true
notifyFailedCase (Optional
)
Set this option to true to attach failed cases in the test results reported to Slack.
- Scope:
webhook
, web-api
- Type:
boolean
- Default:
true
notifyTestFinishMessage (Optional
)
Set this option to true to send notifications test finished.
- Scope:
webhook
, web-api
- Type:
boolean
- Default:
true
useScenarioBasedStateCounts (Optional
) - Only Cucumber
Set this option to true to change the state count from test (steps) based to scenario-based. (Only Cucumber)
- Scope:
webhook
, web-api
- Type:
boolean
- Default:
false
emojiSymbols (Optional
)
This option changes the emoji set by default.
- Scope:
webhook
, web-api
- Type:
object
- Default:
- passed - ✅
:white_check_mark:
- failed - ❌
:x:
- skipped - ⏸
:double_vertical_bar:
- pending - ❔
:grey_question:
- start - 🚀
:rocket:
- finished - 🏁
:checkered_flag:
- watch - ⏱
:stopwatch:
createStartPayload (Optional
)
This option customizes the payload that is notified at the start of the test.
- Scope:
webhook
, web-api
- Type:
function
createFailedTestPayload (Optional
)
This option customizes the payload that is notified at the failure of the test.
- Scope:
webhook
, web-api
- Type:
function
createResultPayload (Optional
)
This option customizes the payload that is notified of the results of the test.
- Scope:
webhook
, web-api
- Type:
function
Use the Incoming Webhook
If you are using webhook, can not thread and upload.
Therefore, functions related to upload
and thread
are not available.
Configuration Example
import SlackReporter from "@moroo/wdio-slack-reporter";
export.config = {
reporters: [
[
SlackReporter, {
slackOptions: {
type: 'webhook',
webhook: process.env.SLACK_WEBHOOK_URL || "https://hooks.slack.com/........",
slackName: "WebdriverIO Reporter",
slackIconUrl: "https://webdriver.io/img/webdriverio.png",
},
title: 'Slack Reporter Test',
resultsUrl: process.env.JENKINS_URL,
notifyTestFinishMessage: true,
useScenarioBasedStateCounts: true,
emojiSymbols: {
passed: ':white_check_mark:',
failed: ':x:',
skipped: ':double_vertical_bar:',
pending: ':grey_question:',
start: ':rocket:',
finished: ':checkered_flag:',
watch: ':stopwatch:'
},
createStartPayload: function (runnerStats: RunnerStats): IncomingWebhookSendArguments {
const payload: IncomingWebhookSendArguments = {
}
return payload;
},
createFailedTestPayload: function (testStats: TestStats): IncomingWebhookSendArguments {
const payload: IncomingWebhookSendArguments = {
}
return payload;
},
createResultPayload: function (runnerStats: RunnerStats, stateCounts: StateCount): IncomingWebhookSendArguments {
const payload: IncomingWebhookSendArguments = {
}
return payload;
}
}
],
],
};
Use the Web API
To use the api, you need a scopes like the one below.
chat:write
, files:write
. See below for more details.
Configuration Example
import SlackReporter from "@moroo/wdio-slack-reporter";
export.config = {
reporters: [
[
SlackReporter, {
slackOptions: {
type: 'web-api',
slackBotToken: process.env.SLACK_BOT_TOKEN || "xoxb-xxxxxxxxxx-xxxxxx...",,
channel: process.env.SLACK_CHANNEL || "Cxxxxxxxxxx",
uploadScreenshotOfFailedCase: true,
notifyDetailResultThread: true,
filterForDetailResults: [
'passed',
'failed',
'pending',
'skipped'
],
createScreenshotPayload: function (testStats: TestStats, screenshotBuffer: Buffer): FilesUploadArguments {
const payload: FilesUploadArguments = {
}
return payload;
},
createResultDetailPayload: function (runnerStats: RunnerStats, stateCounts: StateCount): ChatPostMessageArguments {
const payload: ChatPostMessageArguments = {
}
return payload;
}
},
title: 'Slack Reporter Test',
resultsUrl: process.env.JENKINS_URL,
notifyTestFinishMessage: true,
useScenarioBasedStateCounts: true,
emojiSymbols: {
passed: ':white_check_mark:',
failed: ':x:',
skipped: ':double_vertical_bar:',
pending: ':grey_question:',
start: ':rocket:',
finished: ':checkered_flag:',
watch: ':stopwatch:'
},
createStartPayload: function (runnerStats: RunnerStats): IncomingWebhookSendArguments {
const payload: IncomingWebhookSendArguments = {
}
return payload;
},
createFailedTestPayload: function (testStats: TestStats): IncomingWebhookSendArguments {
const payload: IncomingWebhookSendArguments = {
}
return payload;
},
createResultPayload: function (runnerStats: RunnerStats, stateCounts: StateCount): IncomingWebhookSendArguments {
const payload: IncomingWebhookSendArguments = {
}
return payload;
}
}
],
],
};
Supported API
getResultsUrl
type: () => string | undefined
Get the results url.
import SlackReporter from '@moroo/wdio-slack-reporter';
describe('Get the resultsUrl value', function () {
before(function () {
const resultsUrl = SlackReporter.getResultsUrl();
if (resultsUrl) {
}
});
it('Do something', function () {
});
});
setResultsUrl
type: (url: string) => void
Set the results url.
(This is useful if the url with test results changes every time.)
import SlackReporter from '@moroo/wdio-slack-reporter';
import { RESULTS_URL } from '../constants';
describe('Set the resultsUrl value', function () {
before(function () {
const resultsUrl = RESULTS_URL + new Date().toISOString();
SlackReporter.setResultsUrl(resultsUrl);
});
it('Do something', function () {
});
});
uploadFailedTestScreenshot
type: (data: string | Buffer) => void
Add a screenshot as a thread to the failed test notification.
(If you are using a webhook this will print a warning and do nothing.)
// terminal console
WARN @moroo/slack-wdio-reporter: Not using web-api or disabled notifyFailedCase or uploadScreenshotOfFailedCase options.
export.config = {
afterTest: async function (test, context, result) {
if (error) {
const result = await browser.takeScreenshot();
SlackReporter.uploadFailedTestScreenshot(result);
}
}
}
postMessage
type: (payload: ChatPostMessageArguments) => Promise<WebAPICallResult>
Post a message to Slack.
(If you are using a webhook this will throw an error.)
// terminal console
ERROR @moroo/slack-wdio-reporter: Not using web-api.
import SlackReporter, {
ChatPostMessageArguments,
WebAPICallResult,
} from '@moroo/wdio-slack-reporter';
describe('Post Function Test', function () {
it('Post a message', async function () {
const payload: ChatPostMessageArguments = {
};
const result: WebAPICallResult = await SlackReporter.post(payload);
});
});
upload
type: (payload: FilesUploadArguments) => Promise<WebAPICallResult>
Upload a file to Slack.
(If you are using a webhook this will throw an error.)
// terminal console
ERROR @moroo/slack-wdio-reporter: Not using web-api.
import SlackReporter, {
FilesUploadArguments,
WebAPICallResult,
} from '@moroo/wdio-slack-reporter';
describe('Upload Function Test', function () {
it('Upload a files', async function () {
const payload: FilesUploadArguments = {
};
const result: WebAPICallResult = await SlackReporter.upload(payload);
});
});
send
type: (payload: IncomingWebhookSendArguments) => Promise<IncomingWebhookResult>
Send a message to Slack.
(If you are using a web-api this will throw an error.)
// terminal console
ERROR @moroo/slack-wdio-reporter: Not using webhook.
import SlackReporter, {
IncomingWebhookSendArguments,
IncomingWebhookResult,
} from '@moroo/wdio-slack-reporter';
describe('Sand Function Test', function () {
it('Send a message', async function () {
const payload: IncomingWebhookSendArguments = {
};
const result: IncomingWebhookResult = await SlackReporter.send(payload);
});
});
Add Screenshot
If you want to add a screenshot as a thread to the failed test notification, added the uploadFailedTestScreenshot
function after taking the screenshot.
export.config = {
afterTest: async function (test, context, result) {
if (error) {
const result = await browser.takeScreenshot();
SlackReporter.uploadFailedTestScreenshot(result);
}
}
}
Known Issues
Unsynced
If the following error occurs, set reporterSyncInterval
, reporterSyncTimeout
in wdio.conf.js
.
ERROR @wdio/runner: Error: Some reporters are still unsynced: SlackReporter
export.config = {
reporterSyncInterval: 500,
reporterSyncTimeout: 20000,
}
Jasmine Option - expectationResultHandler
Adding the uploadFailedTestScreenshot function here doesn't work either.
This is because the function works after every test, so the current test is unknown.
export.config = {
jasmineOpts: {
defaultTimeoutInterval: 60000,
expectationResultHandler: function (passed, assertion) {
if (passed) {
return;
}
},
},
afterTest: async function (test, context, result) {
if (result.error) {
const result = await browser.takeScreenshot();
SlackReporter.uploadFailedTestScreenshot(result);
}
}
}