@lytics/playwright-adapters
v1.0.1
Published
Storage adapters for Playwright reporter (filesystem, Slack, Firestore)
Readme
@lytics/playwright-adapters
Storage adapters for the Playwright reporter framework (filesystem, Slack, Firestore).
Installation
npm install @lytics/playwright-adapters
# or
pnpm add @lytics/playwright-adapters
# or
yarn add @lytics/playwright-adaptersAdapters
FilesystemAdapter
Writes test results to JSON files on the local filesystem. Useful for local development, debugging, and CI artifact collection.
Features:
- Creates organized directory structure (
test-results/andtest-runs/) - Pretty-printed JSON by default (configurable)
- Automatic directory creation
- Writes
latest.jsonfor easy access to most recent run - Non-blocking error handling (allows other adapters to continue)
Example:
import { CoreReporter } from '@lytics/playwright-reporter';
import { FilesystemAdapter } from '@lytics/playwright-adapters/filesystem';
export default {
reporter: [
['list'],
[
new CoreReporter({
adapters: [
new FilesystemAdapter({
outputDir: './test-results',
pretty: true, // default: true
}),
],
}),
],
],
};Configuration:
interface FilesystemAdapterConfig {
/** Directory to write test results to (required) */
outputDir: string;
/** Whether to pretty-print JSON (default: true) */
pretty?: boolean;
}Output Structure:
test-results/
├── test-results/
│ ├── TEST-001-2024-01-01T00-00-00.000Z.json
│ ├── TEST-002-2024-01-01T00-01-00.000Z.json
│ └── ...
└── test-runs/
├── test-run-run-123-2024-01-01T00-00-00.000Z.json
├── test-run-run-456-2024-01-01T01-00-00.000Z.json
└── latest.jsonSlackAdapter
Sends test results to Slack channels using @lytics/playwright-slack. Automatically formats test summaries with pass/fail statistics, failed test details, and flaky test tracking.
Features:
- Rich Slack formatting via
@lytics/playwright-slack - Production-only mode (configurable)
- Skip pull request notifications (configurable)
- Automatic flaky test detection
- Failed test details with error messages
- Non-blocking error handling
Example:
import { CoreReporter } from '@lytics/playwright-reporter';
import { FilesystemAdapter } from '@lytics/playwright-adapters/filesystem';
import { SlackAdapter } from '@lytics/playwright-adapters/slack';
export default {
reporter: [
['list'],
[
new CoreReporter({
adapters: [
new FilesystemAdapter({ outputDir: './test-results' }),
new SlackAdapter({
webhookUrl: process.env.SLACK_WEBHOOK_URL,
environment: 'Production',
productionOnly: true, // default: true
skipPullRequests: true, // default: true
dashboardUrl: 'https://dashboard.example.com',
ciJobUrl: process.env.CI_JOB_URL,
artifactBaseUrl: process.env.ARTIFACT_BASE_URL,
triggerType: process.env.TRIGGER_TYPE,
}),
],
}),
],
],
};Configuration:
interface SlackAdapterConfig {
/** Slack webhook URL (can also be set via 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 be set via CI_JOB_URL env var) */
ciJobUrl?: string;
/** Artifact base URL (can also be set via ARTIFACT_BASE_URL env var) */
artifactBaseUrl?: string;
/** Trigger type (can also be set via TRIGGER_TYPE env var) */
triggerType?: string;
}Environment Variables:
The adapter automatically reads from environment variables if not provided in config:
SLACK_WEBHOOK_URL- Slack webhook URL (required)TEST_ENV- Environment name (e.g., 'Production', 'Staging')TRIGGER_TYPE- What triggered the test run (e.g., 'schedule', 'pull_request')CI_JOB_URL- URL to CI job for action linksARTIFACT_BASE_URL- Base URL for test artifacts
Note: This adapter requires @lytics/playwright-slack and @lytics/slack-client to be installed as dependencies.
FirestoreAdapter
Writes test results to Google Cloud Firestore. Supports automatic retry with exponential backoff for transient failures.
Features:
- Writes to three configurable Firestore collections (you define the collection names)
- Automatic retry with exponential backoff for transient failures
- GCP authentication via Application Default Credentials (ADC) or Service Account JSON
- Optional skip conditions (e.g., skip PR runs)
- Non-blocking error handling (allows other adapters to continue)
- Schema-agnostic (you configure your own collection names and structure)
Example:
import { CoreReporter } from '@lytics/playwright-reporter';
import { FirestoreAdapter } from '@lytics/playwright-adapters/firestore';
export default {
reporter: [
['list'],
[
new CoreReporter({
adapters: [
new FirestoreAdapter({
projectId: 'my-gcp-project',
credentials: process.env.GOOGLE_APPLICATION_CREDENTIALS_JSON,
// Configure your own collection names to match your Firestore schema
collections: {
testRuns: 'your_test_runs_collection',
testCases: 'your_test_cases_collection',
latestTestCases: 'your_latest_test_cases_collection',
},
skipConditions: {
skipPullRequests: true,
},
}),
],
}),
],
],
};Configuration:
interface FirestoreAdapterConfig {
/** GCP project ID (required) */
projectId: string;
/** Service account credentials (JSON string or object). If not provided, uses Application Default Credentials */
credentials?: string | Record<string, unknown>;
/** Collection names for different data types (required - configure your own schema) */
collections: {
/** Collection for test run summaries */
testRuns: string;
/** Collection for individual test executions */
testCases: string;
/** Collection for latest test case status */
latestTestCases: string;
};
/** Optional conditions to skip writes */
skipConditions?: {
/** Skip writes for pull requests (default: false) */
skipPullRequests?: boolean;
};
/** Retry configuration */
retry?: {
/** Maximum number of retries (default: 3) */
maxRetries?: number;
/** Initial delay in milliseconds (default: 1000) */
initialDelayMs?: number;
/** Maximum delay in milliseconds (default: 10000) */
maxDelayMs?: number;
};
}Authentication:
The FirestoreAdapter supports two authentication methods:
- Application Default Credentials (ADC) - Recommended: When
credentialsis not provided, the adapter uses Application Default Credentials.
# Set the GOOGLE_APPLICATION_CREDENTIALS environment variable
export GOOGLE_APPLICATION_CREDENTIALS=/path/to/service-account-key.json
# Or use gcloud CLI to authenticate
gcloud auth application-default login- Service Account JSON: Provide service account credentials directly as a JSON string or object.
// From environment variable (JSON string)
new FirestoreAdapter({
projectId: 'my-gcp-project',
credentials: process.env.GOOGLE_APPLICATION_CREDENTIALS_JSON,
});Retry Logic:
The adapter automatically retries failed operations with exponential backoff. Retries are only attempted for transient errors (network issues, rate limits, etc.). Non-retryable errors (authentication, invalid data) fail immediately.
Environment Variables:
TRIGGER_TYPE: Used byskipPullRequestscondition. Set to'pull_request'to skip writes.
Note: This adapter requires @google-cloud/firestore to be installed as a dependency.
Creating Custom Adapters
Adapters implement the ResultAdapter interface:
import type { ResultAdapter, CoreTestResult, CoreTestRun } from '@lytics/playwright-reporter';
export class MyCustomAdapter implements ResultAdapter {
async initialize(): Promise<void> {
// Setup connection, create resources, etc.
}
async writeTestResult(result: CoreTestResult): Promise<void> {
// Write individual test result
}
async writeTestRun(run: CoreTestRun): Promise<void> {
// Write test run summary
}
async close(): Promise<void> {
// Cleanup resources, close connections, etc.
}
}License
MIT
