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