home / skills / cin12211 / orca-q / playwright-expert
This skill provides expert Playwright guidance for setting up E2E tests, cross-browser runs, and reliable automation workflows.
npx playbooks add skill cin12211/orca-q --skill playwright-expertReview the files below or copy the command above to add this skill to your agents.
---
name: playwright-expert
description: Playwright E2E testing expert for browser automation, cross-browser testing, visual regression, network interception, and CI integration. Use for E2E test setup, flaky tests, or browser automation challenges.
---
# Playwright Expert
Expert in Playwright for E2E testing, browser automation, and cross-browser testing.
## When Invoked
### Recommend Specialist
- **Unit/integration tests**: recommend jest-expert or vitest-expert
- **React component testing**: recommend testing-expert
- **API testing only**: recommend rest-api-expert
### Environment Detection
```bash
npx playwright --version 2>/dev/null
ls playwright.config.* 2>/dev/null
find . -name "*.spec.ts" -path "*e2e*" | head -5
```
## Problem Playbooks
### Project Setup
```bash
# Initialize Playwright
npm init playwright@latest
# Install browsers
npx playwright install
```
```typescript
// playwright.config.ts
import { defineConfig, devices } from '@playwright/test';
export default defineConfig({
testDir: './e2e',
fullyParallel: true,
forbidOnly: !!process.env.CI,
retries: process.env.CI ? 2 : 0,
workers: process.env.CI ? 1 : undefined,
reporter: 'html',
use: {
baseURL: 'http://localhost:3000',
trace: 'on-first-retry',
screenshot: 'only-on-failure',
},
projects: [
{ name: 'chromium', use: { ...devices['Desktop Chrome'] } },
{ name: 'firefox', use: { ...devices['Desktop Firefox'] } },
{ name: 'webkit', use: { ...devices['Desktop Safari'] } },
],
webServer: {
command: 'npm run dev',
url: 'http://localhost:3000',
reuseExistingServer: !process.env.CI,
},
});
```
### Writing Tests
```typescript
import { test, expect } from '@playwright/test';
test.describe('Authentication', () => {
test('should login successfully', async ({ page }) => {
await page.goto('/login');
await page.fill('[data-testid="email"]', '[email protected]');
await page.fill('[data-testid="password"]', 'password123');
await page.click('[data-testid="submit"]');
await expect(page).toHaveURL('/dashboard');
await expect(page.locator('h1')).toContainText('Welcome');
});
test('should show error for invalid credentials', async ({ page }) => {
await page.goto('/login');
await page.fill('[data-testid="email"]', '[email protected]');
await page.fill('[data-testid="password"]', 'wrong');
await page.click('[data-testid="submit"]');
await expect(page.locator('.error-message')).toBeVisible();
});
});
```
### Page Object Model
```typescript
// pages/login.page.ts
import { Page, Locator } from '@playwright/test';
export class LoginPage {
readonly page: Page;
readonly emailInput: Locator;
readonly passwordInput: Locator;
readonly submitButton: Locator;
constructor(page: Page) {
this.page = page;
this.emailInput = page.locator('[data-testid="email"]');
this.passwordInput = page.locator('[data-testid="password"]');
this.submitButton = page.locator('[data-testid="submit"]');
}
async goto() {
await this.page.goto('/login');
}
async login(email: string, password: string) {
await this.emailInput.fill(email);
await this.passwordInput.fill(password);
await this.submitButton.click();
}
}
// Usage in test
test('login test', async ({ page }) => {
const loginPage = new LoginPage(page);
await loginPage.goto();
await loginPage.login('[email protected]', 'password');
});
```
### Network Interception
```typescript
test('mock API response', async ({ page }) => {
await page.route('**/api/users', async (route) => {
await route.fulfill({
status: 200,
body: JSON.stringify([{ id: 1, name: 'Mock User' }]),
});
});
await page.goto('/users');
await expect(page.locator('.user-name')).toContainText('Mock User');
});
```
### Visual Regression
```typescript
test('visual comparison', async ({ page }) => {
await page.goto('/');
await expect(page).toHaveScreenshot('homepage.png', {
maxDiffPixelRatio: 0.1,
});
});
```
### Handling Flaky Tests
```typescript
// Retry flaky tests
test('flaky network test', async ({ page }) => {
test.slow(); // Triple timeout
await page.goto('/');
await page.waitForLoadState('networkidle');
// Use polling assertions
await expect(async () => {
const response = await page.request.get('/api/status');
expect(response.ok()).toBeTruthy();
}).toPass({ timeout: 10000 });
});
```
## Running Tests
```bash
# Run all tests
npx playwright test
# Run specific file
npx playwright test login.spec.ts
# Run in headed mode
npx playwright test --headed
# Run in UI mode
npx playwright test --ui
# Debug mode
npx playwright test --debug
# Generate report
npx playwright show-report
```
## Code Review Checklist
- [ ] data-testid attributes for selectors
- [ ] Page Object Model for complex flows
- [ ] Network requests mocked where needed
- [ ] Proper wait strategies (no arbitrary waits)
- [ ] Screenshots on failure configured
- [ ] Parallel execution enabled
## Anti-Patterns
1. **Hardcoded waits** - Use proper assertions
2. **Fragile selectors** - Use data-testid
3. **Shared state between tests** - Isolate tests
4. **No retries in CI** - Add retry for flakiness
5. **Testing implementation details** - Test user behavior
This skill is a Playwright E2E testing expert focused on browser automation, cross-browser testing, visual regression, network interception, and CI integration. It helps set up Playwright, design robust tests for Vue and Electron apps, and troubleshoot flaky or environment-dependent failures. Use it to build maintainable E2E suites and integrate tests into CI pipelines for reliable releases.
I inspect your project for existing Playwright configuration, test files, and typical anti-patterns, then recommend a tailored setup and test architecture. I provide configuration snippets (playwright.config.ts), Page Object Model examples, network interception patterns, and visual regression test templates. I also suggest CI settings, retry/backoff strategies for flakiness, and a code-review checklist to keep tests stable and fast.
How do I integrate Playwright into CI?
Add Playwright install and npx playwright install to your CI job, run npx playwright test with a headless browser, enable retries and a single worker in CI, and publish the HTML report or store traces/screenshots as artifacts.
When should I mock network requests vs using a real backend?
Mock when you need deterministic responses, faster tests, or to simulate edge cases. Use a real backend for end-to-end smoke tests that validate integration between UI and data store.