Skip to main content

playwright-testid-catalog

Why It Exists

The introducing commit (306857c, "skills: add playwright testid-catalog/attributes/waits/page-objects family") describes this skill as generalizing "a Playwright instrumentation convention found undocumented-but-pervasive in a client engagement's codebase." The catalog/registry/mirror pattern wasn't designed in the abstract — it was extracted from a real codebase that had already converged on typed data-testid catalogs, reactive state-marker attributes, and matching wait helpers, without ever writing the convention down. That same commit redacted client-identifying references (envmgr-ui, @ad-infrastructure) from README.md and the docs/*-RUNBOOK.md files it touched, replacing them with the neutral "a client engagement" phrasing this skill's own attribution still carries.

This skill also became the structural precedent for a later skill family. .omc/plans/appium-rn-testing-skills.md (local research artifact, not tracked in this repo) directs the four new appium-* skills to "mirror the existing playwright-testid-attributes / playwright-testid-catalog / playwright-attribute-waits / playwright-page-objects family's producer/catalog/consumer/structure split exactly," and separately observes that "no existing Playwright skill names all three siblings — each names only the sibling(s) whose boundary it's actively disclaiming" — citing this skill by name as the one that names only playwright-testid-attributes, the boundary it exists to hand off to. The narrow "Related Skills" cross-referencing below follows that same precedent rather than listing every sibling generically.

The catalog's shape also carries operational weight beyond authoring: .omc/plans/skill-distribution-channels.md lists playwright-testid-catalog as one of five skills whose metadata.json.references entries needed rewriting from repo-relative paths (skills/playwright-testid-catalog/references/...) to package-relative form (references/...) before the skill could be packaged for npm distribution — a concrete signal that the references/ directory (utils.ts, example-catalog.ts, example-catalog.mirror.ts) is treated as shippable, consumer-facing content, not incidental scratch files.

Finally, .omc/plans/quality-loop-skills.md folds this skill's own conventions into an automated grading rule: its playwright-conventions lens flags "a new dynamic-row list missing the catalog's prefix-${id} convention" as a defect the next-frontend-quality-loop skill should catch during review, citing this skill (alongside its three siblings) as the authority a grader defers to rather than re-deriving the rule inline.

What It Does

playwright-testid-catalog defines a shared createTestIdRegistry helper that builds a nested, section-keyed catalog object of data-testid strings for one feature area, validating uniqueness at dev-time by throwing on any duplicate leaf value. A Playwright-side mirror module re-exports that exact same catalog object so app code and spec code read one in-memory object and can never drift apart on an id string.

It is the canonical, authoritative home for how the catalog is built, validated, and mirrored into the test runner. The sibling playwright-testid-attributes consumes catalog ids inside components but does not define the registry or mirror mechanics itself — that boundary is why this skill exists as a separate, dedicated home for the pattern rather than folding into the producer-side skill.

How To Use It

Triggers on: "data-testid catalog", "typed test ids", "testid registry", "duplicate testid", "migrate hardcoded testid strings", "playwright mirror module", "test id naming convention", "prefix-${id} row ids", or standing up the catalog layer for a new feature area.

skills add git@github.com:catesandrew/next-starters.git --skill skills/playwright-testid-catalog -g
npm install @next-starters/skill-playwright-testid-catalog
/plugin marketplace add catesandrew/next-starters
/plugin install playwright-testid-catalog@next-starters

Gotchas & Invariants

  • One typed catalog module per feature area, built via the shared createTestIdRegistry helper (references/utils.ts) — never a hand-rolled plain object literal, which validates nothing.
  • The registry walks the nested structure at call time, collects every leaf string value, and throws a clear Error listing the offending duplicates when NODE_ENV === 'development' — so a copy-pasted id string surfaces immediately in a dev session instead of silently shadowing another element in production or CI.
  • Catalog keys are nested by view/section (list, detail, create, edit, dialogs), each holding elements suffixed by kind (-page, -button, -input, -table, -row) per references/example-catalog.ts — a convention the helper does not mechanically enforce, so consistency comes from every catalog module following the same shape.
  • Components must bind data-testid={CATALOG.section.element} — never a hand-written literal string. This skill is the canonical, authoritative home for that rule even though playwright-testid-attributes also states a version of it from the consumption side.
  • Dynamic per-row/per-item ids use a documented `prefix-${id}` convention (e.g. widgetRow(id) returning `widgets-row-${id}`) rather than a static string, with an optional reverse-parse fallback for recovering ids from a harvested element list — a last resort for debugging or migration, not the primary path.
  • The Playwright-side mirror module (references/example-catalog.mirror.ts) imports or dynamically imports the app's catalog file directly rather than retyping id strings into a second, parallel catalog — a renamed or removed id breaks the mirror's import at compile time instead of leaving a stale string alive in test code.
  • Verification is a three-part loop — typecheck, a dev-mode run, and lint for literal data-testid strings — because each check catches a failure mode the other two miss; skipping the dev-mode run means the uniqueness validation (gated on NODE_ENV === 'development') never actually fires.
  • metadata.json's references array must stay package-relative (references/...), not repo-relative — this skill was one of five rewritten for that reason ahead of npm packaging.
  • playwright-testid-attributes — the producer side; consumes this skill's catalog ids in components but doesn't define the registry/mirror mechanics itself.

Sourced from: skills/playwright-testid-catalog/metadata.json, skills/playwright-testid-catalog/SKILL.md, .omc/plans/quality-loop-skills.md (local research artifact, not tracked in this repo), .omc/plans/skill-distribution-channels.md (local research artifact, not tracked in this repo), .omc/plans/appium-rn-testing-skills.md (local research artifact, not tracked in this repo), git log --follow -- skills/playwright-testid-catalog (commit 306857c)