Slack 報告器
來自 WebdriverIO 的報告器,使用 Incoming webhook 和 Web API 將結果傳送到 Slack。
此套件與 WebdriverIO 6.x 及以上版本相容。
Slack 通知螢幕擷取畫面

WebdriverIO 4.x 或更低版本相容性
此專案與 WebdriverIO 6.x 及以上版本相容。
如果您使用 4.x 或更低版本,請使用 wdio-slack-reporter。
安裝
最簡單的方法是將 @moroo/wdio-slack-reporter
保留在您的 package.json
中作為 devDependency。
{
"devDependencies": {
"@moroo/wdio-slack-reporter": "8.1.0"
}
}
您可以透過以下方式簡單地完成:
- NPM
npm install @moroo/wdio-slack-reporter --save-dev
- Yarn
yarn add -D @moroo/wdio-slack-reporter
有關如何安裝 WebdriverIO
的說明,請參閱此處。
組態設定
在 wdio.conf.js 檔案的頂部,新增
ES6
// wdio.conf.js
import SlackReporter from '@moroo/wdio-slack-reporter';
為了使用報告器,您需要在 wdio.conf.js 中的 reporters 陣列中新增 slack
// 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...',
},
}
],
],
};
組態選項
支援以下組態選項。若要傳送通知,您必須設定 webhook
或 web-api
。如果同時設定 web-api
和 webhook
,則會使用 web-api
。
Webhook (傳入 Webhook)
webhook (必要
)
應該傳送通知的 slack 頻道的傳入 Webhook。如果未設定 URL,則不會傳送通知。
- 範圍:
webhook
- 類型:
string
slackName (選用
)
username 的值將在 slack 通知中顯示為傳送者。
- 範圍:
webhook
- 類型:
string
- 預設值:
"WebdriverIO 報告器"
slackIconUrl (選用
)
要在 slack 中顯示的圖示 URL
- 範圍:
webhook
- 類型:
string
- 預設值:
"https://webdriverio.dev.org.tw/img/webdriverio.png"
Web API (Slack 機器人)
slackBotToken (必要
)
應該傳送通知的 slack 頻道的 Web API。需要機器人使用者權杖。機器人存取權杖一律以 xoxb
開頭。機器人權杖需要 chat:write
、files:write
的 OAuth 範圍。更多詳細資訊請參閱下方。
- 範圍:
web-api
- 類型:
string
channel (必要
)
要將訊息傳送到的頻道、私人群組或 IM 頻道。可以是編碼的 ID 或名稱。更多詳細資訊請參閱下方。 「如何尋找頻道 ID」 - stackoverflow -
- 範圍:
web-api
- 類型:
string
uploadScreenshotOfFailedCase (選用
)
將此選項設為 true 以將螢幕擷取畫面附加到失敗的案例。
- 範圍:
web-api
- 類型:
boolean
- 預設值:
true
notifyDetailResultThread (選用
)
此選項僅在 notifyTestFinishMessage 選項為 true 時有效。
如果想要在張貼到 Slack 的測試結果通知中新增包含結果詳細資訊的執行緒,請將此選項設為 true。
- 範圍:
web-api
- 類型:
boolean
- 預設值:
true
filterForDetailResults (選用
)
此選項僅在 notifyDetailResultThread 選項為 true 時有效。
將您想要的篩選器新增至此選項的陣列,詳細結果將在 Slack 中篩選出來並傳送到執行緒。(如果沒有篩選器(陣列為空或未定義),則會套用所有篩選器。) 篩選器清單:passed
、failed
、pending
、skipped
- 範圍:
web-api
- 類型:
陣列 (passed | failed | pending | skipped)
- 預設值:
['passed', 'failed', 'pending', 'skipped']
createScreenshotPayload (選用
)
此選項自訂上傳的螢幕擷取畫面有效負載,用於測試失敗。
- 範圍:
web-api
- 類型:
function
createResultDetailPayload (選用
)
此選項自訂已通知的測試詳細結果的有效負載。
- 範圍:
web-api
- 類型:
function
通用
title (選用
)
將此選項設定為測試標題。
- 範圍:
webhook
、web-api
- 類型:
string
resultsUrl (選用
)
提供測試結果的連結。它是通知中可點擊的連結。
- 範圍:
webhook
、web-api
- 類型:
string
notifyTestStartMessage (選用
)
將此選項設為 true 以傳送通知測試開始。
- 範圍:
webhook
、web-api
- 類型:
boolean
- 預設值:
true
notifyFailedCase (選用
)
將此選項設為 true,以在報告給 Slack 的測試結果中附加失敗案例。
- 範圍:
webhook
、web-api
- 類型:
boolean
- 預設值:
true
notifyTestFinishMessage (選用
)
將此選項設為 true 以傳送通知測試完成。
- 範圍:
webhook
、web-api
- 類型:
boolean
- 預設值:
true
useScenarioBasedStateCounts (選填
) - 僅限 Cucumber
將此選項設定為 true,即可將狀態計數從以測試(步驟)為基礎改為以情境為基礎。(僅限 Cucumber)
- 範圍:
webhook
、web-api
- 類型:
boolean
- 預設值:
false
emojiSymbols (選填
)
此選項可變更預設的表情符號集。
- 範圍:
webhook
、web-api
- 類型:
object
- 預設值
- passed - ✅
:white_check_mark:
- failed - ❌
:x:
- skipped - ⏸
:double_vertical_bar:
- pending - ❔
:grey_question:
- start - 🚀
:rocket:
- finished - 🏁
:checkered_flag:
- watch - ⏱
:stopwatch:
- passed - ✅
createStartPayload (選填
)
此選項可自訂在測試開始時通知的酬載。
- 範圍:
webhook
、web-api
- 類型:
function
createFailedTestPayload (選填
)
此選項可自訂在測試失敗時通知的酬載。
- 範圍:
webhook
、web-api
- 類型:
function
createResultPayload (選填
)
此選項可自訂在測試結果通知時的酬載。
- 範圍:
webhook
、web-api
- 類型:
function
使用傳入 Webhook
如果您正在使用 webhook,則無法使用執行緒和上傳功能。
因此,與 upload
和 thread
相關的功能將無法使用。
組態範例
// wdio.conf.js
import SlackReporter from "@moroo/wdio-slack-reporter";
export.config = {
reporters: [
[
SlackReporter, {
// Set the Slack Options used webhook.
slackOptions: {
type: 'webhook',
webhook: process.env.SLACK_WEBHOOK_URL || "https://hooks.slack.com/........",
slackName: "WebdriverIO Reporter",
slackIconUrl: "https://webdriverio.dev.org.tw/img/webdriverio.png",
},
// Set the Title of Test.
title: 'Slack Reporter Test',
// Set the Test Results URL.
resultsUrl: process.env.JENKINS_URL,
// Set the notification of Test Finished
notifyTestFinishMessage: true,
// Set the scenario-based state count (Only Cucumber)
useScenarioBasedStateCounts: true,
// Customize Slack Emoji Symbols.
emojiSymbols: {
passed: ':white_check_mark:',
failed: ':x:',
skipped: ':double_vertical_bar:',
pending: ':grey_question:',
start: ':rocket:',
finished: ':checkered_flag:',
watch: ':stopwatch:'
},
// Override the createStartPayload function.
createStartPayload: function (runnerStats: RunnerStats): IncomingWebhookSendArguments {
const payload: IncomingWebhookSendArguments = {
// do something...
}
return payload;
},
// Override the createFailedTestPayload function.
createFailedTestPayload: function (testStats: TestStats): IncomingWebhookSendArguments {
const payload: IncomingWebhookSendArguments = {
// do something...
}
return payload;
},
// Override the createResultPayload function.
createResultPayload: function (runnerStats: RunnerStats, stateCounts: StateCount): IncomingWebhookSendArguments {
const payload: IncomingWebhookSendArguments = {
// do something...
}
return payload;
}
}
],
],
};
使用 Web API
若要使用 API,您需要如下的 scopes。
chat:write
, files:write
. 請參閱下方以了解更多詳細資訊。
組態範例
// wdio.conf.js
import SlackReporter from "@moroo/wdio-slack-reporter";
export.config = {
reporters: [
[
SlackReporter, {
// Set the Slack Options used web-api.
slackOptions: {
type: 'web-api',
slackBotToken: process.env.SLACK_BOT_TOKEN || "xoxb-xxxxxxxxxx-xxxxxx...",,
channel: process.env.SLACK_CHANNEL || "Cxxxxxxxxxx",
// Set this option to true to attach a screenshot to the failed case.
uploadScreenshotOfFailedCase: true,
// Set this option to true if you want to add thread with details of results to notification of test results posted to Slack.
notifyDetailResultThread: true,
// Set the Filter for detail results. (array is empty or undefined, all filters are applied.)
filterForDetailResults: [
'passed',
'failed',
'pending',
'skipped'
],
// Override the createScreenshotPayload function.
createScreenshotPayload: function (testStats: TestStats, screenshotBuffer: Buffer): FilesUploadArguments {
const payload: FilesUploadArguments = {
// do something...
}
return payload;
},
// Override the createResultDetailPayload function.
createResultDetailPayload: function (runnerStats: RunnerStats, stateCounts: StateCount): ChatPostMessageArguments {
const payload: ChatPostMessageArguments = {
// do something...
}
return payload;
}
},
// Set the Title of Test.
title: 'Slack Reporter Test',
// Set the Test Results URL.
resultsUrl: process.env.JENKINS_URL,
// Set the notification of Test Finished
notifyTestFinishMessage: true,
// Set the scenario-based state count (Only Cucumber)
useScenarioBasedStateCounts: true,
// Customize Slack Emoji Symbols.
emojiSymbols: {
passed: ':white_check_mark:',
failed: ':x:',
skipped: ':double_vertical_bar:',
pending: ':grey_question:',
start: ':rocket:',
finished: ':checkered_flag:',
watch: ':stopwatch:'
},
// Override the createStartPayload function.
createStartPayload: function (runnerStats: RunnerStats): IncomingWebhookSendArguments {
const payload: IncomingWebhookSendArguments = {
// do something...
}
return payload;
},
// Override the createFailedTestPayload function.
createFailedTestPayload: function (testStats: TestStats): IncomingWebhookSendArguments {
const payload: IncomingWebhookSendArguments = {
// do something...
}
return payload;
},
// Override the createResultPayload function.
createResultPayload: function (runnerStats: RunnerStats, stateCounts: StateCount): IncomingWebhookSendArguments {
const payload: IncomingWebhookSendArguments = {
// do something...
}
return payload;
}
}
],
],
};
支援的 API
getResultsUrl
類型:
() => string | undefined
取得結果網址。
// getResultsUrl.spec.ts
import SlackReporter from '@moroo/wdio-slack-reporter';
describe('Get the resultsUrl value', function () {
before(function () {
const resultsUrl = SlackReporter.getResultsUrl();
if (resultsUrl) {
// do something...
}
});
it('Do something', function () {
// do something...
});
});
setResultsUrl
類型:
(url: string) => void
設定結果網址。
(如果測試結果的網址每次都變更,則此功能會很有用。)
// setResultsUrl.spec.ts
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 () {
// do something...
});
});
uploadFailedTestScreenshot
類型:
(data: string | Buffer) => void
將螢幕截圖以執行緒的方式新增至失敗測試通知。
(如果您正在使用 webhook,這會列印警告且不會執行任何動作。)
// terminal console
WARN @moroo/slack-wdio-reporter: Not using web-api or disabled notifyFailedCase or uploadScreenshotOfFailedCase options.
// wdio.conf.js
export.config = {
afterTest: async function (test, context, result) {
if (error) {
const result = await browser.takeScreenshot();
SlackReporter.uploadFailedTestScreenshot(result);
}
}
}
postMessage
類型:
(payload: ChatPostMessageArguments) => Promise<WebAPICallResult>
將訊息發佈至 Slack。
(如果您正在使用 webhook,這會擲回錯誤。)
// terminal console
ERROR @moroo/slack-wdio-reporter: Not using web-api.
// post.spec.ts
import SlackReporter, {
ChatPostMessageArguments,
WebAPICallResult,
} from '@moroo/wdio-slack-reporter';
describe('Post Function Test', function () {
it('Post a message', async function () {
const payload: ChatPostMessageArguments = {
// do something...
};
const result: WebAPICallResult = await SlackReporter.post(payload);
});
});
upload
類型:
(payload: FilesUploadArguments) => Promise<WebAPICallResult>
將檔案上傳至 Slack。
(如果您正在使用 webhook,這會擲回錯誤。)
// terminal console
ERROR @moroo/slack-wdio-reporter: Not using web-api.
// upload.spec.ts
import SlackReporter, {
FilesUploadArguments,
WebAPICallResult,
} from '@moroo/wdio-slack-reporter';
describe('Upload Function Test', function () {
it('Upload a files', async function () {
const payload: FilesUploadArguments = {
// do something...
};
const result: WebAPICallResult = await SlackReporter.upload(payload);
});
});
send
類型:
(payload: IncomingWebhookSendArguments) => Promise<IncomingWebhookResult>
將訊息傳送至 Slack。
(如果您正在使用 web-api,這會擲回錯誤。)
// terminal console
ERROR @moroo/slack-wdio-reporter: Not using webhook.
// send.spec.ts
import SlackReporter, {
IncomingWebhookSendArguments,
IncomingWebhookResult,
} from '@moroo/wdio-slack-reporter';
describe('Sand Function Test', function () {
it('Send a message', async function () {
const payload: IncomingWebhookSendArguments = {
// do something...
};
const result: IncomingWebhookResult = await SlackReporter.send(payload);
});
});
新增螢幕截圖
如果您想將螢幕截圖以執行緒的方式新增至失敗測試通知,請在擷取螢幕截圖後新增 uploadFailedTestScreenshot
函式。
// wdio.conf.js
export.config = {
afterTest: async function (test, context, result) {
if (error) {
const result = await browser.takeScreenshot();
SlackReporter.uploadFailedTestScreenshot(result);
}
}
}
已知問題
未同步
如果發生以下錯誤,請在 wdio.conf.js
中設定 reporterSyncInterval
和 reporterSyncTimeout
。
ERROR @wdio/runner: Error: Some reporters are still unsynced: SlackReporter
//wdio.conf.js
export.config = {
//
// Determines in which interval the reporter should check if they are synchronized if they report their logs asynchronously (e.g. if logs are streamed to a 3rd party vendor).
reporterSyncInterval: 500,
// Determines the maximum time reporters have to finish uploading all their logs until an error is being thrown by the testrunner.
reporterSyncTimeout: 20000,
}
Jasmine 選項 - expectationResultHandler
在此處新增 uploadFailedTestScreenshot 函式也無法運作。
這是因為函式會在每次測試後執行,因此目前測試未知。
// wdio.conf.js
export.config = {
jasmineOpts: {
// Jasmine default timeout
defaultTimeoutInterval: 60000,
//
// The Jasmine framework allows interception of each assertion in order to log the state of the application
// or website depending on the result. For example, it is pretty handy to take a screenshot every time
// an assertion fails.
expectationResultHandler: function (passed, assertion) {
if (passed) {
return;
}
/*
Adding the uploadFailedTestScreenshot function here doesn't work either.
This is because the function works after every test, so the current test is unknown.
[x] const result = await browser.takeScreenshot();
[x] SlackReporter.uploadFailedTestScreenshot(result);
*/
},
},
// Add it here.
afterTest: async function (test, context, result) {
if (result.error) {
const result = await browser.takeScreenshot();
SlackReporter.uploadFailedTestScreenshot(result);
}
}
}