What is playwright-testing?
Use when writing Playwright E2E tests — browser automation, visual regression testing, Page Objects, fixtures, and reliable test patterns.
event4u-app/agent-config
Use when writing Playwright E2E tests — browser automation, visual regression testing, Page Objects, fixtures, and reliable test patterns.
npx skills add https://github.com/event4u-app/agent-config --skill "src/skills/playwright-testing"Quick start
Install it or open the source, trigger it with a clear task, then follow the source workflow.
npx skills add https://github.com/event4u-app/agent-config --skill "src/skills/playwright-testing"Use playwright-testing to help me with: [describe your task]. Before you begin, tell me what input you need, the steps you will follow, and the expected output.
No structured workflow was detected; follow the original SKILL.md below.
Continue to the workflowDirect answers
Use when writing Playwright E2E tests — browser automation, visual regression testing, Page Objects, fixtures, and reliable test patterns.
It is relevant to workflows involving Testing, Engineering, Design, Operations.
SkillSignal detected this source-specific command: npx skills add https://github.com/event4u-app/agent-config --skill "src/skills/playwright-testing". Inspect the repository and command before running it.
The upstream source does not declare a dedicated Agent platform.
Static analysis detected exec-script signals. Review the cited source lines before installing; these signals are not a security audit.
This page combines upstream documentation with deterministic repository, quality, and static-risk signals. It is not described as a manual test or security review.
SkillSignal brief
Use when writing Playwright E2E tests — browser automation, visual regression testing, Page Objects, fixtures, and reliable test patterns.
Useful in these contexts
Core capabilities
Distilled from the source
About 4 min · 17 sections
Writing end-to-end tests with Playwright
Automating browser interactions for testing
Setting up visual regression testing
Using Playwright MCP for design reviews
Playwright test file with Page Object pattern
Reliable locators using role/label selectors over CSS
Quality breakdown
Based on traceable docs and repository signals; stars are not treated as quality.
Compare before choosing
These links are selected from shared tasks, functions, stacks, platforms, and same-name variants. Compare the source owner, documentation, permissions, and maintenance signals.
Use when the user says "review the design", "check the UI", or wants a comprehensive UI/UX review. Uses a 7-phase methodology covering interaction, responsiveness, accessibility, and more.
Design AI evals that catch regressions before users do: rubrics, test cases, failure modes, acceptance gates, and AI-SPEC artifacts.
This skill enables visual inspection of websites running locally or remotely to identify and fix design issues. Triggers on requests like "review website design", "check the UI", "fix the layout", "find design problems". Detects issues with responsive design, accessibility, visual consistency, and layout breakage, then performs fixes at the source code level.
Use this skill to automate visual testing and UI interaction verification using browser automation after deploying features.
E2E testing for Windows native desktop apps (WPF, WinForms, Win32/MFC, Qt) using pywinauto and Windows UI Automation.
Design verification. When exercising a UI artifact, run the design-artifact verification checklist (open → console/load → viewport → text-fit → assets → interaction) and capture evidence; a design task with browser capability present is not "done" without it.
Use this skill when:
Guideline: ../../../docs/guidelines/e2e/playwright.md — full conventions, config templates, CI setup.
Mobile: for native iOS/Android or React Native E2E, do NOT reuse Playwright — see the mobile-e2e-strategy skill for framework selection.
../../../docs/guidelines/e2e/playwright.md for detailed conventions.playwright.config.ts for browsers, base URL, timeouts.tests/e2e/ or e2e/.test-case-discovery funnel per user flow before writing specs; cover the happy flow AND at least one boundary (empty state, max input) and one error path (failed request, validation rejection) per flow — never the happy flow alone.import { test, expect } from '@playwright/test'
test.describe('User Authentication', () => {
test('should login with valid credentials', async ({ page }) => {
await page.goto('/login')
await page.getByLabel('Email').fill('user@example.com')
await page.getByLabel('Password').fill('password123')
await page.getByRole('button', { name: 'Sign in' }).click()
await expect(page).toHaveURL('/dashboard')
await expect(page.getByRole('heading', { name: 'Dashboard' })).toBeVisible()
})
test('should show error for invalid credentials', async ({ page }) => {
await page.goto('/login')
await page.getByLabel('Email').fill('wrong@example.com')
await page.getByLabel('Password').fill('wrong')
await page.getByRole('button', { name: 'Sign in' }).click()
await expect(page.getByText('Invalid credentials')).toBeVisible()
})
})
| Strategy | Example | When to use |
|---|---|---|
| Role | getByRole('button', { name: 'Submit' }) | Default — most accessible |
| Label | getByLabel('Email') | Form inputs |
| Text | getByText('Welcome') | Visible text content |
| Placeholder | getByPlaceholder('Search...') | Input placeholders |
| Test ID | getByTestId('submit-btn') | Last resort — when no semantic locator works |
| CSS | page.locator('.my-class') | Avoid — brittle |
Prefer semantic locators (getByRole, getByLabel) over CSS selectors.
// Wait for page to fully load
await page.goto('/dashboard', { waitUntil: 'networkidle' })
// Wait for specific API response
await page.waitForResponse(resp =>
resp.url().includes('/api/users') && resp.status() === 200
)
// ✅ Auto-retrying assertions (Playwright retries until timeout)
await expect(page.getByText('Success')).toBeVisible()
await expect(page.getByRole('list')).toHaveCount(5)
// ❌ Non-retrying — can be flaky
const text = await page.textContent('.message')
expect(text).toBe('Success')
// pages/LoginPage.ts
export class LoginPage {
constructor(private page: Page) {}
async goto() {
await this.page.goto('/login')
}
async login(email: string, password: string) {
await this.page.getByLabel('Email').fill(email)
await this.page.getByLabel('Password').fill(password)
await this.page.getByRole('button', { name: 'Sign in' }).click()
}
}
test('homepage visual regression', async ({ page }) => {
await page.goto('/')
await expect(page).toHaveScreenshot('homepage.png', {
maxDiffPixelRatio: 0.01,
})
})
tests/*.png (or configured path).npx playwright test --update-snapshots.test.describe('Responsive design', () => {
for (const viewport of [
{ width: 1440, height: 900, name: 'desktop' },
{ width: 768, height: 1024, name: 'tablet' },
{ width: 375, height: 812, name: 'mobile' },
]) {
test(`renders correctly on ${viewport.name}`, async ({ page }) => {
await page.setViewportSize(viewport)
await page.goto('/')
await expect(page).toHaveScreenshot(`home-${viewport.name}.png`)
})
}
})
# Run with headed browser (see what's happening)
npx playwright test --headed
# Run with Playwright Inspector (step through)
npx playwright test --debug
# View test report
npx playwright show-report
# Run specific test
npx playwright test -g "should login"
Use --grep, --reporter=json, plus jq/rg to keep diagnosis scoped:
# Targeted run — only matching specs
npx playwright test --grep '@smoke'
# JSON report, narrowed to failures via jq
npx playwright test --reporter=json > pw.json
jq '.suites[].specs[] | select(.tests[].results[].status=="failed")' pw.json
# Scan trace logs for one selector
rg --color=never 'getByRole.*Submit' test-results/
Run verification. The test run's exit code is the pass/fail signal — 0
means every spec passed, non-zero means at least one failed. Read the command
output (or the --reporter=json above) to diagnose the failing spec's
root cause; do not blindly re-run hoping it turns green — a retry-until-pass
is not a fix, and a flaky green hides the real defect.
| Problem | Solution |
|---|---|
| Element not ready | Use auto-retrying assertions (toBeVisible, toHaveText) |
| Animation interference | Use page.evaluate(() => document.body.style.setProperty('--transition-duration', '0s')) |
| Network timing | Wait for specific responses, not arbitrary timeouts |
| Test isolation | Use fresh browser context per test (Playwright default) |
| Shared state | Reset database/state before each test |
// Use storageState to avoid logging in via UI in every test
// auth.setup.ts
import { test as setup } from '@playwright/test'
setup('authenticate', async ({ page }) => {
await page.goto('/login')
await page.getByLabel('Email').fill(process.env.TEST_USER_EMAIL!)
await page.getByLabel('Password').fill(process.env.TEST_USER_PASSWORD!)
await page.getByRole('button', { name: 'Sign in' }).click()
await page.waitForURL('/dashboard')
await page.context().storageState({ path: '.auth/user.json' })
})
// playwright.config.ts — use storage state in projects
projects: [
{ name: 'setup', testMatch: /.*\.setup\.ts/ },
{
name: 'chromium',
use: { ...devices['Desktop Chrome'], storageState: '.auth/user.json' },
dependencies: ['setup'],
},
]
// Mock API responses for isolated testing
await page.route('**/api/users', route =>
route.fulfill({
status: 200,
contentType: 'application/json',
body: JSON.stringify([{ id: 1, name: 'Test User' }]),
})
)
page.waitForTimeout() as a fix — it masks the real problem and makes tests flaky.getByRole, getByLabel.test.fixme() is for app bugs, test.skip() is for environment constraints — don't confuse them.test.fixme() and move on.baseURL from config..only — enforce via forbidOnly: !!process.env.CI.When a spec fails, do not retry blindly by re-running, swapping locators at random, or bumping timeouts until green. Diagnose the root cause first: open the trace viewer, inspect the failing locator's aria tree, identify the real reason (timing, locator, app state), then apply a targeted fix. Trial-and-error locator swaps mask flaky test design.