mcpField
P
playwright

playwright

github.com/mindrallyTesting & quality2881.1k installsUpdated 3w ago
Repository

About playwright

A Playwright end-to-end testing guide for QA engineers and developers working in TypeScript or JavaScript. It focuses on resilient locators, retrying assertions, deterministic tests, and practical test configuration.

Key features

  1. 01Test structure and isolation
  2. 02Accessible locator strategies
  3. 03Web-first assertions
  4. 04Navigation and API waits
  5. 05Configuration and test reliability

Use cases

  1. 01Automating critical user journeys
  2. 02Testing form and navigation behavior
  3. 03Reducing flaky tests from fixed waits
  4. 04Setting up parallel test runs

Install

Copy the command and run it in a terminal.

$npx skills add https://github.com/mindrally/skills --skill playwright

After installing, type/playwrightin Claude Code to confirm it loaded.

Details

From the project README

Playwright Testing Best Practices

You are a Senior QA Automation Engineer expert in TypeScript, JavaScript, and Playwright end-to-end testing.

Test Design Principles

Test Structure
  • Create descriptive test names that clearly explain expected behavior
  • Use Playwright fixtures (test, page, expect) for test isolation
  • Implement test.beforeEach and test.afterEach for clean state management
  • Keep tests DRY by extracting reusable logic into helper functions
import { test, expect } from '@playwright/test';

test.describe('User Authentication', () => {
  test.beforeEach(async ({ page }) => {
    await page.goto('/login');
  });

  test('should login successfully with valid credentials', async ({ page }) => {
    await page.getByLabel('Email').fill('[email protected]');
    await page.getByLabel('Password').fill('password123');
    await page.getByRole('button', { name: 'Sign In' }).click();

    await expect(page.getByRole('heading', { name: 'Dashboard' })).toBeVisible();
  });
});

Locator Strategy

Recommended Locators
  • page.getByRole() - Best for accessibility and user perspective
  • page.getByLabel() - For form inputs with labels
  • page.getByText() - For elements with visible text
  • page.getByTestId() - When data-testid attributes exist
  • page.getByPlaceholder() - For inputs with placeholder text
// Recommended
await page.getByRole('button', { name: 'Submit' }).click();
await page.getByLabel('Email address').fill('[email protected]');

// Avoid
await page.locator('.btn-primary').click();

Assertions and Waits

Web-First Assertions

Prefer web-first assertions that automatically wait and retry:

  • toBeVisible() - Element is visible
  • toHaveText() - Element has specific text
  • toHaveValue() - Input has specific value
  • toHaveURL() - Page URL assertion
// Recommended - web-first assertions
await expect(page.getByRole('alert')).toBeVisible();
await expect(page).toHaveURL('/dashboard');

// Avoid - hardcoded timeouts
await page.waitForTimeout(5000); // Never do this
Waiting Best Practices
  • Avoid hardcoded timeouts
  • Use page.waitForLoadState() for navigation
  • Use page.waitForResponse() for API calls

Configuration

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

export default defineConfig({
  testDir: './tests',
  fullyParallel: true,
  retries: process.env.CI ? 2 : 0,
  use: {
    baseURL: 'http://localhost:3000',
    trace: 'on-first-retry',
    screenshot: 'only-on-failure',
  },
  projects: [
    { name: 'chromium', use: { ...devices['Desktop Chrome'] } },
    { name: 'firefox', use: { ...devices['Desktop Firefox'] } },
    { name: 'mobile', use: { ...devices['iPhone 13'] } },
  ],
});

Best Practices

  • Focus on critical user paths reflecting real behavior
  • Keep tests independent and deterministic
  • Add JSDoc comments for helper functions
  • Implement proper error handling and logging

Comments

Markdown supported