yasin-playwright-slack-report
Version:
Send Slack notifications with Playwright test results using a custom reporter.
120 lines (109 loc) • 3.04 kB
text/typescript
import { Reporter, TestResult, FullResult, TestCase } from '@playwright/test/reporter';
import axios from 'axios';
interface SlackReporterOptions {
webhookUrl: string;
buildId?: string;
branchName?: string;
htmlReportUrl?: string;
}
class SlackReporter implements Reporter {
private webhookUrl: string;
private buildId?: string;
private branchName?: string;
private htmlReportUrl?: string;
private passed = 0;
private failed = 0;
private skipped = 0;
constructor(options: SlackReporterOptions) {
this.webhookUrl = options.webhookUrl;
this.buildId = options.buildId;
this.branchName = options.branchName;
this.htmlReportUrl = options.htmlReportUrl;
}
onTestEnd(_: TestCase, result: TestResult) {
switch (result.status) {
case 'passed':
this.passed++;
break;
case 'failed':
this.failed++;
break;
case 'skipped':
this.skipped++;
break;
}
}
async onEnd(result: FullResult) {
const total = this.passed + this.failed + this.skipped;
const passPercent = total > 0 ? Math.round((this.passed / total) * 100) : 0;
const blocks: any[] = [
{
type: "section",
text: {
type: "mrkdwn",
text: `*🎭 Playwright Test Results*`,
},
},
{
type: "section",
fields: [
{
type: "mrkdwn",
text: `*✅ Passed:* ${this.passed}`,
},
{
type: "mrkdwn",
text: `*❌ Failed:* ${this.failed}`,
},
{
type: "mrkdwn",
text: `*⏭ Skipped:* ${this.skipped}`,
},
{
type: "mrkdwn",
text: `*🕒 Duration:* ${(result.duration / 1000).toFixed(2)}s`,
},
{
type: "mrkdwn",
text: `*📦 Build:* ${this.buildId ?? "N/A"}`,
},
{
type: "mrkdwn",
text: `*🌿 Branch:* ${this.branchName ?? "N/A"}`,
},
],
},
{
type: "section",
text: {
type: "mrkdwn",
text: `*📊 Pass Rate:* ${passPercent}%`,
},
},
{
type: "image",
image_url: `https://quickchart.io/chart?c={type:'doughnut',data:{labels:['Passed','Failed'],datasets:[{data:[${this.passed},${this.failed}],backgroundColor:['#2ecc71','#e74c3c']}]},options:{plugins:{legend:{display:true}}}}`,
alt_text: "Pass/Fail Chart"
}
];
if (this.htmlReportUrl) {
blocks.push({
type: "section",
text: {
type: "mrkdwn",
text: `🔗 *HTML Report:* <${this.htmlReportUrl}|View Report>`,
},
});
}
try {
await axios.post(this.webhookUrl, {
text: `Playwright Test Summary`,
blocks: blocks,
});
console.log('✅ Slack report sent.');
} catch (error) {
console.error('❌ Failed to send Slack report:', error);
}
}
}
export default SlackReporter;