Back to Skills

playwright-patterns

verified

Use when writing Playwright automation code, building web scrapers, or creating E2E tests - provides best practices for selector strategies, waiting patterns, and robust automation that minimizes flakiness

View on GitHub

Marketplace

ed3d-plugins

ed3dai/ed3d-plugins

Plugin

ed3d-playwright

Repository

ed3dai/ed3d-plugins
82stars

plugins/ed3d-playwright/skills/playwright-patterns/SKILL.md

Last Verified

January 25, 2026

Install Skill

Select agents to install to:

Scope:
npx add-skill https://github.com/ed3dai/ed3d-plugins/blob/main/plugins/ed3d-playwright/skills/playwright-patterns/SKILL.md -a claude-code --skill playwright-patterns

Installation paths:

Claude
.claude/skills/playwright-patterns/
Powered by add-skill CLI

Instructions

# Playwright Automation Patterns

## Overview

Reliable browser automation requires strategic selector choice, proper waiting, and defensive coding. This skill provides patterns that minimize test flakiness and maximize maintainability.

## When to Use

- Writing new Playwright scripts or tests
- Debugging flaky automation
- Refactoring unreliable selectors
- Building web scrapers that need to handle dynamic content
- Creating E2E tests that must be maintainable

**When NOT to use:**
- Simple one-time browser tasks
- When you need Playwright API documentation (use context7 MCP)

## Selector Strategy

### Priority Order

Use user-facing locators first (most resilient), then test IDs, then CSS/XPath as last resort:

1. **Role-based locators** (best - user-centric)
   ```javascript
   await page.getByRole('button', { name: 'Submit' }).click();
   await page.getByRole('textbox', { name: 'Email' }).fill('test@example.com');
   ```

2. **Other user-facing locators**
   ```javascript
   await page.getByLabel('Password').fill('secret');
   await page.getByPlaceholder('Search...').fill('query');
   await page.getByText('Submit Order').click();
   ```

3. **Test ID attributes** (explicit contract)
   ```javascript
   // Default uses data-testid
   await page.getByTestId('submit-button').click();

   // Can customize in playwright.config.ts:
   // use: { testIdAttribute: 'data-pw' }
   ```

4. **CSS/ID selectors** (fragile, avoid if possible)
   ```javascript
   await page.locator('#submit-btn').click();
   await page.locator('.btn.btn-primary.submit').click();
   ```

### Strictness and Specificity

Locators are strict by default - operations throw if multiple elements match:

```javascript
// ERROR if 2+ buttons exist
await page.getByRole('button').click();

// Solutions:
// 1. Make locator more specific
await page.getByRole('button', { name: 'Submit' }).click();

// 2. Filter to narrow down
await page.getByRole('button')
  .filter({ hasText: 'Submit' })
  .click();

// 3. C

Validation Details

Front Matter
Required Fields
Valid Name Format
Valid Description
Has Sections
Allowed Tools
Instruction Length:
13728 chars