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-ai-resilience

v0.1.1

Published

Deterministic self-healing wrapper for Playwright selectors. Catches TimeoutErrors, recovers via heuristic DOM scoring, verifies intent.

Readme

# playwright-ai-resilience

Your Playwright tests passed yesterday.  
Today a frontend engineer renamed `#checkout-btn` to `data-testid="checkout-v2"`.  
Your CI pipeline is red. Your deploy is blocked.

This package catches `TimeoutError`, scans the local DOM for the closest semantic match using a deterministic heuristic engine, verifies the outcome, and heals the workflow — with zero cloud dependencies, zero API keys, and zero hosted infrastructure.

---

## Install

```bash
npm install playwright-ai-resilience

Add to .gitignore:

.resilience/recovery-log.jsonl

Commit .resilience/baselines.json — it's your team's shared selector memory.


Usage

import { safeAssert, verify } from 'playwright-ai-resilience';

// Before — breaks when the selector is renamed
await page.click('#checkout-btn');

// After — records a fingerprint on the first green run,
//         recovers from mutations on subsequent broken runs
await safeAssert(page, {
  selector: '#checkout-btn',
  action: (locator) => locator.click(),
  verify: verify.urlTransition(/.*\/payment/),
  riskLevel: 'high',
});

How it works

First green run: safeAssert succeeds normally, then silently records a fingerprint of the element to .resilience/baselines.json.

Later, when the selector breaks: The engine loads the stored fingerprint, scores up to 30 nearby DOM candidates using text, ARIA, structural, and spatial signals, picks the best match above the risk threshold, clicks it, and verifies the result.

If verification fails: The engine rolls back page state and throws the original error — your test suite is never silently corrupted.


Suggest Mode (start here)

Not ready to auto-execute? Run in suggest mode. The engine identifies the recovery candidate and prints it — no click happens.

await safeAssert(page, {
  selector: '#checkout-btn',
  action: (locator) => locator.click(),
  mode: 'suggest',
});
  ╔═══ playwright-ai-resilience ══════════════════════╗
  ✖  Original selector failed: #checkout-btn
  ↺  Scanning DOM neighborhood... 30 candidates found

  → [1] ████████░░ 0.872  [data-testid="checkout-v2"]  "pay now"
    [2] ████░░░░░░ 0.412  button.cancel-btn              "cancel"
    [3] ██░░░░░░░░ 0.201  a.nav-link                     "checkout"

  ⚠  [SUGGEST MODE] No action executed. To heal, use mode: "execute"
  ╚═══════════════════════════════════════════════════╝

Risk Levels

| Level | Score Threshold | Auto-Execute | | --- | --- | --- | | low | > 0.60 | Yes | | medium | > 0.75 | Yes | | high | > 0.90 | Yes | | critical | any | No — suggest only |

Selectors containing delete, remove, pay, transfer, or password are never auto-healed without riskLevel: 'critical'.


Verify Helpers

verify.urlTransition(/.*\/payment/)        // Waits for URL regex match
verify.elementVisible('.success-toast')    // Waits for element to appear
verify.networkRequest('/api/checkout')     // Waits for network request

CLI

npx resilience status                  # Show how many baselines are recorded
npx resilience list                    # List all recorded selectors
npx resilience log                     # Show last 20 recovery events
npx resilience clear '#checkout-btn'   # Delete one baseline
npx resilience clear-all               # Delete all baselines

Disable healing per-action

await safeAssert(page, {
  selector: '#payment-submit',
  action: (locator) => locator.click(),
  healing: 'disabled',   // Will throw on failure, never attempt recovery
});

What gets stored

.resilience/baselines.json stores a minimal fingerprint per selector — no raw HTML, no screenshots, no computed CSS. Example entry:

{
  "selector": "#checkout-btn",
  "tag": "button",
  "semanticTokens": ["pay", "now"],
  "textHash": "a3f9c2b1d4e8f701",
  "ariaRole": "button",
  "testId": "",
  "classList": ["btn", "btn-primary"],
  "lineageVector": ["body", "main", "form", "button"],
  "spatialBucket": "bottom-right",
  "fingerprintVersion": "v1"
}

Project layout

src/
  index.ts              ← Public API
  cli.ts                ← CLI tool
  core/
    schema.ts           ← Fingerprint types (versioned)
    baselineCache.ts    ← Read/write .resilience/baselines.json
    safeAssert.ts       ← Main developer API
    fingerprint.ts      ← Feature extraction (pure, no side effects)
    scoringEngine.ts    ← Heuristic scoring (used by jsdom harness)
    browserScript.ts    ← Browser-injectable scoring IIFE

tests/
  harness.ts            ← Ground-truth grader (no browser needed)
  corpus/fixtures.ts    ← 15 synthetic breakage scenarios
  integration.test.ts   ← Real Playwright browser tests

Harness results (synthetic fixtures)

Scoring Engine:   15/15
Baseline Cache:    3/3
TOTAL:            18/18  (100.0%)

By category:
  CLASS_RENAME:    2/2
  DOM_RESTRUCTURE: 6/6
  ARIA_CHANGE:     1/1
  TEXT_MUTATION:   4/4
  ATTR_SHIFT:      2/2

These are synthetic. Add your real broken selectors to tests/corpus/fixtures.ts and run npm run harness to measure actual accuracy on your codebase.


License

MIT

Author

Aryan Sanskar Ahuja * GitHub: @2-claw-4-kennex

  • LinkedIn: (https://www.linkedin.com/in/aryan-sanskar-ahuja-49804a308/)

If this tool saved your CI pipeline, consider giving the repo a ⭐ on GitHub!