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.

Safety Notice

This listing is imported from skills.sh public index metadata. Review upstream SKILL.md and repository scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "playwright-e2e-init" with this command: npx skills add shipshitdev/library/shipshitdev-library-playwright-e2e-init

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

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"]', "test@example.com");
    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"]', "wrong@example.com");
    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"]', "john@example.com");
    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"]', "test@example.com");
    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

SkillIntegration
testing-cicd-initSets up unit tests first
testing-expertProvides testing patterns
webapp-testingAlternative automation skill

When this skill is active, Claude 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

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

Coding

financial-operations-expert

No summary provided by upstream source.

Repository SourceNeeds Review
Coding

youtube-video-analyst

No summary provided by upstream source.

Repository SourceNeeds Review
Coding

nestjs-testing-expert

No summary provided by upstream source.

Repository SourceNeeds Review