Skip to main content

ng-playwright-page-objects

What it does

ng-playwright-page-objects defines the output shape of a Playwright Page Object — the typed façade over one route that owns its locators and small actions/assertions, so specs read as intent ("search, then verify the row appears") instead of raw selector plumbing. It covers class structure and selector/wait discipline only, not how you discover what's on a page in the first place (that stays a general, tool-agnostic step, not owned by any skill).

Its six invariants specify: a shared BasePage base class exposing route, navigate(), and a constructor(page: Page), with locators as get accessors and verify* assertion methods that call expect internally rather than returning a boolean; a selector priority ladder of role-based → label/text → typed-catalog data-testid → CSS class last (deliberately, because a role/label selector doubles as a live accessibility check that a bare testid selector can't provide); action methods that call named readiness-wait helpers instead of a bare waitForTimeout() (and if one is truly unavoidable, it must carry a comment justifying the exact millisecond budget); one page-object file per route with a deterministic naming rule; a hard boundary keeping business/domain flow logic out of page objects; and the idea that a stub page object (just route + a title locator) is a legitimate first commit, with expansion purely additive.

Why it was created

Per commit f012bc9 ("feat(skills): add ng-playwright-* skill family (Angular 21+ Playwright testing)"), this skill ports next-starters' playwright-page-objects skill to Angular as part of the same research-grounded effort as its siblings — checked against arcos-web's real Angular 21.1.2 codebase rather than assumed to transfer unchanged.

The follow-up architect review, per commit ca86d59 ("fix: address architect review findings on ng-playwright-* skills"), found and fixed a concrete grounding error specific to this skill: ExampleDataTablePage.ts had been framed around Angular Material, but the real source codebase declares @angular/material as a dependency without actually using it — that reference component was retargeted to Pinnacle's actual lib-table. As with the other skills in this family, that correction is part of why the skill is trustworthy, not an unrelated cleanup: its examples now describe the component library this repo's target codebase genuinely uses.

How to use it

Extend BasePage for a new route, deriving the file path and class name mechanically from the route (segments → PascalCase, suffixed Page). Start with a stub — route and a title locator — and expand it additively as specs need more of the page. Reach for getByRole() with an accessible name first; fall back to getByLabel()/getByText(); only drop to a catalog-sourced getByTestId() when no reliable role/label/text exists, and never to a CSS class if any alternative is available. Wrap every interaction in a readiness-wait helper from the sibling skill rather than a fixed sleep. Keep multi-step business flows out of the page object itself — compose them at a higher test/flow layer that calls into one or more page objects. See /docs/usage-examples for a worked example expanding a stub page object.

Companion skills

  • ng-playwright-attribute-waits — supplies the readiness-wait helper implementations this skill's action methods call into (invariant 3).
  • ng-playwright-testid-catalog — supplies the typed ids used as the selector-priority fallback (invariant 2) when no reliable role/label exists.