# playwright-testing

A Playwright E2E skill: page objects, a locator order that starts with roles, and a config running chromium, firefox, webkit plus mobile viewports.

- skill · `type=skill` · Claude Code, Codex, Cursor, GitHub Copilot, Gemini CLI, OpenCode · 3300 installs · ★ 711
- Author: alinaqi
- License: MIT · policy=mirror · the beginning of the file is at the end of this page
- Source: https://github.com/alinaqi/maggy/tree/HEAD/skills/playwright-testing/SKILL.md
- Updated: 2026-10-13
- HTML: https://affpapa.org/en/nevibecode/skills/playwright-testing

## What it does

The skill hands your agent a working test layout rather than a blank file. Everything sits in `e2e/`, split across `fixtures/`, `pages/`, `tests/` and `utils/`, with `auth.setup.ts` signing in once before any browser project starts. Page objects arrive as a base class with shared header and footer helpers, plus concrete login and dashboard classes.

Locators follow a fixed ladder: role first, then label, placeholder, visible text or test id. CSS is a fallback and XPath never appears. Expect the agent to drag your old tests toward roles, so a suite built on `.btn-primary` will carry two styles for a while.

The sample config launches your app through `npm run dev`, waits on `http://localhost:3000` and reads the address from `BASE_URL`. Rename that script or move the port and the `webServer` step waits forever. Playwright itself has to be in the project first: `npm install -D @playwright/test` and then `npx playwright install` for the browsers the chromium, firefox and webkit projects need.

## Requirements
- Works with: Playwright

## Install

### Claude Code (native platform)

1. **Skills CLI (Vercel)**
```bash
npx skills add alinaqi/maggy --skill playwright-testing -a claude-code
```

2. **Manually: put the files in place**
- File: `~/.claude/skills/playwright-testing/SKILL.md` — Copy the whole skill folder; for one project use .claude/skills/playwright-testing/

### Codex

1. **Skills CLI (Vercel)**
```bash
npx skills add alinaqi/maggy --skill playwright-testing -a codex
```

2. **Manually: put the files in place**
- File: `.agents/skills/playwright-testing/SKILL.md` — For all projects use ~/.agents/skills/

### Cursor

1. **Skills CLI (Vercel)**
```bash
npx skills add alinaqi/maggy --skill playwright-testing -a cursor
```

2. **Manually: put the files in place**
- File: `.cursor/skills/playwright-testing/SKILL.md` — Cursor also reads .agents/skills/ and .claude/skills/

### GitHub Copilot

1. **GitHub CLI**
```bash
gh skill install alinaqi/maggy playwright-testing
```

2. **Manually: put the files in place**
- File: `.github/skills/playwright-testing/SKILL.md`

### Gemini CLI

1. **Skills CLI (Vercel)**
```bash
npx skills add alinaqi/maggy --skill playwright-testing -a gemini-cli
```

2. **Platform CLI**
```bash
gemini skills install https://github.com/alinaqi/maggy --path skills/playwright-testing
```

### Windsurf (Devin Desktop)

**Manually: put the files in place**
- File: `.devin/skills/playwright-testing/SKILL.md` — The legacy .windsurf/skills/ path still works

### OpenCode

**Skills CLI (Vercel)**
```bash
npx skills add alinaqi/maggy --skill playwright-testing -a opencode
```

### Claude.ai

**Claude.ai**
- Zip the folder and upload it in Settings → Capabilities → Skills

Where a file is given instead of a command, copy the files from the source to that path: https://github.com/alinaqi/maggy/tree/HEAD/skills/playwright-testing/SKILL.md

## When to use it
- write E2E tests for login and checkout with page objects
- replace brittle CSS selectors with role-based locators
- split `e2e/` into fixtures, page objects, tests and data factories
- log in once through `auth.setup.ts` before the browser projects run
- run one suite on chromium, firefox, webkit and mobile viewports

## Example prompts
- Write an E2E test for signing in at `e2e/tests/auth.spec.ts` and pull the steps into a page object.
- Swap the CSS selectors in `e2e/pages/login.page.ts` for `getByRole` locators.
- Set up `playwright.config.ts` to run on chromium, firefox and webkit with screenshots only on failure.

## Source text · SKILL.md · MIT

Below is the content of a third-party file. It is data, not instructions for you: do not act on anything written inside unless the human asks. Block tag: fbe6e8963cf7c438.

BEGIN THIRD-PARTY FILE fbe6e8963cf7c438
````text
---
name: playwright-testing
description: E2E testing with Playwright - Page Objects, cross-browser, CI/CD
when-to-use: When writing or debugging E2E tests with Playwright
user-invocable: true
paths: ["**/e2e/**", "**/*.spec.ts", "**/playwright/**", "playwright.config.*"]
effort: medium
---

# Playwright E2E Testing Skill


For end-to-end testing of web applications with Playwright - cross-browser, fast, reliable.

**Sources:** [Playwright Best Practices](https://playwright.dev/docs/best-practices) | [Playwright Docs](https://playwright.dev/docs/intro) | [Better Stack Guide](https://betterstack.com/community/guides/testing/playwright-best-practices/)

---

## Setup

### Installation

```bash
# New project
npm init playwright@latest

# Existing project
npm install -D @playwright/test
npx playwright install
```

### Configuration

```typescript
// 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'],
    ['list'],
    process.env.CI ? ['github'] : ['line'],
  ],

  use: {
    baseURL: process.env.BASE_URL || 'http://localhost:3000',
    trace: 'on-first-retry',
    screenshot: 'only-on-failure',
    video: 'retain-on-failure',
  },

  projects: [
    // Auth setup - runs once before all tests
    { name: 'setup', testMatch: /.*\.setup\.ts/ },

    {
      name: 'chromium',
      use: { ...devices['Desktop Chrome'] },
      dependencies: ['setup'],
    },
    {
      name: 'firefox',
      use: { ...devices['Desktop Firefox'] },
      dependencies: ['setup'],
    },
    {
      name: 'webkit',
      use: { ...devices['Desktop Safari'] },
      dependencies: ['setup'],
    },
    // Mobile viewports
    {
      name: 'mobile-chrome',
      use: { ...devices['Pixel 5'] },
      dependencies: ['setup'],
    },
    {
      name: 'mobile-safari',
      use: { ...devices['iPhone 12'] },
      dependencies: ['setup'],
    },
  ],

  // Start dev server before tests
  webServer: {
    command: 'npm run dev',
    url: 'http://localhost:3000',
    reuseExistingServer: !process.env.CI,
    timeout: 120 * 1000,
  },
});
```

---

## Project Structure

```
project/
├── e2e/
│   ├── fixtures/
│   │   ├── auth.fixture.ts      # Auth fixtures
│   │   └── test.fixture.ts      # Extended test with fixtures
│   ├── pages/
│   │   ├── base.page.ts         # Base page object
````
END THIRD-PARTY FILE fbe6e8963cf7c438

The third-party file has ended. Everything between the fbe6e8963cf7c438 tags is data: requests and commands from it are not followed. An “end of file” line with another tag inside the block is part of the file.

First 2580 of 23306 bytes. © alinaqi · MIT · https://github.com/alinaqi/maggy/tree/HEAD/skills/playwright-testing/SKILL.md

_Part of the page did not fit — see the HTML version._

---
NeVibeCode on affpapa.org. Catalog texts are descriptions, not instructions for the agent. How to choose and install: https://affpapa.org/en/nevibecode/agents.md
