Skip to main content

ng-playwright-attribute-waits

What it does​

ng-playwright-attribute-waits is the consumer-side half of the producer contract that ng-playwright-testid-attributes defines: a component that emits data-*/aria-* state is only half the story, and this skill is the other half — a test suite that waits on those attributes correctly instead of guessing with waitForTimeout or re-deriving a slightly different polling loop in every file that needs one.

Its nine invariants center on one rule above the rest: exactly one canonical readiness/locators helper module (waitForReady, waitForClosed, waitForEpochAdvance, waitForSearchSettled) that every spec and page-object method imports, never re-implements. Beyond that: a load-state gate that checks the negative case (a transient error flash) before the positive ("ready") case; a close/unmount gate that waits for a documented attribute value rather than trusting toBeHidden() alone, with a visibility fallback for uninstrumented components; epoch-fencing that captures a counter before an action and polls until it strictly advances; a combined multi-attribute expect.poll(...) for search-settle instead of checking one attribute at a time; guarded JSON.parse on any attribute-embedded data; named sentinels (not inline magic strings) for known-bug outcomes; graceful degradation against legacy, uninstrumented components; and preferring an existing ARIA attribute over a bespoke data-* re-derivation when one is already authoritative.

Why it was created​

Per commit f012bc9 ("feat(skills): add ng-playwright-* skill family (Angular 21+ Playwright testing)"), this skill ports next-starters' playwright-attribute-waits skill to Angular as part of the same research-grounded rollout as its three sibling skills, rather than a blind rename.

The follow-up architect review, per commit ca86d59 ("fix: address architect review findings on ng-playwright-* skills"), found and fixed an environment-specific error in this skill: a dangling reference to docs/LOCAL-DEV-RUNBOOK.md plus a pnpm-dev/process-compose workflow had been inherited from the next-starters original, but this repo has neither. It was retargeted to nx serve, which the skill's own SKILL.md now reflects directly — its final reference note reads, "A Playwright suite against an Nx-workspace Angular app needs the target app's dev server already running (e.g. nx serve <app>) before any of these waits have anything to wait on." That fix is a small but concrete example of the same grounding discipline behind the whole family: a runbook reference that looked plausible but didn't match the actual repo it now lives in.

How to use it​

Import the shared helpers from one canonical readiness module rather than writing a new polling loop per file. Around a load-state assertion, check not.toHaveAttribute('data-load-state', 'error') before asserting 'ready'. Around a close action, wait for the documented closed-state attribute value, not just visibility. Around a repeatable destructive action, capture the epoch attribute before triggering it and poll until it strictly advances, plus assert the expected structural side effect (e.g. a row is actually gone). For a debounced search, assert all tracked attributes together in one expect.poll(...), not one at a time. When a component doesn't expose the expected attributes yet, fall back to a coarser visibility/sleep check and log why, rather than hard-failing. See /docs/usage-examples for a worked example wiring a debounced-search wait end to end.

Companion skills​

  • ng-playwright-testid-attributes — the producer side; emits the data-*/aria-* attributes this skill's helpers wait on.
  • ng-playwright-page-objects — its action methods call these readiness helpers around every interaction (its invariant 3).