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-gatekeeper

v1.0.5

Published

Dependency-aware test orchestration layer for Playwright - skip tests when prerequisites fail

Readme

Playwright Gatekeeper

npm version License: MIT

A lightweight orchestration layer that allows Playwright tests to declare dependencies on "gatekeeper" tests. When a gatekeeper fails, all dependent tests are automatically skipped with clear reporting.

Why This Exists

In E2E testing, some tests are prerequisites for others:

  • If login is broken, testing the dashboard is pointless
  • If the API is down, all API-dependent tests will fail with confusing errors
  • Running 100 tests when a core dependency is broken wastes time and creates noise

This orchestration layer solves these problems by:

  1. Preventing cascading failures - Skip tests whose prerequisites failed
  2. Saving execution time - Don't run tests that can't possibly pass
  3. Clear reporting - Know exactly why tests were skipped

Installation

npm install playwright-gatekeeper

The package uses @playwright/test as a peer dependency, so it will work with whatever Playwright version you have installed (>=1.40.0).


Setup

Add the global setup and reporter to your playwright.config.ts:

import { defineConfig } from '@playwright/test';

export default defineConfig({
  // Initialize gatekeeper state before tests run
  globalSetup: require.resolve('playwright-gatekeeper/setup'),

  // Add the dependency reporter (alongside default reporters)
  reporter: [
    ['list'],
    ['playwright-gatekeeper/reporter'],
  ],

  // Your other config...
});

Usage

Gatekeepers

A gatekeeper is a critical test that other tests depend on. Mark it with markAs():

import { test, expect, markAs } from 'playwright-gatekeeper';

test('Authentication works', async ({ page }) => {
  markAs('auth');  // Register this test as the 'auth' gatekeeper

  await page.goto('/login');
  await page.fill('#username', 'testuser');
  await page.fill('#password', 'password');
  await page.click('button[type="submit"]');
  await expect(page).toHaveURL('/dashboard');
});

Dependent Tests

Use await dependsOn() to declare dependencies. The test will wait for its gatekeepers to complete, then skip if any failed:

import { test, expect, dependsOn } from 'playwright-gatekeeper';

test('Dashboard shows user data', async ({ page }) => {
  await dependsOn('auth');  // Wait for 'auth', skip if it failed

  await page.goto('/dashboard');
  await expect(page.locator('.user-name')).toBeVisible();
});

Multiple Dependencies

test('Admin panel loads', async ({ page }) => {
  await dependsOn('auth', 'api', 'db');  // Wait for all three

  await page.goto('/admin');
});

Chained Dependencies

Gatekeepers can depend on other gatekeepers:

test('API is healthy', async ({ page }) => {
  markAs('api');
  // ...
});

test('Authentication works', async ({ page }) => {
  markAs('auth', ['api']);  // 'auth' depends on 'api'
  // ...
});

test('Dashboard loads', async ({ page }) => {
  await dependsOn('auth');  // If 'api' fails, this skips too
  // ...
});

How It Works

  1. Global setup initializes a shared state file before tests run
  2. Gatekeepers register themselves with markAs() and record pass/fail results
  3. Dependent tests call await dependsOn() which:
    • Waits (polls) until the gatekeeper completes
    • Checks the result
    • Skips the test if the gatekeeper failed
  4. File locking ensures concurrent workers don't corrupt the state
  5. Reporter shows a summary of what failed and what was skipped
┌─────────────────────────────────────────────────────────────────┐
│  Worker 1                    │  Worker 2                       │
├──────────────────────────────┼─────────────────────────────────┤
│  API is healthy              │  Dashboard loads...             │
│    └─ markAs('api')          │    └─ await dependsOn('auth')   │
│    └─ test runs...           │       └─ waiting for auth...    │
│    └─ PASS → write to file   │       └─ still waiting...       │
│                              │                                 │
│  Auth works                  │       └─ auth done! checking... │
│    └─ markAs('auth')         │       └─ auth passed, continue  │
│    └─ PASS → write to file   │    └─ page.goto('/dashboard')   │
└──────────────────────────────┴─────────────────────────────────┘

Example Output

Running 11 tests using 7 workers

  ✓  1 › Gatekeepers › API is healthy
  ✓  2 › Gatekeepers › Authentication works
  ✓  3 › Gatekeepers › Database connection
  ✘  4 › Gatekeepers › Intentionally failing gatekeeper
  ✓  5 › Dashboard Features › Dashboard loads correctly
  ✓  6 › Dashboard Features › User profile displays
  ✓  7 › Settings Features › Settings page loads
  -  8 › Chain Dependency Example › Test depending on failing gatekeeper  ← SKIPPED

══════════════════════════════════════════════════════════════════════
  DEPENDENCY ORCHESTRATION SUMMARY
══════════════════════════════════════════════════════════════════════

  Total: 11 | Passed: 9 | Failed: 1 | Skipped: 1

  Gatekeepers: 4 registered | 3 passed | 1 failed

  ❌ Failed Gatekeepers:
     • will-fail: Expected pattern: /This Will Not Match/

  ⏭️  Tests skipped due to dependencies: 1

     Due to 'will-fail' failure:
       - Test depending on failing gatekeeper

══════════════════════════════════════════════════════════════════════

API Reference

markAs(key: string, dependencies?: string[])

Register the current test as a gatekeeper.

markAs('auth');                    // Simple gatekeeper
markAs('dashboard', ['auth']);     // Gatekeeper that depends on another

await dependsOn(...keys: string[])

Wait for gatekeepers and skip if any failed. Must be awaited.

await dependsOn('auth');              // Single dependency
await dependsOn('auth', 'api', 'db'); // Multiple dependencies

Configuration

The orchestration uses these files (auto-created, gitignored):

  • .playwright-gatekeeper-state.json - Shared state between workers
  • .playwright-gatekeeper-state.lock - File lock for concurrent access

Default timeout for dependsOn() is 30 seconds. Override with:

await dependsOn('slow-gatekeeper', 60000);  // 60 second timeout

Add to your .gitignore:

.playwright-gatekeeper-state.json
.playwright-gatekeeper-state.json.tmp.*
.playwright-gatekeeper-state.lock

Using with trackedTest

For automatic result tracking, use trackedTest instead of test:

import { trackedTest as test, markAs, dependsOn } from 'playwright-gatekeeper';

// Results are automatically recorded when the test completes
test('Auth works', async ({ page }) => {
  markAs('auth');
  // ...
});

License

MIT


Designed and developed by GitHub