smithery/gruckion

setup-playwright

Configure Playwright for E2E testing. Use when setting up end-to-end tests, when no E2E framework is detected, or when the user asks to configure browser testing.

Installation

$ npx skills add smithery/gruckion --skill setup-playwright

Similar popular skills

Related neighbors and high-traction skills in the same topics — useful to compare before installing.

Also in this package

Other skills from smithery/gruckion.

npx skills add smithery/gruckion

Browse all from smithery/gruckion

More details

Agent compatibility

Declared targets from SKILL.md / docs. Unmarked agents are not listed — the skill may still install via the CLI.

Claude Code Declared
Cursor Not declared
Codex Not declared
GitHub Copilot Not declared
Windsurf Not declared
Gemini CLI Not declared
Cline Not declared
OpenCode Not declared

Skill metadata

Parsed from SKILL.md frontmatter.

Allowed toolsRead, Write, Edit, Bash, Glob, Grep
Declared agents claude-code

Package contents

Files included with this skill beyond the listing page.

  • skill md SKILL.md 9,629 B
  • docs SUMMARY.md 186 B

History

  1. First recorded snapshot · 0 installs

SKILL.md

Setup Playwright

Configure Playwright as the end-to-end testing framework with fixtures and best practices.

When to Use This Skill

  • No E2E framework is configured in the project
  • User requests to set up E2E testing
  • Project is a web application needing browser testing
  • Migrating from Cypress to Playwright

Installation

Use ni to auto-detect the package manager. Get the exec command from .claude/marathon-ralph.json under project.commands.exec:

# Install Playwright
ni -D @playwright/test

# Install browsers (use exec command from project state: bunx, pnpm exec, npx, etc.)
# Examples:
bunx playwright install --with-deps
# or: pnpm exec playwright install --with-deps
# or: npx playwright install --with-deps

# For CI optimization, install only needed browsers
bunx playwright install chromium --with-deps

Configuration

playwright.config.ts

Create playwright.config.ts at the project root:

import { defineConfig, devices } from '@playwright/test'

export default defineConfig({
  // Test directory
  testDir: './tests/e2e',

  // Run tests in parallel
  fullyParallel: true,

  // Fail build on CI if test.only is left in code
  forbidOnly: !!process.env.CI,

  // Retry failed tests (more on CI)
  retries: process.env.CI ? 2 : 0,

  // Parallel workers
  workers: process.env.CI ? 1 : undefined,

  // Reporter configuration
  reporter: process.env.CI
    ? [['github'], ['html', { open: 'never' }]]
    : [['list'], ['html']],

  // Timeouts
  timeout: 30000,
  expect: {
    timeout: 5000,
  },

  // Shared settings for all projects
  use: {
    // Base URL for page.goto('/')
    baseURL: process.env.BASE_URL || 'http://localhost:3000',

    // Collect trace on first retry
    trace: 'on-first-retry',

    // Screenshot on failure
    screenshot: 'only-on-failure',

    // Video on first retry
    video: 'on-first-retry',
  },

  // Browser projects
  projects: [
    // Setup project for authentication
    {
      name: 'setup',
      testMatch: /.*\.setup\.ts/,
    },

    // Desktop Chrome
    {
      name: 'chromium',
      use: {
        ...devices['Desktop Chrome'],
        storageState: 'playwright/.auth/user.json',
      },
      dependencies: ['setup'],
    },

    // Desktop Firefox (optional)
    {
      name: 'firefox',
      use: {
        ...devices['Desktop Firefox'],
        storageState: 'playwright/.auth/user.json',
      },
      dependencies: ['setup'],
    },

    // Desktop Safari (optional)
    {
      name: 'webkit',
      use: {
        ...devices['Desktop Safari'],
        storageState: 'playwright/.auth/user.json',
      },
      dependencies: ['setup'],
    },

    // Mobile Chrome (optional)
    {
      name: 'Mobile Chrome',
      use: {
        ...devices['Pixel 5'],
        storageState: 'playwright/.auth/user.json',
      },
      dependencies: ['setup'],
    },
  ],

  // Run dev server before tests
  // IMPORTANT: Use the dev command from your package manager
  // Get from project state: project.commands.dev
  webServer: {
    command: process.env.DEV_COMMAND || 'bun run dev', // Adjust based on package manager
    url: 'http://localhost:3000',
    reuseExistingServer: !process.env.CI,
    timeout: 120 * 1000,
  },
})

Directory Structure

Create the recommended directory structure:

project/
├── tests/
│   └── e2e/
│       ├── fixtures/
│       │   └── test-fixtures.ts    # Custom fixtures
│       ├── pages/
│       │   ├── login.page.ts       # Page objects
│       │   └── home.page.ts
│       ├── auth.setup.ts           # Authentication setup
│       ├── home.spec.ts            # Test files
│       └── login.spec.ts
├── playwright/
│   └── .auth/
│       └── .gitkeep                # Auth state storage
├── playwright.config.ts
└── package.json

Create the directories:

mkdir -p tests/e2e/fixtures tests/e2e/pages playwright/.auth
touch playwright/.auth/.gitkeep

.gitignore

Add to .gitignore:

# Playwright
playwright-report/
test-results/
playwright/.auth/
!playwright/.auth/.gitkeep

Package.json Scripts

Add test scripts:

{
  "scripts": {
    "test:e2e": "playwright test",
    "test:e2e:ui": "playwright test --ui",
    "test:e2e:headed": "playwright test --headed",
    "test:e2e:debug": "playwright test --debug",
    "test:e2e:report": "playwright show-report"
  }
}

Authentication Setup

Create tests/e2e/auth.setup.ts for shared authentication:

import { test as setup, expect } from '@playwright/test'

const authFile = 'playwright/.auth/user.json'

setup('authenticate', async ({ page }) => {
  // Navigate to login
  await page.goto('/login')

  // Fill credentials
  await page.getByLabel(/email/i).fill('[email protected]')
  await page.getByLabel(/password/i).fill('password123')
  await page.getByRole('button', { name: /sign in/i }).click()

  // Wait for authentication to complete
  await expect(page).toHaveURL('/dashboard')

  // Save authentication state
  await page.context().storageState({ path: authFile })
})

Custom Fixtures

Create tests/e2e/fixtures/test-fixtures.ts:

import { test as base, expect } from '@playwright/test'
import { LoginPage } from '../pages/login.page'
import { HomePage } from '../pages/home.page'

// Declare fixture types
type MyFixtures = {
  loginPage: LoginPage
  homePage: HomePage
}

// Extend base test with custom fixtures
export const test = base.extend<MyFixtures>({
  loginPage: async ({ page }, use) => {
    const loginPage = new LoginPage(page)
    await use(loginPage)
  },

  homePage: async ({ page }, use) => {
    const homePage = new HomePage(page)
    await use(homePage)
  },
})

export { expect }

Page Object Model

Create tests/e2e/pages/login.page.ts:

import { type Page, type Locator } from '@playwright/test'

export class LoginPage {
  readonly page: Page
  readonly emailInput: Locator
  readonly passwordInput: Locator
  readonly submitButton: Locator
  readonly errorMessage: Locator

  constructor(page: Page) {
    this.page = page
    this.emailInput = page.getByLabel(/email/i)
    this.passwordInput = page.getByLabel(/password/i)
    this.submitButton = page.getByRole('button', { name: /sign in/i })
    this.errorMessage = page.getByRole('alert')
  }

  async goto() {
    await this.page.goto('/login')
  }

  async login(email: string, password: string) {
    await this.emailInput.fill(email)
    await this.passwordInput.fill(password)
    await this.submitButton.click()
  }
}

GitHub Actions CI

Create .github/workflows/playwright.yml:

Adjust commands based on your package manager (get from project.commands):

name: Playwright Tests

on:
  push:
    branches: [main, master]
  pull_request:
    branches: [main, master]

jobs:
  test:
    timeout-minutes: 60
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - uses: actions/setup-node@v4
        with:
          node-version: lts/*

      # For bun projects
      - uses: oven-sh/setup-bun@v2
        # if using bun

      # Install dependencies - adjust for your package manager
      # bun: bun install
      # pnpm: pnpm install
      # yarn: yarn install
      # npm: npm ci
      - name: Install dependencies
        run: bun install

      # Install Playwright browsers - use your exec command
      - name: Install Playwright Browsers
        run: bunx playwright install chromium --with-deps

      # Run tests - use your exec command
      - name: Run Playwright tests
        run: bunx playwright test

      - uses: actions/upload-artifact@v4
        if: ${{ !cancelled() }}
        with:
          name: playwright-report
          path: playwright-report/
          retention-days: 30

Verification

After setup, verify with:

# Run all tests
nr test:e2e

# Run in UI mode
nr test:e2e:ui

# Run headed (visible browser)
nr test:e2e:headed

# Debug mode
nr test:e2e:debug

# View report
nr test:e2e:report

Key Configuration Options

Option Description Default
testDir Directory containing tests ./tests
fullyParallel Run tests in parallel true
retries Retry failed tests 0
workers Parallel workers Auto
timeout Test timeout (ms) 30000
trace Trace collection 'on-first-retry'
screenshot Screenshot capture 'only-on-failure'
video Video recording 'off'
baseURL Base URL for navigation Required

CLI Commands Reference

Use your exec command from project state (bunx, pnpm exec, npx, etc.):

Command Description
{exec} playwright test Run all tests
{exec} playwright test --ui UI mode
{exec} playwright test --headed Visible browser
{exec} playwright test --debug Debug mode
{exec} playwright test file.spec.ts Run specific file
{exec} playwright test --project=chromium Run specific project
{exec} playwright codegen Generate tests
{exec} playwright show-report Open HTML report

Replace {exec} with your package manager's exec command (e.g., bunx, pnpm exec, npx).