跳至主要內容

Slack 報告器

wdio-slack-reporter 是一個第三方套件,如需更多資訊,請參閱 GitHub | npm

version downloads license webdriverio

來自 WebdriverIO 的報告器,使用 Incoming webhookWeb API 將結果傳送到 Slack
此套件與 WebdriverIO 6.x 及以上版本相容。

Slack 通知螢幕擷取畫面

Notification

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...',
},
}
],
],
};

組態選項

支援以下組態選項。若要傳送通知,您必須設定 webhookweb-api。如果同時設定 web-apiwebhook,則會使用 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:writefiles: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 中篩選出來並傳送到執行緒。(如果沒有篩選器(陣列為空或未定義),則會套用所有篩選器。) 篩選器清單passedfailedpendingskipped

  • 範圍:web-api
  • 類型:陣列 (passed | failed | pending | skipped)
  • 預設值:['passed', 'failed', 'pending', 'skipped']

createScreenshotPayload (選用)

此選項自訂上傳的螢幕擷取畫面有效負載,用於測試失敗。

  • 範圍:web-api
  • 類型:function

createResultDetailPayload (選用)

此選項自訂已通知的測試詳細結果的有效負載。

  • 範圍:web-api
  • 類型:function

通用

title (選用)

將此選項設定為測試標題。

  • 範圍:webhookweb-api
  • 類型:string

resultsUrl (選用)

提供測試結果的連結。它是通知中可點擊的連結。

  • 範圍:webhookweb-api
  • 類型:string

notifyTestStartMessage (選用)

將此選項設為 true 以傳送通知測試開始。

  • 範圍:webhookweb-api
  • 類型:boolean
  • 預設值:true

notifyFailedCase (選用)

將此選項設為 true,以在報告給 Slack 的測試結果中附加失敗案例。

  • 範圍:webhookweb-api
  • 類型:boolean
  • 預設值:true

notifyTestFinishMessage (選用)

將此選項設為 true 以傳送通知測試完成。

  • 範圍:webhookweb-api
  • 類型:boolean
  • 預設值:true

useScenarioBasedStateCounts (選填) - 僅限 Cucumber

將此選項設定為 true,即可將狀態計數從以測試(步驟)為基礎改為以情境為基礎。(僅限 Cucumber)

  • 範圍:webhookweb-api
  • 類型:boolean
  • 預設值:false

emojiSymbols (選填)

此選項可變更預設的表情符號集。

  • 範圍:webhookweb-api
  • 類型:object
  • 預設值
    • passed - ✅ :white_check_mark:
    • failed - ❌ :x:
    • skipped - ⏸ :double_vertical_bar:
    • pending - ❔ :grey_question:
    • start - 🚀 :rocket:
    • finished - 🏁 :checkered_flag:
    • watch - ⏱ :stopwatch:

createStartPayload (選填)

此選項可自訂在測試開始時通知的酬載。

  • 範圍:webhookweb-api
  • 類型:function

createFailedTestPayload (選填)

此選項可自訂在測試失敗時通知的酬載。

  • 範圍:webhookweb-api
  • 類型:function

createResultPayload (選填)

此選項可自訂在測試結果通知時的酬載。

  • 範圍:webhookweb-api
  • 類型:function

使用傳入 Webhook

如果您正在使用 webhook,則無法使用執行緒和上傳功能。
因此,與 uploadthread 相關的功能將無法使用。

組態範例

// 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 中設定 reporterSyncIntervalreporterSyncTimeout

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);
}
}
}

歡迎!有什麼我可以幫您的嗎?

WebdriverIO AI Copilot