npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

@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-adapters

Adapters

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/ and test-runs/)
  • Pretty-printed JSON by default (configurable)
  • Automatic directory creation
  • Writes latest.json for 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.json

SlackAdapter

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 links
  • ARTIFACT_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:

  1. Application Default Credentials (ADC) - Recommended: When credentials is 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
  1. 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 by skipPullRequests condition. 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