playwright-e2e-testing
Skill256 starsChanged 23 days agoMITView on GitHub
Author and maintain versioned Playwright (@playwright/test) TypeScript UI specs for browser user flows. Use when asked to create, run, debug, or refactor E2E tests, form/navigation/auth flows, responsive checks, UI mocking, fixtures, Page Objects, or visual comparisons. Use api-testing for standalone REST/GraphQL contracts and playwright-cli for live browser sessions. Keywords: E2E spec, Playwright test, POM, fixtures, UI regression.
- Reads credentials
- Installs packages
8 other projects use a version of this.
Adopted by
Most recently taken up by
- JPeetz/agent-skillstheir own version, first seen Oct 28, 2026
- aiqadam/qadam-flowtheir own version, first seen Oct 8, 2026
- Ghosteken/agent-harnesstheir own version, first seen Oct 1, 2026
- ZeroTokenClaw/agents-skillsword for word, first seen Sep 21, 2026
- bkjain655/agent-skillstheir own version, first seen Aug 2, 2026
- jpoindexter/theft-kittheir own version, first seen May 20, 2026
Used with
Projects with it also use api-and-interface-design, receiving-code-review and 1 more.
Other files people use alongside this one.
Files found in the same public projects as a version of this one, more often than they turn up anywhere else. Each project counts once, large collections count for less, and this file's own repository is left out.
LLl0k0laDSkillapi-and-interface-design
Use when designing APIs, module boundaries, or any public interface. Use when creating REST or GraphQL endpoints, defining type contracts between modules, or establishing boundaries between frontend and backend.
Also in 3 projects that use this
CloudflareSkillreceiving-code-review
Use when receiving code review feedback, before implementing suggestions, especially if feedback seems unclear or technically questionable - requires technical rigor and verification, not performative agreement or blind implementation
Also in 3 projects that use this
OpenAISkillrequesting-code-review
Use when completing tasks, implementing major features, or before merging to verify work meets requirements
Also in 3 projects that use this
Other versions8 projects use a version of this.
Word for word · 1
- ZeroTokenClaw/agents-skills★ 1100% same
Edited · 0
None found.
Wrote their own version · 7
- JPeetz/agent-skills★ 14same name
- aiqadam/qadam-flow★ 5same name
- Ghosteken/agent-harness★ 2same name
- FutureAtoms/claude-skills-backup★ 1same name
- impeto-ai/claude-skills-impeto★ 1same name
- jpoindexter/theft-kit★ 1same name
- bkjain655/agent-skills★ 0same name
How matches are found. Word for word: the exact same text. Edited: shares passages with this file (“99% same” means 99% of its five-word phrases also appear here; 10% or more counts). Their own version: similar meaning, or, weakest, the same name. We can’t tell which project had it first. Projects are counted among the 200 most-starred candidates, and mentions are links to the repository we found, up to 50 per site, so both counts are a floor.
In this repository11 other files it gives its agents.
- AGENTS.mdAGENTS.md
- CLAUDE.mdCLAUDE.md
- a11y-playwright-testingSkill
- accessibility-selenium-testingSkill
- api-testingSkill
- grill-me-qaSkill
- playwright-cliSkill
- playwright-regression-testingSkill
- qa-investigationSkill
- qa-manual-istqbSkill
- webapp-selenium-testingSkill
The file
We split this skill into the rules it gives an agent
5 rules. 0 are common, 1 is distinctive, and 4 are very specific to this project.
0
Common
Most of the 4 edited versions we read keep these.
1
Distinctive
This author's own choices. Worth a look.
4
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Distinctive: line 53
Before writing tests, clarify:
- Very specific: line 67
Always use @playwright/test with TypeScript for type safety and better IDE support.
- Very specific: line 83
Prefer role-based locators (getByRole) with accessible names, then label → placeholder → text → test ID → CSS (last resort).
- Very specific: line 103
Use test.step() for readable reports and failure localization:
- Very specific: line 194
Use playwright.config.ts for project-wide settings:
“Common” is measured: kept by at least 6 in 10 of the 4 edited versions of this file we could read. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
Playwright E2E Testing (TypeScript)
Comprehensive toolkit for end-to-end testing of web applications using Playwright with TypeScript. Enables robust UI testing, UI-dependent API setup, and responsive design verification following best practices.
Activation: This skill is triggered when authoring or maintaining versioned Playwright UI specs and their test infrastructure.
When to Use This Skill
- Write E2E tests for user flows, forms, navigation, and authentication
- UI-dependent API setup via the
requestfixture or network interception - Responsive testing across mobile, tablet, and desktop viewports
- Debug flaky tests using traces, screenshots, videos, and Playwright Inspector
- Setup test infrastructure with Page Object Model and fixtures
- Mock/intercept APIs for isolated, deterministic testing
- Visual regression testing with screenshot comparisons
Do NOT Use For
- Standalone API/contract testing with no browser (use
api-testing). - Driving a live browser interactively for exploration or debugging (use
playwright-cli). - Governing a large regression suite, tiers, or CI sharding strategy (use
playwright-regression-testing). - Selenium/Java browser automation (use
webapp-selenium-testing).
Prerequisites
| Requirement | Details |
| Node.js | v18+ recommended |
| Package Manager | npm, yarn, or pnpm |
| Playwright | @playwright/test package |
| TypeScript | typescript + ts-node (optional but recommended) |
| Browsers | Installed via npx playwright install |
Quick Setup
# Initialize new project
npm init playwright@latest
# Or add to existing project
npm install -D @playwright/test
npx playwright installFirst Questions to Ask
Before writing tests, clarify:
- App URL: Local dev server command + port, or staging URL?
- Critical flows: Which user journeys must be covered (happy path + error states)?
- Browsers/devices: Chrome, Firefox, Safari? Mobile viewports?
- API strategy: Real backend, mocked responses, or hybrid?
- Test data: Seed data available? Reset/cleanup strategy?
Core Principles
1. Test Runner & TypeScript
Always use @playwright/test with TypeScript for type safety and better IDE support.
import { test, expect } from "@playwright/test";
test("user can login", async ({ page }) => {
await page.goto("/login");
await page.getByLabel("Email").fill("user@test.com");
await page.getByLabel("Password").fill("password123");
await page.getByRole("button", { name: "Sign in" }).click();
await expect(page).toHaveURL(/.*dashboard/);
});2. Locator Strategy (Priority Order)
Prefer role-based locators (getByRole) with accessible names, then label → placeholder → text → test ID → CSS (last resort). XPath is never used.
➡️ Full priority hierarchy, role reference, and examples: Locator Strategies: Priority — the single source of truth.
3. Auto-Waiting & Web-First Assertions
Playwright auto-waits for elements. Never use sleep() or arbitrary timeouts.
// [ok] Web-first assertions (auto-retry)
await expect(page.getByRole("alert")).toBeVisible();
await expect(page).toHaveURL(/dashboard/);
await expect(page.getByTestId("status")).toHaveText("Success!");
// [no] Avoid manual waits
await page.waitForTimeout(2000); // Bad practice4. Test Structure with Steps
Use test.step() for readable reports and failure localization:
test("checkout flow", async ({ page }) => {
await test.step("Add item to cart", async () => {
await page.goto("/products/1");
await page.getByRole("button", { name: "Add to Cart" }).click();
});
await test.step("Complete checkout", async () => {
await page.goto("/checkout");
await page.getByRole("button", { name: "Pay Now" }).click();
});
await test.step("Verify confirmation", async () => {
await expect(page.getByRole("heading")).toContainText("Order Confirmed");
});
});Key Workflows
Forms & Navigation
// Form submit and wait for navigation (auto-waiting)
await page.getByRole("button", { name: "Login" }).click();
await expect(page).toHaveURL(/.*dashboard/);
// Form with API response validation
const responsePromise = page.waitForResponse(
(r) => r.url().includes("/api/login") && r.status() === 200,
);
await page.getByRole("button", { name: "Login" }).click();
const response = await responsePromise;API Testing (Request Fixture)
test("API health check", async ({ request }) => {
const response = await request.get("/api/health");
expect(response.ok()).toBeTruthy();
expect(await response.json()).toMatchObject({ status: "ok" });
});API Mocking & Interception
test("handles API error", async ({ page }) => {
await page.route("**/api/users", (route) =>
route.fulfill({
status: 500,
body: JSON.stringify({ error: "Server error" }),
}),
);
await page.goto("/users");
await expect(page.getByRole("alert")).toContainText("Something went wrong");
});Responsive Testing
const viewports = [
{ width: 375, height: 667, name: "mobile" },
{ width: 768, height: 1024, name: "tablet" },
{ width: 1280, height: 720, name: "desktop" },
];
for (const vp of viewports) {
test(`navigation works on ${vp.name}`, async ({ page }) => {
await page.setViewportSize(vp);
await page.goto("/");
// Mobile: hamburger menu
if (vp.width < 768) {
await page.getByRole("button", { name: /menu/i }).click();
}
await page.getByRole("link", { name: "About" }).click();
await expect(page).toHaveURL(/about/);
});
}Configuration
Use playwright.config.ts for project-wide settings:
import { defineConfig, devices } from "@playwright/test";
export default defineConfig({
testDir: "./tests",
retries: process.env.CI ? 2 : 0,
reporter: [["html"], ["junit", { outputFile: "results.xml" }]],
use: {
baseURL: "http://localhost:3000",
trace: "on-first-retry",
screenshot: "only-on-failure",
video: "retain-on-failure",
},
projects: [
{ name: "chromium", use: devices["Desktop Chrome"] },
{ name: "mobile", use: devices["Pixel 5"] },
],
webServer: {
command: "npm run dev",
url: "http://localhost:3000",
reuseExistingServer: !process.env.CI,
},
});Troubleshooting
| Problem | Cause | Solution |
| Element not found | Wrong locator or not rendered | Use PWDEBUG=1 to inspect, verify with getByRole |
| Timeout waiting | Element hidden or slow load | Check for overlays, increase timeout, use waitFor() |
| Flaky tests | Race conditions, animations | Add test.step(), use proper waits, disable animations |
| Strict mode violation | Multiple elements match | Use .first(), .filter(), or more specific locator |
| Screenshots differ | Dynamic content | Mask dynamic areas, use deterministic data |
| CI fails, local passes | Environment differences | Check baseURL, timeouts, webServer config |
| API mock not working | Route pattern mismatch | Use **/api/... glob, verify with page.on('request') |
CLI Quick Reference
| Command | Description |
npx playwright test | Run all tests headless |
npx playwright test --ui | Open UI mode (interactive) |
npx playwright test --headed | Run with visible browser |
npx playwright test --debug | Run with Playwright Inspector |
npx playwright test -g "login" | Run tests matching pattern |
npx playwright test --project=chromium | Run specific project |
npx playwright show-report | Open HTML report |
npx playwright codegen | Generate tests by recording |
PWDEBUG=1 npx playwright test | Debug with Inspector |
DEBUG=pw:api npx playwright test | Verbose API logging |
Red Flags
- CSS/XPath locators when a role/label/testId is available — brittle and breaks on refactor.
waitForTimeout/ manual sleeps instead of web-first auto-retrying assertions.- Tests sharing state and depending on execution order — flaky and order-coupled.
- Assertions only on status/URL with no visible-state check — hides render regressions.
- Inline page setup repeated across tests instead of fixtures — duplication and drift.
References
| Document | Content |
| Snippets: Setup | Config, auth setup, custom fixtures & logging |
| Snippets: Interactions | Form interactions, API testing & network interception |
| Snippets: Viewports & Auth | Responsive viewports & authentication patterns |
| Snippets: Assertions & Debug | Assertions, debug commands & utility helpers |
| Locator Strategies: Priority | Locator priority hierarchy & role-based locators |
| Locator Strategies: Text | Label, text, placeholder, alt-text & test-ID locators |
| Locator Strategies: Filtering | Filtering, chaining & complex locator patterns |
| Locator Strategies: Anti & Debug | Anti-patterns, CSS last-resort, debugging & quick reference |
| POM: Basics | POM concepts, directory structure, base page & fluent API |
| POM: Components | Page object & reusable component object implementation |
| POM: Fixtures | Custom & authenticated page-object fixtures |
| POM: Practices | Best practices, anti-patterns & a complete worked example |
| Debugging: Tools & UI | Debugging tools, UI mode, Inspector & headed mode |
| Debugging: Tracing & Logs | Trace viewer, verbose logging, screenshots & videos |
| Debugging: Errors & Network | Console/page errors & network debugging |
| Debugging: Flaky & Locators | Flaky-test fixes, locator debugging & quick commands |
Verification
- Uses custom fixture injection — No
new PageObject()calls in spec files; all POMs injected via fixtures - Locators use recommended strategies — All locators use
getByRole(),getByTestId(), orgetByText(); no CSS selectors for interactive elements - Tests are independent — Each test sets up and tears down its own state; no
beforeAllwith shared mutable state - Error states covered — At least one test verifies error/empty/loading states alongside happy path
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

