SlackAdapter
Sends test results to Slack channels using rich formatting.
Installation
import { SlackAdapter } from '@lytics/playwright-adapters/slack';This adapter requires @lytics/playwright-slack and @lytics/slack-client as peer dependencies. These are included when you install @lytics/playwright-adapters.
Overview
The SlackAdapter sends formatted test summaries to Slack, including:
- âś… Pass/fail statistics
- ❌ Failed test details with error messages
- ⚠️ Flaky test tracking
- đź”— Links to CI jobs and artifacts
Configuration
interface SlackAdapterConfig {
/** Slack webhook URL (can also use SLACK_WEBHOOK_URL env var) */
webhookUrl?: string;
/** Environment label (defaults to TEST_ENV or 'Production') */
environment?: string;
/** Only send notifications in production (default: true) */
productionOnly?: boolean;
/** Skip notifications for pull requests (default: true) */
skipPullRequests?: boolean;
/** Dashboard URL for test reports */
dashboardUrl?: string;
/** CI job URL (can also use CI_JOB_URL env var) */
ciJobUrl?: string;
/** Artifact base URL (can also use ARTIFACT_BASE_URL env var) */
artifactBaseUrl?: string;
/** Trigger type (can also use TRIGGER_TYPE env var) */
triggerType?: string;
}Usage
Basic Usage
Create a reporter file:
// reporter.ts
import { CoreReporter } from '@lytics/playwright-reporter';
import { SlackAdapter } from '@lytics/playwright-adapters/slack';
class CustomReporter extends CoreReporter {
constructor() {
super({
adapters: [
new SlackAdapter({
webhookUrl: process.env.SLACK_WEBHOOK_URL!,
}),
],
});
}
}
export default CustomReporter;Reference it in your config:
// playwright.config.ts
export default {
reporter: [['list'], ['./reporter.ts']],
};Production Configuration
new SlackAdapter({
webhookUrl: process.env.SLACK_WEBHOOK_URL,
environment: 'Production',
productionOnly: true, // Only notify in production
skipPullRequests: true, // Don't notify for PR runs
dashboardUrl: 'https://dashboard.example.com',
ciJobUrl: process.env.CI_JOB_URL,
artifactBaseUrl: process.env.ARTIFACT_BASE_URL,
})Always Notify
For staging or development environments:
new SlackAdapter({
webhookUrl: process.env.SLACK_WEBHOOK_URL,
environment: 'Staging',
productionOnly: false, // Notify in all environments
skipPullRequests: false, // Notify for PR runs too
})Environment Variables
The adapter reads these environment variables if config values aren’t provided:
| Variable | Config Key | Description |
|---|---|---|
SLACK_WEBHOOK_URL | webhookUrl | Slack webhook URL (required) |
TEST_ENV | environment | Environment name |
TRIGGER_TYPE | triggerType | What triggered the run |
CI_JOB_URL | ciJobUrl | URL to CI job |
ARTIFACT_BASE_URL | artifactBaseUrl | Base URL for artifacts |
Features
Production-Only Mode
By default, notifications are only sent when environment is 'Production':
new SlackAdapter({
webhookUrl: process.env.SLACK_WEBHOOK_URL,
environment: process.env.TEST_ENV, // 'Production', 'Staging', etc.
productionOnly: true, // Only notify if environment === 'Production'
})Skip Pull Requests
Skip notifications for PR test runs:
new SlackAdapter({
webhookUrl: process.env.SLACK_WEBHOOK_URL,
skipPullRequests: true,
triggerType: process.env.TRIGGER_TYPE, // 'pull_request', 'schedule', etc.
})When triggerType is 'pull_request', no notification is sent.
Rich Formatting
The adapter formats messages with:
- Header — Environment and overall status
- Stats — Total, passed, failed, skipped counts
- Pass Rate — Percentage with visual indicator
- Failed Tests — List of failures with error summaries
- Flaky Tests — Tests that passed after retry
- Action Buttons — Links to CI job, artifacts, dashboard
Flaky Test Detection
Tests that fail initially but pass on retry are marked as flaky:
⚠️ Flaky Tests (2)
• ACCOUNT_SECURITY_VIEW-TOKENS_VALID
• USER_MANAGEMENT_CREATE-USER_EDGEMessage Format
Example Slack message:
🎠Playwright Test Results - Production
📊 Summary
• Total: 50 tests
• ✅ Passed: 48
• ❌ Failed: 2
• âŹď¸Ź Skipped: 0
• Pass Rate: 96%
❌ Failed Tests (2)
1. ACCOUNT_SECURITY_VIEW-TOKENS_EMPTY
Expected element to be visible
2. USER_MANAGEMENT_DELETE-USER_INVALID
Timeout waiting for selector
⚠️ Flaky Tests (1)
• DATA_PIPELINES_CREATE-JOB_VALID
[View CI Job] [View Artifacts] [View Dashboard]CI/CD Integration
GitHub Actions
env:
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
TEST_ENV: Production
TRIGGER_TYPE: ${{ github.event_name }}
CI_JOB_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
ARTIFACT_BASE_URL: https://artifacts.example.com/${{ github.run_id }}GitLab CI
variables:
SLACK_WEBHOOK_URL: $SLACK_WEBHOOK_URL
TEST_ENV: Production
TRIGGER_TYPE: $CI_PIPELINE_SOURCE
CI_JOB_URL: $CI_JOB_URL
ARTIFACT_BASE_URL: $CI_PROJECT_URL/-/jobs/$CI_JOB_ID/artifacts/browseCreating a Slack Webhook
- Go to Slack APIÂ
- Create a new app or select existing
- Enable Incoming Webhooks
- Add a new webhook to your workspace
- Select the channel for notifications
- Copy the webhook URL
Security: Store the webhook URL as a secret in your CI/CD system. Never commit it to your repository.
Troubleshooting
No notifications received
Possible causes:
- productionOnly is true — Check that
environmentequals'Production' - skipPullRequests is true — Check that
triggerTypeisn’t'pull_request' - Invalid webhook URL — Verify the webhook URL is correct
- Network issues — Check firewall/proxy settings
Debug:
new SlackAdapter({
webhookUrl: process.env.SLACK_WEBHOOK_URL,
productionOnly: false, // Disable for testing
skipPullRequests: false, // Disable for testing
})Webhook URL not found
Cause: Neither config nor environment variable provides the URL.
Solution: Set SLACK_WEBHOOK_URL environment variable or pass webhookUrl in config.
Rate limiting
Cause: Too many messages sent too quickly.
Solution: Slack webhooks have rate limits. The adapter sends one message per test run, which should be well within limits.
Best Practices
1. Use Environment-Specific Channels
const channel = process.env.TEST_ENV === 'Production'
? process.env.SLACK_CHANNEL_PROD
: process.env.SLACK_CHANNEL_DEV;2. Include Useful Links
new SlackAdapter({
webhookUrl: process.env.SLACK_WEBHOOK_URL,
dashboardUrl: 'https://dashboard.example.com',
ciJobUrl: process.env.CI_JOB_URL,
artifactBaseUrl: process.env.ARTIFACT_BASE_URL,
})3. Filter Noise
new SlackAdapter({
webhookUrl: process.env.SLACK_WEBHOOK_URL,
productionOnly: true, // Only production
skipPullRequests: true, // Skip PR runs
})