agents-inc/skills/src/skills/web-testing-playwright-e2e/SKILL.md
web-testing-playwright-e2e
Playwright E2E testing patterns - test structure, Page Object Model, locator strategies, assertions, network mocking, visual regression, parallel execution, fixtures, and configuration
- Source repository stars
- 23
- Declared platforms
- 0
- Static risk flags
- 0
- Last source update
- 2026-08-09
- Source checked
- 2026-08-28
Decision brief
What it does: where it fits
Quick Guide: Use Playwright for end-to-end tests that verify complete user workflows through the real browser. Focus on critical user journeys, use accessibility-based locators (getByRole), and leverage auto-waiting assertions -- never use manual sleeps. Isolate each test with i…
Not for
- Tasks that require unconfirmed production actions or broad system permissions.
- Environments where the pinned source and install steps cannot be inspected.
Compatibility matrix
Platform support, with evidence labels
| Platform | Status | Evidence | What to check |
|---|---|---|---|
| Codex | Not declared | No explicit evidence | Portability before use |
| Claude Code | Not declared | No explicit evidence | Portability before use |
| Cursor | Not declared | No explicit evidence | Portability before use |
| Gemini CLI | Not declared | No explicit evidence | Portability before use |
Installation
Inspect first. Install second.
The source command is displayed only when detected. A safe inspection prompt is always available so your agent can explain every action before execution.
npx skills add https://github.com/agents-inc/skills --skill "src/skills/web-testing-playwright-e2e"Inspect the Agent Skill "web-testing-playwright-e2e" from https://github.com/agents-inc/skills/blob/81d43a51211aca12c85dcc16085fa99014ec548e/src/skills/web-testing-playwright-e2e/SKILL.md at commit 81d43a51211aca12c85dcc16085fa99014ec548e. List every install step, command, network request, credential, file read/write, external action, and rollback step. Explain whether it fits my task. Do not install or execute anything until I approve.
Workflow
What the source asks the agent to do
- 01
CRITICAL: Before Using This Skill
All code must follow project conventions in CLAUDE.md (kebab-case, named exports, import ordering, import type, named constants)
Testing critical user-facing workflows (login, checkout, form submission)Multi-step user journeys that span multiple pagesCross-browser compatibility testing - 02
Philosophy
Playwright E2E tests verify that your application works correctly from the user's perspective. They interact with the real browser, navigate through actual pages, and validate user-visible behavior.
Test user-visible behavior - Focus on what end users see and interact with, not implementation detailsUse accessibility locators - getByRole mirrors how screen readers and users interact with pagesIsolate tests completely - Each test has its own browser context, cookies, and storage - 03
Core Patterns
Group related tests with test.describe, use beforeEach for common navigation, and name constants for all test data.
Group related tests with test.describe, use beforeEach for common navigation, and name constants for all test data.Why good: Groups related tests logically, beforeEach maintains isolation, named constants prevent magic stringsSee examples/core.md Pattern 1 for complete user flow with error scenarios. - 04
Pattern 1: Test Structure and Organization
Group related tests with test.describe, use beforeEach for common navigation, and name constants for all test data.
Group related tests with test.describe, use beforeEach for common navigation, and name constants for all test data.Why good: Groups related tests logically, beforeEach maintains isolation, named constants prevent magic stringsSee examples/core.md Pattern 1 for complete user flow with error scenarios. - 05
Pattern 2: Page Object Model
Encapsulate page structure and interactions in reusable classes. Define locators in the constructor, expose domain-specific methods.
Encapsulate page structure and interactions in reusable classes. Define locators in the constructor, expose domain-specific methods.Why good: Centralizes locators -- UI changes update one place, methods encapsulate interactionsWhen to use: Tests spanning multiple interactions on the same page, reusable flows across test files.
Permission review
Static risk signals and limitations
No configured static risk pattern was detected
This is not proof of safety. Runtime behavior, indirect dependencies, and hidden external systems are outside the static scan.
Evidence record
Why each signal appears
| Signal | Value | Evidence type | Meaning |
|---|---|---|---|
| Quality score | 95/100 | Computed | Documentation, specificity, maintenance, and trust rules |
| Repository stars | 23 | Source | Repository attention, not individual Skill quality |
| Compatibility | 0 platforms | Source | Declared in the catalog source record |
| Usage guide | automated source guide | Editorial | Generated or reviewed according to the visible evidence level |
Pinned source
Provenance and original SKILL.md
- Repository
- agents-inc/skills
- Skill path
- src/skills/web-testing-playwright-e2e/SKILL.md
- Commit
- 81d43a51211aca12c85dcc16085fa99014ec548e
- License
- MIT
- Collected
- 2026-08-28
- Default branch
- main
View the original SKILL.md
Playwright E2E Testing Patterns
Quick Guide: Use Playwright for end-to-end tests that verify complete user workflows through the real browser. Focus on critical user journeys, use accessibility-based locators (
getByRole), and leverage auto-waiting assertions -- never use manual sleeps. Isolate each test with its own browser context. Mock external APIs via route interception for reliability.
<critical_requirements>
CRITICAL: Before Using This Skill
All code must follow project conventions in CLAUDE.md (kebab-case, named exports, import ordering,
import type, named constants)
(You MUST use getByRole() as your primary locator strategy - it mirrors how users interact with the page)
(You MUST test complete user workflows end-to-end - login flows, checkout processes, form submissions)
(You MUST use web-first assertions that auto-wait - toBeVisible(), toHaveText(), not manual sleeps)
(You MUST isolate tests - each test runs independently with its own browser context)
(You MUST use named constants for test data - no magic strings or numbers in test files)
</critical_requirements>
Auto-detection: Playwright, E2E testing, end-to-end testing, browser automation, page.goto, test.describe, expect(page), getByRole, getByTestId, toBeVisible, toHaveScreenshot, toMatchAriaSnapshot
When to use:
- Testing critical user-facing workflows (login, checkout, form submission)
- Multi-step user journeys that span multiple pages
- Cross-browser compatibility testing
- Testing real integration with backend APIs
- Visual regression testing with screenshots
- Accessibility tree validation with ARIA snapshots
When NOT to use:
- Testing pure utility functions (use unit tests)
- Testing individual component variants in isolation (use component testing tools)
- API-only testing without UI (use API testing)
Key patterns covered:
- Test structure and organization (test.describe, test, hooks)
- Page Object Model pattern for maintainability
- Locator strategies prioritizing accessibility (getByRole, getByLabel, chaining, operators)
- Web-first assertions with auto-waiting (toBeVisible, toHaveText, soft assertions)
- Network mocking and interception (route.fulfill, route.abort, response modification)
- Visual regression testing (toHaveScreenshot, masking, thresholds)
- Custom and worker-scoped fixtures
- Clock API for time-dependent testing (v1.45+)
- ARIA snapshot testing for accessibility (v1.49+)
- Accessibility assertions (v1.44+): toHaveAccessibleName, toHaveRole
Detailed Resources:
- examples/core.md - User flows, page objects, network mocking, config, auth fixtures
- examples/page-objects.md - Base page inheritance, hierarchy
- examples/api-mocking.md - Response interception and modification
- examples/visual-testing.md - Screenshot comparison, component visual testing
- examples/fixtures.md - Combined fixtures, database seeding, IndexedDB state
- examples/advanced-features.md - Clock API, ARIA snapshots, worker fixtures, polling assertions, accessibility assertions
- reference.md - Decision frameworks, locator/assertion tables, anti-patterns, CLI commands, configuration reference
Philosophy
Playwright E2E tests verify that your application works correctly from the user's perspective. They interact with the real browser, navigate through actual pages, and validate user-visible behavior.
Core Principles:
- Test user-visible behavior - Focus on what end users see and interact with, not implementation details
- Use accessibility locators -
getByRolemirrors how screen readers and users interact with pages - Isolate tests completely - Each test has its own browser context, cookies, and storage
- Trust auto-waiting - Playwright automatically waits for elements; no manual sleeps needed
- Mock external dependencies - Use route interception for third-party APIs to ensure reliability
When E2E tests provide the most value:
- Critical business workflows (authentication, payments, core features)
- User journeys spanning multiple pages or components
- Testing real backend integration
- Cross-browser compatibility verification
- Catching integration bugs that unit tests miss
When E2E tests may not be the best choice:
- Testing pure utility functions (unit tests are faster and more precise)
- Testing component styling variants (use visual testing tools)
- Testing every edge case (balance with unit and integration tests)
Core Patterns
Pattern 1: Test Structure and Organization
Group related tests with test.describe, use beforeEach for common navigation, and name constants for all test data.
const LOGIN_URL = "/login";
const VALID_EMAIL = "[email protected]";
test.describe("Login Flow", () => {
test.beforeEach(async ({ page }) => {
await page.goto(LOGIN_URL);
});
test("successful login redirects to dashboard", async ({ page }) => {
await page.getByLabel(/email/i).fill(VALID_EMAIL);
// ... fill password, click sign in
await expect(page).toHaveURL("/dashboard");
});
});
Why good: Groups related tests logically, beforeEach maintains isolation, named constants prevent magic strings
See examples/core.md Pattern 1 for complete user flow with error scenarios.
Pattern 2: Page Object Model
Encapsulate page structure and interactions in reusable classes. Define locators in the constructor, expose domain-specific methods.
export class LoginPage {
readonly emailInput: Locator;
readonly signInButton: Locator;
constructor(page: Page) {
this.emailInput = page.getByLabel(/email/i);
this.signInButton = page.getByRole("button", { name: /sign in/i });
}
async login(email: string, password: string) {
await this.emailInput.fill(email);
// ...
}
}
Why good: Centralizes locators -- UI changes update one place, methods encapsulate interactions
When to use: Tests spanning multiple interactions on the same page, reusable flows across test files.
When not to use: Simple one-off tests where inline locators are clearer.
See examples/core.md Pattern 2 for full page objects with fixtures, examples/page-objects.md for base page inheritance.
Pattern 3: Locator Strategies
Prioritize accessibility-based locators that mirror how users interact with the application.
// BEST: Accessibility-based
await page.getByRole("button", { name: /submit/i });
await page.getByLabel(/email address/i);
await page.getByText(/welcome back/i);
// ACCEPTABLE: Test IDs for complex cases
await page.getByTestId("user-avatar"); // When no semantic role exists
// AVOID: Implementation-dependent
await page.locator("#submit-btn"); // Fragile
await page.locator(".btn-primary"); // CSS class can change
Chaining and filtering narrow down to specific elements without fragile selectors:
await page
.getByRole("listitem")
.filter({ hasText: "Product A" })
.getByRole("button", { name: /add to cart/i })
.click();
// Exclude elements (v1.33+)
await page
.getByRole("listitem")
.filter({ hasNot: page.getByText("Out of stock") })
.first()
.click();
// Combine conditions (v1.33+)
const btn = page.getByRole("button").and(page.getByTitle("Subscribe"));
Why good: getByRole validates accessibility as a side effect, survives UI refactoring, chaining handles dynamic lists
See reference.md for locator priority table and common ARIA role mappings.
Pattern 4: Web-First Assertions
Use assertions that automatically wait and retry until the condition is met.
// Auto-waits for element visibility
await expect(page.getByText("Welcome")).toBeVisible();
// Auto-waits for URL
await expect(page).toHaveURL(/\/dashboard/);
// Negated assertions also auto-wait
await expect(page.getByRole("progressbar")).not.toBeVisible();
Why good: Eliminates flaky tests from race conditions, no manual sleeps needed
// BAD: Manual waiting
await page.waitForTimeout(2000); // Arbitrary sleep!
const text = await page.textContent(".result");
expect(text).toBe("Success"); // Non-waiting assertion
Why bad: Fixed timeouts are either too short (flaky) or too long (slow), doesn't adapt to actual page load time
Soft assertions collect all failures in one run:
await expect.soft(page.getByTestId("avatar")).toBeVisible();
await expect.soft(page.getByText("Premium")).toBeVisible();
// Test continues, all failures reported at end
See reference.md for complete assertion table, polling assertions, and accessibility assertions (v1.44+).
Pattern 5: Network Mocking and Interception
Mock external APIs for reliable, isolated tests. Use page.route() to intercept and fulfill requests.
const API_USERS = "**/api/users";
await page.route(API_USERS, (route) =>
route.fulfill({
status: 200,
contentType: "application/json",
body: JSON.stringify({ id: "user-123", name: "John Doe" }),
}),
);
// Error simulation
await page.route(API_USERS, (route) => route.abort("failed")); // Network failure
Why good: Eliminates third-party flakiness, enables testing error states, controls exact data
Modifying real responses (hybrid approach):
await page.route("**/api/products", async (route) => {
const response = await route.fetch();
const json = await response.json();
json.products = json.products.map((p: { price: number }) => ({
...p,
price: p.price * 0.9,
}));
await route.fulfill({ response, json });
});
See examples/core.md Pattern 3 for complete mocking with error states, examples/api-mocking.md for response modification.
Pattern 6: Visual Regression Testing
Capture and compare screenshots to detect unintended visual changes.
await expect(page).toHaveScreenshot("homepage.png");
// Mask dynamic content
await expect(page).toHaveScreenshot("dashboard.png", {
mask: [page.getByTestId("current-time"), page.getByTestId("random-ad")],
});
// Disable animations for deterministic screenshots
await expect(page).toHaveScreenshot("stable.png", { animations: "disabled" });
Why good: Catches unintended visual changes, masking prevents false positives from timestamps
See examples/visual-testing.md for component visual testing with state variations.
Pattern 7: Custom Fixtures
Extend the base test with reusable fixtures for page objects, authentication, and shared setup.
export const test = base.extend<{
loginPage: LoginPage;
authenticatedPage: void;
}>({
loginPage: async ({ page }, use) => {
await use(new LoginPage(page));
},
authenticatedPage: [
async ({ context }, use) => {
await context.addCookies([
{ name: "session", value: "token", domain: "localhost", path: "/" },
]);
await use();
await context.clearCookies();
},
{ auto: true },
],
});
Why good: Encapsulates setup + teardown, auto fixtures eliminate repetitive auth, composable
See examples/core.md Pattern 5 for auth fixtures, examples/fixtures.md for combined fixtures and database seeding, examples/advanced-features.md for worker-scoped fixtures.
Pattern 8: Clock API (v1.45+)
Control time for testing countdowns, session timeouts, and scheduled events.
await page.clock.install({ time: new Date("2024-02-02T08:00:00") });
await page.goto("/dashboard");
await page.clock.fastForward("25:00"); // Jump 25 minutes
await expect(page.getByText(/session expires/i)).toBeVisible();
CRITICAL: clock.install() MUST be called before any other clock methods.
See examples/advanced-features.md for countdown testing and session timeout patterns.
Pattern 9: ARIA Snapshot Testing (v1.49+)
Validate accessibility tree structure programmatically.
await expect(page.getByRole("navigation")).toMatchAriaSnapshot(`
- navigation:
- link "Home"
- link "Products"
- link "About"
`);
Why good: Catches ARIA issues before production, documents expected accessibility behavior
See examples/advanced-features.md for complex component ARIA snapshots.
<red_flags>
RED FLAGS
High Priority Issues:
- Using
page.waitForTimeout()with fixed delays -- causes flaky or slow tests, use auto-waiting assertions instead - Using CSS selectors like
.btn-primaryor#submit-btn-- fragile and break on refactoring, usegetByRole - Not testing error states -- only happy paths leaves error handling untested
- Tests sharing state or data -- causes flaky failures in parallel execution, isolate each test completely
Medium Priority Issues:
- Using
getByTestIdas primary locator -- misses accessibility validation, prioritizegetByRole - No network mocking for external APIs -- third-party flakiness affects your tests
- Running E2E tests only on one browser -- cross-browser issues go undetected
- Screenshots without masking dynamic content -- timestamps and ads cause false positives
Common Mistakes:
- Hardcoded test data scattered throughout files -- use named constants
- Testing implementation details (e.g., Redux state via
window.__REDUX_STATE__) instead of user behavior - Not using
beforeEachfor common setup -- leads to duplicated code - Mixing E2E tests with unit tests in the same directory
Gotchas & Edge Cases:
toBeVisible()auto-waits for the element;toBeAttached()checks DOM presence without visibility -- prefer visibility checks for most cases- Screenshots vary by OS and browser -- run visual tests in consistent CI environment
beforeAllruns once per worker, not once globally -- useglobalSetupin config for true one-time setup- Network routes are global to context -- routes set in
beforeEachoverride previous; always set up fresh per test - Parallel tests cannot share state -- use fixtures for per-test setup, not shared variables
toBeEditable()throws on non-editable elements (v1.50+) -- verify element type first- Glob URL patterns in
page.route()no longer support?and[](v1.52+) -- use regex instead route.continue()cannot override Cookie header (v1.52+) -- usecontext.addCookies()instead_reactand_vueselectors removed (v1.58) -- use data-testid or role-based locators
</red_flags>
<critical_reminders>
CRITICAL REMINDERS
All code must follow project conventions in CLAUDE.md
(You MUST use getByRole() as your primary locator strategy - it mirrors how users interact with the page)
(You MUST test complete user workflows end-to-end - login flows, checkout processes, form submissions)
(You MUST use web-first assertions that auto-wait - toBeVisible(), toHaveText(), not manual sleeps)
(You MUST isolate tests - each test runs independently with its own browser context)
(You MUST use named constants for test data - no magic strings or numbers in test files)
Failure to follow these rules will result in flaky tests, false positives, and maintenance nightmares.
</critical_reminders>
Frequently asked questions
What to verify before installation and use
What does the web-testing-playwright-e2e source document cover?
Quick Guide: Use Playwright for end-to-end tests that verify complete user workflows through the real browser. Focus on critical user journeys, use accessibility-based locators (getByRole), and leverage auto-waiting assertions -- never use manual sleeps. Isolate each test with i…
How do I install web-testing-playwright-e2e?
The source record exposes this install command: npx skills add https://github.com/agents-inc/skills --skill "src/skills/web-testing-playwright-e2e". Inspect the command and pinned source before running it.
Alternatives
Compare before choosing
coreyhaines31/marketingskills
ab-testing
When the user wants to plan, design, or implement an A/B test or experiment, or build a growth experimentation program. Also use when the user mentions "A/B test," "split test," "experiment," "test this change," "variant copy," "multivariate test," "hypothesis," "should I test this," "which version is better," "test two versions," "statistical significance," "how long should I run this test," "growth experiments," "experiment velocity," "experiment backlog," "ICE score," "experimentation program
narrative-io/narrative-skills-marketplace
design-analysis
Translate a fuzzy analytical question into a rigorous investigation plan. Interrogates the ask, grounds the plan in the available data dictionary, applies analytical best practices, and produces a structured brief of query specifications for a downstream query-writing skill. Plans, does not write SQL. Use when: "why did X drop", "is there a relationship between A and B", "who are our highest-value customers", "what's driving the change in Y", "investigate this trend", "design an analysis for", "
vasilyu1983/AI-Agents-public
qa-testing-ios
Guides iOS testing with XCTest, XCUITest, Swift Testing, simctl, and xcresult. Use when choosing destinations, controlling flakes, or parsing test artifacts for native apps.
vasilyu1983/AI-Agents-public
foundations-consumer-neuroscience
Consumer-neuroscience primitives for attention, arousal, bonding, narrative, memory, and reward. Use when shaping ethical UX, neuro study design, or DMCC/AI Act gates.