Use when adding new error messages to React, or seeing "unknown error code" warnings.
npx skills add shipshitdev/library --skill "playwright-e2e-init"
Install specific skill from multi-skill repository
# Description
Initialize Playwright end-to-end testing for Next.js and React projects. Sets up configuration, creates example tests, and integrates with existing CI/CD. Use when adding E2E tests to a frontend project.
# SKILL.md
name: playwright-e2e-init
description: Initialize Playwright end-to-end testing for Next.js and React projects. Sets up configuration, creates example tests, and integrates with existing CI/CD. Use when adding E2E tests to a frontend project.
Playwright E2E Testing Initialization
Sets up Playwright for end-to-end testing in Next.js and React applications.
When to Use
This skill should be used when:
- Adding E2E tests to a Next.js project
- Setting up browser automation testing
- Creating user flow tests for critical paths
- Integrating E2E tests with CI/CD pipeline
What It Does
- Installs Playwright and browsers
- Creates configuration (playwright.config.ts)
- Sets up test directory (e2e/)
- Creates example tests for common flows
- Adds npm scripts for running tests
- Updates CI/CD to run E2E tests
Quick Start
Ask Claude to:
Add Playwright E2E tests to this project
Or be specific:
Set up E2E tests for the authentication flow
Installation
bun add -D @playwright/test
bunx playwright install chromium
Configuration
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", { open: "never" }], ["list"]],
use: {
baseURL: "http://localhost:3000",
trace: "on-first-retry",
screenshot: "only-on-failure",
},
projects: [
{ name: "chromium", use: { ...devices["Desktop Chrome"] } },
],
webServer: {
command: "bun run dev",
url: "http://localhost:3000",
reuseExistingServer: !process.env.CI,
timeout: 120 * 1000,
},
});
Test Structure
e2e/
├── home.spec.ts # Homepage tests
├── auth.spec.ts # Authentication flow
├── navigation.spec.ts # Navigation tests
└── fixtures/
└── test-data.ts # Shared test data
Example Tests
Basic Navigation Test
import { test, expect } from "@playwright/test";
test.describe("Homepage", () => {
test("should load successfully", async ({ page }) => {
await page.goto("/");
await expect(page).toHaveTitle(/My App/);
});
test("should navigate to about page", async ({ page }) => {
await page.goto("/");
await page.click('a[href="/about"]');
await expect(page).toHaveURL("/about");
});
});
Authentication Flow Test
import { test, expect } from "@playwright/test";
test.describe("Authentication", () => {
test("should login successfully", async ({ page }) => {
await page.goto("/login");
await page.fill('input[name="email"]', "[email protected]");
await page.fill('input[name="password"]', "password123");
await page.click('button[type="submit"]');
await expect(page).toHaveURL("/dashboard");
await expect(page.locator("text=Welcome")).toBeVisible();
});
test("should show error for invalid credentials", async ({ page }) => {
await page.goto("/login");
await page.fill('input[name="email"]', "[email protected]");
await page.fill('input[name="password"]', "wrongpassword");
await page.click('button[type="submit"]');
await expect(page.locator("text=Invalid credentials")).toBeVisible();
});
});
Form Submission Test
import { test, expect } from "@playwright/test";
test.describe("Contact Form", () => {
test("should submit form successfully", async ({ page }) => {
await page.goto("/contact");
await page.fill('input[name="name"]', "John Doe");
await page.fill('input[name="email"]', "[email protected]");
await page.fill('textarea[name="message"]', "Hello, this is a test message");
await page.click('button[type="submit"]');
await expect(page.locator("text=Thank you")).toBeVisible();
});
});
NPM Scripts
Add to package.json:
{
"scripts": {
"e2e": "playwright test",
"e2e:ui": "playwright test --ui",
"e2e:headed": "playwright test --headed",
"e2e:debug": "playwright test --debug",
"e2e:report": "playwright show-report"
}
}
CI/CD Integration
GitHub Actions
Add to your CI workflow:
- name: Install Playwright Browsers
run: bunx playwright install --with-deps chromium
- name: Run E2E tests
run: bun run e2e
env:
CI: true
- name: Upload Playwright Report
uses: actions/upload-artifact@v4
if: always()
with:
name: playwright-report
path: playwright-report/
retention-days: 7
Best Practices
1. Test Critical User Flows
Focus on:
- Authentication (login, logout, signup)
- Core features (main value proposition)
- Payment/checkout flows
- Error handling
2. Use Page Object Model
// e2e/pages/login.page.ts
import { Page } from "@playwright/test";
export class LoginPage {
constructor(private page: Page) {}
async goto() {
await this.page.goto("/login");
}
async login(email: string, password: string) {
await this.page.fill('input[name="email"]', email);
await this.page.fill('input[name="password"]', password);
await this.page.click('button[type="submit"]');
}
}
3. Use Data Attributes for Selectors
<button data-testid="submit-button">Submit</button>
await page.click('[data-testid="submit-button"]');
4. Keep Tests Independent
Each test should:
- Set up its own state
- Not depend on other tests
- Clean up after itself
5. Use Fixtures for Common Setup
import { test as base } from "@playwright/test";
const test = base.extend({
authenticatedPage: async ({ page }, use) => {
await page.goto("/login");
await page.fill('input[name="email"]', "[email protected]");
await page.fill('input[name="password"]', "password");
await page.click('button[type="submit"]');
await use(page);
},
});
Troubleshooting
Tests timing out
Increase timeout in config:
timeout: 60000, // 60 seconds
Elements not found
Use waitFor:
await page.waitForSelector('[data-testid="element"]');
Flaky tests
Add retries and use toPass:
await expect(async () => {
await expect(page.locator("text=Success")).toBeVisible();
}).toPass({ timeout: 10000 });
Integration with Other Skills
| Skill | Integration |
|---|---|
testing-cicd-init |
Sets up unit tests first |
testing-expert |
Provides testing patterns |
webapp-testing |
Alternative automation skill |
When this skill is active, Claude will:
- Install Playwright and browsers
- Create configuration file
- Set up e2e/ directory
- Create example tests for existing pages
- Add npm scripts
- Update CI/CD workflow
# Supported AI Coding Agents
This skill is compatible with the SKILL.md standard and works with all major AI coding agents:
Learn more about the SKILL.md standard and how to use these skills with your preferred AI coding agent.