Simple and Effective Playwright Reporter via Telegram Bot
Send your Playwright test results directly to Telegram with flexible reporting options.
- 🚀 Simple Setup - Just add to your Playwright config
- 📊 Multiple Report Types - Simple, Summary, or Detailed reports
- 🎨 Custom Formatters - Full control over message formatting
- ⚙️ Configurable Triggers - Send always, only on failure, or only on success
- 🔒 Zero Dependencies - Uses native Node.js fetch (requires Node.js 18+)
- 📦 TypeScript Support - Full type definitions included
npm install @b3nab/playwright-telegram-reporter
# or
pnpm add @b3nab/playwright-telegram-reporter
# or
yarn add @b3nab/playwright-telegram-reporter- Node.js 18+ - Required for native fetch support
- Telegram Bot Token - Get one from @BotFather
- Chat ID - The Telegram chat where messages will be sent
- Open Telegram and search for @BotFather
- Send
/newbotcommand - Follow the prompts to create your bot
- Copy the bot token provided
- Start a chat with your bot or add it to a group
- Send any message to the chat
- Visit:
https://api.telegram.org/bot<YOUR_BOT_TOKEN>/getUpdates - Look for the
chat.idfield in the JSON response
The simplest way to add the reporter to your playwright.config.ts:
import { defineConfig } from '@playwright/test';
export default defineConfig({
reporter: [
['list'], // Keep the default list reporter for console output
[
'@b3nab/playwright-telegram-reporter',
{
botToken: process.env.TELEGRAM_BOT_TOKEN,
chatId: process.env.TELEGRAM_CHAT_ID,
},
],
],
// ... other config
});TELEGRAM_BOT_TOKEN=your_bot_token_here
TELEGRAM_CHAT_ID=your_chat_id_hereChoose from three built-in report types:
export default defineConfig({
reporter: [
['@b3nab/playwright-telegram-reporter', {
botToken: process.env.TELEGRAM_BOT_TOKEN,
chatId: process.env.TELEGRAM_CHAT_ID,
reportType: 'simple',
}]
],
});Output:
✅ Test run passed
export default defineConfig({
reporter: [
['@b3nab/playwright-telegram-reporter', {
botToken: process.env.TELEGRAM_BOT_TOKEN,
chatId: process.env.TELEGRAM_CHAT_ID,
reportType: 'summary',
}]
],
});Output:
✅ Playwright Test Results
Status: PASSED
Duration: 12.45s
📊 Summary:
• Total: 15
• Passed: 15
• Failed: 0
• Skipped: 0
export default defineConfig({
reporter: [
['@b3nab/playwright-telegram-reporter', {
botToken: process.env.TELEGRAM_BOT_TOKEN,
chatId: process.env.TELEGRAM_CHAT_ID,
reportType: 'detailed',
}]
],
});Output includes summary statistics and all individual test names with durations, plus full error messages for failures:
✅ Playwright Test Results
Status: PASSED
Duration: 12.45s
📊 Summary:
• Total: 15
• Passed: 13
• Failed: 2
• Skipped: 0
❌ FAILED (2):
• Auth Tests › Login with invalid credentials (3.21s)
Error: Expected "error" but got "success"
at page.locator...
...
• API Tests › API returns 404 (1.15s)
Error: Request failed with status 404
✅ PASSED (13):
• Home Page › Homepage loads correctly (0.85s)
• Home Page › Navigation menu works (1.20s)
• Search › Search functionality (2.30s)
• Auth Tests › User can logout (0.95s)
...
Note: You can customize the title using the
titleoption and test name format using thetestFormatoption (see below).
For complete control over the message format:
import { defineConfig } from '@playwright/test';
import type { FullResult, Suite } from '@playwright/test/reporter';
export default defineConfig({
reporter: [
['@b3nab/playwright-telegram-reporter', {
botToken: process.env.TELEGRAM_BOT_TOKEN,
chatId: process.env.TELEGRAM_CHAT_ID,
customFormatter: (result: FullResult, suite: Suite) => {
const tests = suite.allTests();
return `🎭 Custom Report
Tests completed: ${tests.length}
Status: ${result.status}
Time: ${new Date().toLocaleString()}
Custom message here!`;
},
}]
],
});Control when reports are sent:
export default defineConfig({
reporter: [
['@b3nab/playwright-telegram-reporter', {
botToken: process.env.TELEGRAM_BOT_TOKEN,
chatId: process.env.TELEGRAM_CHAT_ID,
sendOn: 'always', // 'always' | 'failure' | 'success'
}]
],
});always(default) - Send report on every test runfailure- Only send when tests failsuccess- Only send when all tests pass
Customize the report title (first line):
export default defineConfig({
reporter: [
['@b3nab/playwright-telegram-reporter', {
botToken: process.env.TELEGRAM_BOT_TOKEN,
chatId: process.env.TELEGRAM_CHAT_ID,
title: '🎭 My Test Suite', // Simple string
}]
],
});Or use a function for dynamic titles based on pass/fail:
export default defineConfig({
reporter: [
['@b3nab/playwright-telegram-reporter', {
botToken: process.env.TELEGRAM_BOT_TOKEN,
chatId: process.env.TELEGRAM_CHAT_ID,
title: (passed) => passed ? '✅ All Tests Passed!' : '❌ Tests Failed',
}]
],
});Customize how test names appear in detailed reports:
export default defineConfig({
reporter: [
['@b3nab/playwright-telegram-reporter', {
botToken: process.env.TELEGRAM_BOT_TOKEN,
chatId: process.env.TELEGRAM_CHAT_ID,
reportType: 'detailed',
testFormat: '{GROUP} › {TEST} ({TIME})', // Default
}]
],
});Available variables:
{GROUP}- Test suite/group (e.g.,Example Tests){TEST}- Test name (e.g.,has heading){TIME}- Duration (e.g.,0.58s){BROWSER}- Browser/project (e.g.,chromium){FILENAME}- File name (e.g.,example.spec.ts)
Example formats:
| Format | Output |
|---|---|
{GROUP} › {TEST} ({TIME}) |
Example Tests › has heading (0.58s) |
{TEST} ({TIME}) |
has heading (0.58s) |
{BROWSER} | {TEST} |
chromium | has heading |
{FILENAME} › {TEST} |
example.spec.ts › has heading |
import { defineConfig } from '@playwright/test';
import type { TelegramReporterOptions } from '@b3nab/playwright-telegram-reporter';
export default defineConfig({
testDir: './tests',
reporter: [
['html'],
['list'],
[
'@b3nab/playwright-telegram-reporter',
{
botToken: process.env.TELEGRAM_BOT_TOKEN || '',
chatId: process.env.TELEGRAM_CHAT_ID || '',
reportType: 'summary',
sendOn: 'always',
} satisfies TelegramReporterOptions,
],
],
use: {
baseURL: 'https://example.com',
trace: 'on-first-retry',
},
});Full TypeScript definitions are included. Import types for better type safety:
import type {
TelegramReporterOptions,
ReportType,
SendOn,
} from '@b3nab/playwright-telegram-reporter';
const options: TelegramReporterOptions = {
botToken: 'your-token',
chatId: 'your-chat-id',
reportType: 'summary',
sendOn: 'failure',
};You can also use the satisfies operator for inline type checking:
import { defineConfig } from '@playwright/test';
import type { TelegramReporterOptions } from '@b3nab/playwright-telegram-reporter';
export default defineConfig({
reporter: [
[
'@b3nab/playwright-telegram-reporter',
{
botToken: process.env.TELEGRAM_BOT_TOKEN || '',
chatId: process.env.TELEGRAM_CHAT_ID || '',
reportType: 'detailed',
sendOn: 'failure',
} satisfies TelegramReporterOptions,
],
],
});| Option | Type | Required | Default | Description |
|---|---|---|---|---|
botToken |
string |
✅ Yes | - | Telegram Bot Token from @BotFather |
chatId |
string |
✅ Yes | - | Telegram Chat ID where messages are sent |
reportType |
'simple' | 'summary' | 'detailed' |
No | 'detailed' |
Report type: simple (pass/fail), summary (counts + duration), detailed (all tests + summary) |
customFormatter |
(result, suite) => string |
No | - | Custom function to format the entire message |
sendOn |
'always' | 'failure' | 'success' |
No | 'always' |
When to send: always, failure only, or success only |
title |
string | ((passed) => string) |
No | '✅/❌ Playwright Test Results' |
Custom title for the report. Can be string or function |
testFormat |
string |
No | '{GROUP} › {TEST} ({TIME})' |
Template for test names. Variables: {GROUP}, {TEST}, {TIME}, {BROWSER}, {FILENAME} |
Contributions are welcome! Please feel free to submit a Pull Request.
# Clone the repository
git clone https://github.com/b3nab/playwright-telegram-reporter.git
cd playwright-telegram-reporter
# Install dependencies
pnpm install
# Run linter
pnpm run lint
# Build the project
pnpm run build
# Run tests (requires Telegram credentials)
pnpm testAGPL-3.0-only
Benedetto Abbenanti
- Website: ben.abbenanti.com