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 🙏

© 2026 – Pkg Stats / Ryan Hefner

playwright-easy-selective-tests

v1.1.0

Published

Selective test runner for Playwright based on dependency analysis

Readme

Playwright Easy Selective Tests (PEST)

A powerful tool to easily setup selective test execution in Playwright. PEST analyzes your code dependencies to determine which tests need to run, significantly reducing CI/CD time.

How It Works

  1. Analyse changes: pest analyze analyzes your code changes using the VCS (git by default) and dependency-cruiser to find:
    • Which source files changed
    • Which endpoints/pages are affected by these changes
    • Which test files depend on the changed code
  2. Test Execution: Playwright fixture:
    • Reads the analysis results
    • Skips tests that don't use any modified endpoints
    • Tracks which endpoints each test actually uses using URLs
    • Reports mismatches to keep the endpoint map up to date
  3. Endpoint Mapping: After tests run, worker processes save endpoint usage data which can be merged using pest merge to maintain an accurate map of which tests use which endpoints.

Installation

pnpm add -D playwright-easy-selective-tests
# or
npm install --save-dev playwright-easy-selective-tests
# or
yarn add -D playwright-easy-selective-tests

Do not forget to install peer dependencies:

pnpm add -D dependency-cruiser
# or
npm install --save-dev dependency-cruiser
# or
yarn add -D dependency-cruiser

I assume you already have Playwright installed

Quick Start

1. Initialize Configuration

pnpm pest init

This creates a pest.config.js file. Edit it to match your project:

// pest.config.js
export default {
  vcs: "git",
  baseBranch: "main",
  forceAllTestsFiles: ["playwright.config.js", "src/shared/config.js"],
  exclude: ["node_modules", "dist", ".git"],
  endpointRegex: "^pages/.*\\.tsx?$",
  getEndpointFromFile: undefined,
  testFilesRegex: "^tests/.*\\.spec\\.ts$",
  testEndpointMapFile: "tests/test-endpoints.json",
  projectRoot: undefined,
  includeOnly: undefined,
  getEndpointFromUrl: (url) => {
    try {
      const u = new URL(url, "http://localhost:3000");
      // Next.js serves pages as /about, /, etc. Map to pages/about.js, pages/index.js
      let path = u.pathname;
      if (path === "/") return "pages/index.js";
      if (path.endsWith("/")) path = path.slice(0, -1);
      return `pages${path}.js`;
    } catch {
      return null;
    }
  },
};

2. Undestrand how your endpoints work

The only challenging bit of configuration you need to do is to help PEST match files and urls to endpoints. Endpoint is not necessarily a URL endpoint, but rather a single somewhat decoupled part of your application. For some projects endpoints might be represented by pages (for example, Next.js), other projects can have custom solutions, including monolithic setups with multiple applications in the same project - in this case endpoints may represent those applications. When you are settled with how this should work:

  1. Update endpointRegex in pest.config.js. It should only match paths to your endpoints. For example, ^pages/.*\\.jsx?$ will match all page files in Next.js project and results will look like pages/about/contacts.js. Some projects can have chaotic folder structure. In this case some refactoring might be necessary.

If using a regular expression is not an option, or you have an application that has highly coupled groups of pages, you can implement getEndpointFromFile(file) to implement custom endpoint resolution behaviour.

  1. Create getEndpointFromUrl(url) function. It will be used in fixture in the next step

    This function is necessary to match URLs that are being visited when running the test to endpoints. Endpoint format should always match the results from previous step (be a path to endpoint file if using regex or have the exact same value as getEndpointFromFile).

    getEndpointFromUrl: (url) => {
      try {
        const u = new URL(url, "http://localhost");
        // Example: Next.js serves pages as /about, /, etc. Map to pages/about.js, pages/index.js
        let path = u.pathname;
        if (path === "/") return "pages/index.js";
        if (path.endsWith("/")) path = path.slice(0, -1);
        return `pages${path}.js`;
      } catch {
        return null;
      }
    };

3. Configure Playwright Tests with the Selective Fixture

Add fixture to your extended test:

// tests/test.js
import { test as base } from "@playwright/test";
import { createSelectiveTestFixture } from "playwright-easy-selective-tests/fixture";
// You can use the same config file
import config from "../pest.config.js";

const [selectiveTestFixture, afterAllHook] = createSelectiveTestFixture(config);

export const test = base.extend({
  // Fixture is already configured to run automatically on every test case
  selectiveTestFixture: selectiveTestFixture,
});

// Make sure to also include the hook!
test.afterAll(afterAllHook);

export const expect = base.expect;

It's best to put the fixture as early as possible - otherwise it might take more time to skip a test due to other fixtures.

4. Simply run your tests

All tests fill fail with annotation about mismatch in used endpoints.

5. Merge Endpoint Mappings

After running tests, merge the endpoint mappings produced by the fixture:

pnpm pest merge

This command collects endpoint usage data from all test workers and updates your test-endpoints.json file.

6. Analyze changes before running tests

After making changes make sure to run analysis command:

pnpm pest analyze

This command will generate a temporary file with the list of changed endpoints. This file be later consumed by fixture to tell which tests need to run.

Advanced Usage

CI configuration

To use PEST in CI simply run pnpm pest analyze before running tests.

# .github/workflows/test.yml
name: Analyze changes
run: pnpm pest analyze

name: Run affected tests
run: pnpm playwright test

You might want to also upload directory with temporary files (.pest-temp by default) so that you can use remote run results to update endpoint mapping without running tests locally.

Custom endpoint names

You can implement getEndpointFromFile function in pest.config.js to use custom endpoint names. This may be useful if your project is structured into multiple highly coupled apps with multiple pages (apps/landings/pages/contacts-page.js and apps/landings/pages/index-page.js will both result as landings). See custom endpoints example for reference.

Monorepo Setup

You can provide a custom projectRoot function so that PEST can work within monorepos. projectRoot should include the path from VCS repository root (which should be the same as workspaces root). Only the changes from this path will be taken into account and this path will be omitted from results.

Workspace Dependency Detection

If you are using a monorepo or workspace setup (e.g., with pnpm, yarn, npm workspaces), you can configure PEST to detect changes in dependency packages and automatically run all tests if any dependency package is modified.

Add the workspacePatterns option to your pest.config.js:

export default {
  // ... other config ...
  projectRoot: "apps/web", // relative to workspace root
  workspacePatterns: ["packages/*"], // glob patterns for workspace packages
};

If both workspacePatterns and projectRoot are set, PEST will use @pnpm/fs.find-packages to find all workspace packages and their manifests. If any of these packages change, all tests will be run.

One large caveat is that only direct dependencies are supported at the moment. Contributions are welcome

Programmatic API

Programmatic API can be used, for example, to check how many shards you need to use in your CI flows. Also if you are using shards, this can be helpful to merge endpoint mappings from multiple shards from remotely executed tests.

import {
  loadConfig,
  analyzeChanges,
  mergeEndpointMappings,
} from "playwright-easy-selective-tests";

async function runAnalysis() {
  const config = await loadConfig("./pest.config.js");
  const results = await analyzeChanges(config);
  console.log("Run all tests", results.runAllTests);
  console.log("Affected endpoints:", results.modifiedEndpoints);
  console.log("Affected test files:", results.modifiedTestFiles);
}

// Merge endpoint mappings programmatically
await mergeEndpointMappings(".pest-temp", "test-endpoints.json");

Exports

  • createSelectiveTestFixture — Main Playwright fixture factory
  • mergeEndpointMappings — Programmatic endpoint merging
  • loadConfig, analyzeChanges — Programmatic analysis

Example Project

See examples/next-basic for a full working setup with Playwright and Next.js.

Requirements

  • Node.js >= 18
  • Playwright >= 1.40.0
  • dependency-cruiser >= 12.0.0

Contributing

Contributions are welcome! Share your experience using PEST and help make it more reusable for different projects.

License

MIT