playwright-e2e-init
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.
What this skill does
# 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
1. **Installs Playwright** and browsers
2. **Creates configuration** (playwright.config.ts)
3. **Sets up test directory** (e2e/)
4. **Creates example tests** for common flows
5. **Adds npm scripts** for running tests
6. **Updates CI/CD** to run E2E tests
## Quick Start
Example prompt:
```
Add Playwright E2E tests to this project
```
Or be specific:
```
Set up E2E tests for the authentication flow
```
## Installation
```bash
bun add -D @playwright/test
bunx playwright install chromium
```
## Configuration
### playwright.config.ts
```typescript
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
```typescript
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
```typescript
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
```typescript
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:
```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:
```yaml
- 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
```typescript
// 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
```html
<button data-testid="submit-button">Submit</button>
```
```typescript
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
```typescript
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:
```typescript
timeout: 60000, // 60 seconds
```
### Elements not found
Use `waitFor`:
```typescript
await page.waitForSelector('[data-testid="element"]');
```
### Flaky tests
Add retries and use `toPass`:
```typescript
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 |
| `debug` | Investigates flaky tests and failing browser flows |
---
**When this skill is active**, it will:
1. Install Playwright and browsers
2. Create configuration file
3. Set up e2e/ directory
4. Create example tests for existing pages
5. Add npm scripts
6. Update CI/CD workflow
Related in Web Dev
generating-lwc-components
IncludedLightning Web Components with PICKLES methodology and 165-point scoring. Use this skill when the user creates or edits LWC components, builds wire service patterns, or writes Jest tests for LWC. TRIGGER when: user creates/edits LWC components, touches lwc/**/*.js, .html, .css, .js-meta.xml files, or asks about wire service, SLDS, or Jest LWC tests. DO NOT TRIGGER when: Apex classes (use generating-apex), Aura components, or Visualforce.
tanstack-query
IncludedManage server state in React with TanStack Query v5. Set up queries with useQuery, mutations with useMutation, configure QueryClient caching strategies, implement optimistic updates, and handle infinite scroll with useInfiniteQuery. Use when: setting up data fetching in React projects, migrating from v4 to v5, or fixing object syntax required errors, query callbacks removed issues, cacheTime renamed to gcTime, isPending vs isLoading confusion, keepPreviousData removed problems.
document-processor-api
IncludedProcess documents with Nutrient DWS. Use when the user wants to generate PDFs from HTML or URLs, convert Office/images/PDFs, assemble or split packets, OCR scans, extract text/tables/key-value pairs, redact PII, watermark, sign, fill forms, optimize PDFs, or produce compliance outputs like PDF/A or PDF/UA. Triggers include convert to PDF, merge these PDFs, OCR this scan, extract tables, redact PII, sign this PDF, make this PDF/A, or linearize for web delivery.
nutrient-document-processing
IncludedProcess documents with Nutrient DWS. Use when the user wants to generate PDFs from HTML or URLs, convert Office/images/PDFs, assemble or split packets, OCR scans, extract text/tables/key-value pairs, redact PII, watermark, sign, fill forms, optimize PDFs, or produce compliance outputs like PDF/A or PDF/UA. Triggers include convert to PDF, merge these PDFs, OCR this scan, extract tables, redact PII, sign this PDF, make this PDF/A, or linearize for web delivery.
tanstack-query
IncludedManage server state in React with TanStack Query v5. Covers useMutationState, simplified optimistic updates, throwOnError, network mode (offline/PWA), and infiniteQueryOptions. Use when setting up data fetching, fixing v4→v5 migration errors (object syntax, gcTime, isPending, keepPreviousData), or debugging SSR/hydration issues with streaming server components.
accelint-nextjs-best-practices
IncludedNext.js performance optimization and best practices. Use when writing Next.js code (App Router or Pages Router); implementing Server Components, Server Actions, or API routes; optimizing RSC serialization, data fetching, or server-side rendering; reviewing Next.js code for performance issues; fixing authentication in Server Actions; or implementing Suspense boundaries, parallel data fetching, or request deduplication.