# Skills: Domain Expertise on Demand

Sound familiar? In the [first article](https://idavidov.eu/the-scaffold-playwright-ai), we set up a project scaffold designed for AI. But a good structure only gets you so far if the AI is just a code suggester. Useful, but not transformative. You still have to know what to ask, verify what it wrote, adapt it to your project, and repeat for every file.

In the [second article](https://idavidov.eu/what-is-agentic-qa), we saw what makes an AI agent different from a chatbot. It reads your code, takes actions, and works inside your project. But here's the catch: an agent is only as good as the instructions it follows.

In the [third article](https://idavidov.eu/claude-md-teaching-the-ai-your-rules), we saw how `CLAUDE.md` gives the agent its rules and workflow. But rules without depth only get you so far. "Use the Page Object Model" is a rule, but how exactly do you structure a page object? What's the difference between a locator getter and an action method? How do you compose components into page objects?

* * *

`CLAUDE.md` gives the agent its rules and workflow. But rules without depth only get you so far. "Use the Page Object Model" is a rule, but how exactly do you structure a page object? What's the difference between a locator getter and an action method? How do you compose components into page objects?

This is where **skill files** come in.

* * *

## 🤔 What Is a Skill File?

A skill file is a detailed, focused markdown document that covers one area of your testing framework in depth. Where `CLAUDE.md` tells the agent *what* to do, skills tell the agent *how* to do it.

The scaffold comes with 13 skills, all living in `.claude/skills/`:

```markdown
.claude/skills/
├── selectors/SKILL.md        → Locator priority, forbidden patterns, examples
├── page-objects/SKILL.md     → POM structure, getters vs actions, registration
├── fixtures/SKILL.md         → DI pattern, fixture creation, merging
├── test-standards/SKILL.md   → Test structure, imports, tagging, steps
├── api-testing/SKILL.md      → apiRequest fixture, schema validation
├── data-strategy/SKILL.md    → Factories vs static JSON, Faker usage
├── type-safety/SKILL.md      → Zod schemas, TypeScript strict mode
├── enums/SKILL.md            → Enum conventions and naming
├── config/SKILL.md           → Config patterns, environment variables
├── helpers/SKILL.md          → Helper functions, auth helpers
├── browser-use/SKILL.md      → Live app exploration with browser automation
├── common-tasks/SKILL.md     → Prompt templates, verification checklist
└── refactor-values/SKILL.md  → Safe refactoring of enums and static data
```

Each one is loaded on demand, not all at once. The agent reads only the skill that's relevant to what it's currently doing.

![](https://cdn.hashnode.com/uploads/covers/684094468ee5eff3cfc91033/d43001b5-0d29-43f1-a93a-318c5c307852.webp align="center")

* * *

## 🧠 Why Not Put Everything in CLAUDE.md?

A single giant instruction file has a real problem. The further down the page a rule lives, the less likely the AI is to apply it consistently. Context windows have limits, and even when they don't, a 5,000 word instruction file is harder to reason about than a 300 word one.

Skills solve this with **lazy loading**. The agent reads the orchestrator (`CLAUDE.md`) first. Short, high-level, fast. When it needs to work on a specific area, it reads the relevant skill. Deep expertise, loaded exactly when needed.

```markdown
Agent working on a page object:
  → CLAUDE.md: "Read selectors and page-objects skills for pages/**"
  → Loads selectors/SKILL.md
  → Loads page-objects/SKILL.md
  → Now has full expertise for this specific task
  → Generates code confidently and correctly
```

![](https://cdn.hashnode.com/uploads/covers/684094468ee5eff3cfc91033/e2aa6e0a-f772-499e-9fa9-21c9a43eabce.webp align="center")

* * *

## 📖 What's Inside a Skill File?

Let's look at what the `selectors` skill actually contains:

**The priority rule with reasoning:**

```markdown
Priority order:

1. getByRole() - Tests behaviour, survives CSS/ID changes
2. getByLabel() - Tied to accessible form labels
3. getByPlaceholder() - Tied to input hint text
4. getByText() - Matches visible text content
5. getByTestId() - Last resort, when no semantic option exists

Forbidden: XPath, CSS class selectors (.btn-primary)
```

**Examples of correct vs incorrect usage:**

```typescript
// ✅ Correct
page.getByRole("button", { name: "Submit Order" });
page.getByLabel("Email address");

// ❌ Wrong: fragile, will break on CSS changes
page.locator(".submit-btn");
page.locator("#email-input");
page.locator('xpath=//button[@class="btn"]');
```

**Edge cases:**

```markdown
- Buttons with icons only: use getByRole('button', { name: /icon label/i })
- Dynamic text: use getByRole with partial name match
- Inside a shadow DOM: note the limitation, escalate to human review
```

A skill file is essentially what you'd tell a new team member on their first code review. "We do it this way, here's why, here are the gotchas".

![](https://cdn.hashnode.com/uploads/covers/684094468ee5eff3cfc91033/b6a40039-5d02-4f43-88f4-593c5c49fcb7.webp align="center")

* * *

## 🔗 The `common-tasks` Skill

One skill deserves special attention: `common-tasks`. It contains **prompt templates**, pre-written instructions for the most frequent tasks an agent performs:

```markdown
## Create a Page Object

Before starting:

1. Read selectors/SKILL.md and page-objects/SKILL.md
2. Navigate to the page using browser-use
3. Discover: button names, label text, heading roles

Generate:

- pages/{area}/{name}.page.ts
- Register in fixtures/pom/page-object-fixture.ts

Verification checklist:

- [ ] No XPath
- [ ] No hardcoded strings in test files
- [ ] No `any` type
- [ ] Linting passes
- [ ] Tests run and pass
```

This is the agent's playbook. Instead of reasoning from scratch about how to create a page object, it has a structured checklist to follow. The output is consistent because the process is consistent.

* * *

## 📝 Writing Your Own Skill Files

The skills that ship with the scaffold are a starting point. As your project grows, you'll discover new conventions that need documenting, and new anti-patterns that need blocking.

A good skill file has four parts:

1.  **The rule:** What the agent should do (or not do) in this area
    
2.  **The reasoning:** Why the rule exists (helps the agent generalize)
    
3.  **Code examples:** Correct and incorrect, clearly labeled
    
4.  **Edge cases:** The situations where the rule gets tricky
    

Keep them short. A skill file that is short and concise will get used. One that is long and verbose won't.

* * *

## 🔄 Skills as a Team Knowledge Base

Here's something that's easy to miss. Skill files aren't just for AI. They're documentation of your team's decisions.

When a new colleague joins your team, they can read the skill files to understand why things are done the way they are. When you make a decision in a code review ("we always use `z.strictObject()` because here's what happened that one time"), you add it to the relevant skill file. The AI and the humans stay aligned.

Over time, the `.claude/skills/` folder becomes a living record of your team's accumulated QA knowledge.

![](https://cdn.hashnode.com/uploads/covers/684094468ee5eff3cfc91033/42dc4968-ada5-4491-b455-db87b86261ee.webp align="center")

* * *

🙏🏻 **Thank you for reading!** Skills are what separate a consistent AI-generated codebase from a chaotic one. But rules and skills only get the agent so far. It also needs to see the actual application before writing code for it. That's the subject of the next article.

You can find the Public README.md file for the scaffold on GitHub: [Playwright Scaffold](https://github.com/idavidov13/Playwright-Scaffold-AI-Assisted-Development-Public)

You can get access to the private GitHub repository here: [Get Access](https://buymeacoffee.com/idavidov/e/513835)

> Every coffee you buy ☕ directly contributes to keeping this resource open and growing for everyone.

[![Buy me a coffee](https://img.buymeacoffee.com/button-api/?text=Buy%20me%20a%20coffee&emoji=%F0%9F%91%A8%E2%80%8D%F0%9F%92%BB&slug=idavidov&button_colour=FFDD00&font_colour=000000&font_family=Comic&outline_colour=000000&coffee_colour=ffffff align="center")](https://www.buymeacoffee.com/idavidov)
