# Beyond the Form Tester: Building a Skill Pack for Your Whole Playwright Suite

> Source: <https://dev.to/aswani25/beyond-the-form-tester-building-a-skill-pack-for-your-whole-playwright-suite-gk5>
> Published: 2026-07-23 16:30:00+00:00

*Part 6 of the "Automating Playwright with Claude Code" series. In Part 4 we built one Skill; in Part 5 we learned why installing many Skills doesn't bloat every session. This post uses both to grow a single Skill into a small, organized **pack** covering more of your actual test suite.*

One Skill is useful. A handful of *related* Skills, organized as a pack, is what actually replaces a chunk of your team's onboarding docs. This post takes the `playwright-form-tester`

Skill from Part 4 and grows it into a three-Skill pack — a locator policy, a page object generator, and a flaky-test debugger — using the progressive disclosure model from Part 5 so none of it costs you tokens you're not using.

`references/`

folder across Skills instead of repeating the same conventions in three separate files.**Grows with your team.** New teammates get your locator conventions, your page object style, and your flaky-test triage process automatically — the same idea the wider "Skill pack" ecosystem (directories like qaskills.sh) is built around.

Completed [Part 4](https://dev.to/aswani25/what-is-skillmd-building-a-reusable-playwright-testing-skill-for-claude-code-27b1) (the `playwright-form-tester`

Skill) and [Part 5](https://dev.to/aswani25/progressive-disclosure-why-you-can-install-30-skills-and-pay-for-almost-nothing-3n04) (progressive disclosure) of this series.

Comfortable creating multiple sibling folders under `.claude/skills/`

.

Before writing anything, it helps to map out which Skill owns which trigger, so descriptions don't overlap:

| Skill | Fires on requests like... |
|---|---|
`playwright-form-tester` (Part 4) |
"test the login form", "validate checkout" |
`playwright-locator-policy` |
"add a locator for...", "find the best selector for..." |
`playwright-page-object-generator` |
"generate a page object for...", "scaffold a POM for..." |
`playwright-flaky-test-debugger` |
"this test is flaky", "why does this fail intermittently" |

```
.claude/skills/
├── playwright-form-tester/
├── playwright-locator-policy/
├── playwright-page-object-generator/
├── playwright-flaky-test-debugger/
└── playwright-shared/
    └── references/
```

This Skill enforces a consistent locator strategy instead of letting Claude default to fragile CSS selectors.

```
---
name: playwright-locator-policy
description: Enforce locator strategy when writing or reviewing Playwright
  selectors. Use whenever the user asks to add a locator, pick a selector,
  or review existing locators for reliability.
---

# Playwright locator policy

## Priority order
1. `getByRole` (accessible name + role) — always prefer this first.
2. `getByLabel` / `getByPlaceholder` — for form fields without a clear role match.
3. `getByTestId` — only when no accessible attribute exists, using the
   project's `data-testid` convention.
4. Raw CSS/XPath — last resort only; flag it in the response so it can be
   revisited later.

## Process
1. Inspect the snapshot for accessible roles and names before suggesting
   any selector.
2. Never suggest a locator tied to visual position (nth-child, index) —
   these break the moment layout changes.
3. If an existing test uses a fragile selector, suggest a replacement
   rather than leaving it as-is.
```

This Skill turns a page snapshot into a Page Object class matching your team's conventions.

```
---
name: playwright-page-object-generator
description: Generate or update Playwright Page Object Model classes. Use
  whenever the user asks to scaffold a page object, generate a POM, or
  create a page class for a UI flow.
---

# Playwright page object generator

## Process
1. Navigate to the target page and take a snapshot.
2. Apply `playwright-locator-policy` conventions for every element chosen.
3. Generate one class per page, with:
   - Locators as readonly properties, named after their purpose
     (`emailInput`, not `input1`).
   - One method per user action (`login()`, `submitForm()`), not per
     individual click or fill.
4. Place the file under `pages/<PageName>Page.ts` (or the project's
   existing page object folder, if one exists — check first).
5. Never duplicate an existing Page Object; check for one before creating
   a new file.
```

Notice this Skill explicitly references the locator-policy Skill's conventions in step 2 — Skills in a pack can lean on each other's standards without repeating the full policy inline.

This one handles a completely different trigger: diagnosing, not writing.

```
---
name: playwright-flaky-test-debugger
description: Diagnose intermittently failing Playwright tests. Use whenever
  the user says a test is flaky, fails intermittently, or passes locally
  but fails in CI.
---

# Playwright flaky test debugger

## Process
1. Ask for (or locate) the failing test's trace file or CI logs first —
   never guess at a root cause without evidence.
2. Check, in order, for the most common causes:
   - Missing `await` before an action or assertion.
   - An assertion that doesn't wait for state (use `expect(locator)`
     auto-waiting patterns, not manual `sleep`/` wait` calls).
   - Test-order dependency (does it fail only when run after another
     specific test?).
   - Environment difference (timing, viewport, or data state between
     local and CI).
3. Report the most likely cause with the specific line of evidence from
   the trace/log that supports it — don't report a guess as a finding.
4. Suggest one fix at a time; don't rewrite the whole test speculatively.
```

Notice step 3's guardrail — this mirrors the "never fabricate" guidance that's become a best practice for AI-assisted QA work: report evidence, not guesses.

If several Skills need the same longer reference (say, your team's full accessibility-name conventions for `getByRole`

), put it once in a shared location instead of duplicating it:

```
.claude/skills/playwright-shared/references/accessible-naming.md
```

Then point to it by relative path from any Skill that needs it, rather than pasting the same content into three separate `SKILL.md`

bodies. Per the progressive disclosure model from Part 5, this file still only loads when a step actually calls for it — sharing it doesn't cost you anything extra.

Restart your Claude Code session, then test each trigger independently:

```
Add a locator for the "Remember me" checkbox.
→ should fire playwright-locator-policy

Generate a page object for the checkout page.
→ should fire playwright-page-object-generator

This test passes locally but fails in CI about half the time.
→ should fire playwright-flaky-test-debugger
```

If two Skills fire for the same request, or neither fires, revisit their `description`

fields — Part 5 covered why this is almost always a description problem, not a bug in the Skill body.

A single Skill solves one repeated conversation. A pack — planned so each Skill has a clear, non-overlapping trigger, and sharing common references — starts to genuinely replace parts of your team's onboarding documentation, all without costing you tokens for the Skills you're not using in a given session. In the next post, we'll add explicit guardrails and human-review gates across this whole pack, so none of these Skills ever ship a fabricated result unchecked.

Have you grouped your own Skills into a pack yet? What's in it? Let me know in the comments!
