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

speclab

v0.5.0

Published

Auto-generate Playwright specs from app source + runtime crawl + DB schema

Readme

speclab — Playwright Test Generation Toolkit

Generate annotated Playwright specs and human-readable test deliverables from natural-language scenarios — with a built-in locator inventory, migration pipeline, behavioral test generators, and token-efficient Claude Code skills.

Quick start

# 1. Install
npm install --save-dev speclab @playwright/test
npx playwright install chromium

# 2. Scaffold into your project
npx speclab init

# 3. Configure
# Edit speclab.config.json with your app's baseURL, auth, and (optionally) DB

# 4. Run
npx playwright test

What's in the box

speclab ships three complementary pipelines:

| Pipeline | Purpose | Entry point | |---|---|---| | Spec generation | Turn scenarios → passing .spec.ts files | /playwright-testgen skill | | Migration testing | AsIs↔ToBe behavioral equivalence (Stage A→G) | speclab migrate | | Behavioral extraction | Auto-generate filter-reactive tests from source | filter:extract + filter:generate |


1 — Spec generation

speclab init scaffold

your-project/
├── speclab.config.json
├── playwright.config.ts
├── tests/helpers/
│   ├── config.ts        ← typed config export
│   ├── api.ts           ← loginAs() helper
│   ├── db.ts            ← queryDB(), entityTable()
│   └── locators.ts      ← locate(), findComponent()
└── .claude/skills/
    ├── playwright-testgen/   ← /playwright-testgen skill
    └── playwright-batch/     ← /playwright-batch skill

Configuration — speclab.config.json

{
  "project": "my-app",
  "baseURL": "https://your-app.example.com/",
  "extractor": { "kind": "disabled" },
  "auth": {
    "loginEndpoint": "/api/auth/login",
    "admin": { "username": "admin", "password": "..." }
  }
}

extractor.kind options:

  • "disabled" — no source scan; rely on runtime discovery
  • "react-jsx" — scans React/JSX source (+ optional @ast-grep/napi for deeper AST)
  • "thymeleaf" — scans Spring Boot + Thymeleaf templates

Claude Code skills

/playwright-testgen — turn a natural-language scenario into a passing Playwright spec + markdown deliverable.

/playwright-batch — run /playwright-testgen in batch across a multi-scenario markdown file.


2 — Migration pipeline (Stage A→G)

Tests behavioral equivalence between an AsIs (legacy) system and a ToBe (new) system during a migration project.

# Configure once
cp node_modules/speclab/templates/migrate/migrate.config.example.json migrate.config.json
# Edit migrate.config.json with asis/tobe URLs, auth, source paths

# Run all 7 stages
speclab migrate run migrate.config.json

# Or run individual stages
speclab migrate coverage migrate.config.json   # coverage report
speclab migrate gap-hint migrate.config.json   # gap analysis

Stages

| Stage | What it does | Output | |---|---|---| | A — asis-ingest | Crawl AsIs app, capture live signal | asis-signal.json | | B — abs-generate | Extract ABS scenarios from source code | abs.json | | C — tobe-route | Map ABS scenarios → ToBe routes | routing.json | | D — abs-to-spec | Generate .spec.ts for ToBe only | specs/abs-*.spec.ts | | E — abs-to-excel | Generate Excel deliverable | *.xlsx | | F — abs-to-markdown | Generate human-readable docs | docs/*.md | | G — abs-to-compare | Generate AsIs↔ToBe equivalence specs | compare/*.compare.spec.ts |

Dual-harness test fixture

import { dualTest, assertEquivalent, loginBoth } from './helpers/dual-harness';

dualTest('CV list loads same data', async ({ asisPage, tobePage }) => {
  await loginBoth(asisPage, tobePage);
  await assertEquivalent(asisPage, tobePage, {
    redirectPath: '/cv',
    visibleText: ['Employee Code', 'Full Name'],
    screenshot: true,   // pixel-diff comparison
  });
});

Source extractors

Supports 6 legacy frameworks via semgrep-backed extractors:

| Framework | Rule file | Rules | |---|---|---| | ASP.NET Web Forms | semgrep-rules/aspnet.yml | 9 | | CodeIgniter 4 | semgrep-rules/ci4.yml | 9 | | Laravel | semgrep-rules/laravel.yml | 10 | | Spring MVC | semgrep-rules/spring.yml | 14 | | Apache Struts | semgrep-rules/struts.yml | 10 | | React/TSX | built-in (+ ast-grep) | — |

Install semgrep for legacy framework extraction: pip install semgrep

Install ast-grep for deeper React AST patterns: npm install @ast-grep/napi


3 — Behavioral extraction (filter-reactive)

Automatically extract React filter-state signals from source and generate Playwright tests that verify filter controls correctly affect displayed data.

# Step 1 — scan source, emit FilterSignal JSON per module
node scripts/extract-filter-signals.mjs \
  --source /path/to/app/src \
  --out output/filter-signals/

# Step 2 — review JSON, annotate cardSelectors, prune false positives

# Step 3 — generate .spec.ts from signals
node scripts/generate-filter-specs.mjs \
  --signals output/filter-signals/ee.json \
  --out output/specs/

# Step 4 — run
ASIS_BASE_URL=https://your-app.com \
  npx playwright test output/specs/ee-filter-reactive.spec.ts \
  --config playwright.migrate.config.ts

FilterSignal JSON format

{
  "meta": {
    "module": "EE",
    "route": "/ee",
    "waitForTable": "loading-div",
    "activeClass": "ring-1",
    "cardCountLocator": ".text-2xl"
  },
  "signals": [
    {
      "signalId": "filter_ee_statusFilter",
      "stateName": "statusFilter",
      "controlType": "card-toggle",
      "cardValues": ["critical", "warning", "healthy"],
      "cardSelectors": {
        "critical": "[class*=\"bg-red-900\"]"
      }
    }
  ],
  "supplement": [
    {
      "id": "T-EXPORT",
      "ts": "test('T-EXPORT — export triggers download', async ({ page }) => { ... });"
    }
  ]
}

Detected control types

| controlType | Pattern in source | Generated invariant | |---|---|---| | card-toggle | active={state === "value"} | count-match + toggle-off | | text-input | <input value={state}> | canary + prefix search | | dropdown | <select value={state}> | API intercept + count assert |

Meta options

| Field | Default | Description | |---|---|---| | waitForTable | "tbody" | "loading-div" | "networkidle" | "tbody" | | activeClass | "ring-1" | CSS class added to active card (e.g. "ring-2") | | cardCountLocator | ".text-2xl" | Locator for count display inside card; "" = button textContent | | dataRowsSelector | "tbody tr:not(:has(td[colspan]))" | Selector for data rows |

supplement[] — hand-authored tests

Add verbatim TypeScript tests that the extractor cannot generate (cross-filter combinations, exports, etc.). They are appended inside the test.describe block and tracked in version control alongside the signal JSON.


CLI reference

| Command | Purpose | |---|---| | speclab init [--force] | Scaffold helpers, skills, and config | | speclab locators [refresh\|force] | Build locator inventory from source | | speclab deliverables | Generate markdown deliverables from specs | | speclab migrate run <config> | Run full A→G migration pipeline | | speclab migrate coverage <config> | Route × ABS × spec coverage report | | speclab migrate gap-hint <config> | CRUD gaps, RBAC blindspots, DB entity gaps | | speclab skill:start <name> <summary> | Open skill-trace invocation | | speclab skill:end <id> [artifacts...] | Close skill-trace invocation | | speclab batch:parse <file.md> | Parse and verify a test-suite markdown | | speclab batch:report <state.json> <out.md> | Render a batch report | | speclab batch:run <suite.md> | Run /playwright-batch via claude -p |


npm scripts (in your project after speclab init)

| Script | Command | |---|---| | npm test | playwright test | | npm run test:headed | Headed + slowMo 1500ms | | npm run locators:refresh | Locator inventory (cached) | | npm run locators:force | Locator inventory (force rebuild) | | npm run deliverables | Specs → markdown deliverables | | npm run filter:extract | Scan source → FilterSignal JSON | | npm run filter:generate | FilterSignal JSON → spec.ts |


Peer dependencies

{
  "@playwright/test": ">=1.60.0",
  "pg": ">=8.0.0",        // optional — DB assertions
  "pixelmatch": ">=5.0.0", // optional — visual regression
  "pngjs": ">=6.0.0"       // optional — visual regression
}

Optional external tools:

  • pip install semgrep — legacy framework extraction (ASP.NET, Laravel, Spring, Struts, CI4)
  • npm install @ast-grep/napi — deeper React AST patterns in react-tsx extractor

License

ISC