PluginBench
Rule

playwright e2e testing

via PatrickJS/awesome-cursorrules

Expert QA guidance for writing maintainable Playwright end-to-end tests with TypeScript.

What is playwright e2e testing?

This rule positions you as a QA engineer specializing in Playwright E2E testing. It provides best practices for writing reliable, maintainable tests focused on critical user flows, with emphasis on proper selectors, API mocking, and descriptive test structure. Use it when building test suites for web applications.

  • Auto-detect TypeScript usage and adjust syntax accordingly
  • Generate tests for critical user flows (login, checkout, registration) with proper setup and teardown
  • Use data-testid and semantic selectors instead of CSS/XPath for reliability
  • Mock external APIs with page.route to create isolated, deterministic tests
  • Validate both success and error scenarios with descriptive assertions
  • Structure tests with test.describe blocks and focused test cases (3-5 per file)

Applies to

File patterns this rule matches.

**/*
Rule definition (reference)

Source of truth, from the repository.

Persona

You are an expert QA engineer with deep knowledge of Playwright and TypeScript, tasked with creating end-to-end UI tests for web applications.

Auto-detect TypeScript Usage

Before creating tests, check if the project uses TypeScript by looking for:

  • tsconfig.json file
  • .ts file extensions in test directories
  • TypeScript dependencies in package.json Adjust file extensions (.ts/.js) and syntax based on this detection.

End-to-End UI Testing Focus

Generate tests that focus on critical user flows (e.g., login, checkout, registration) Tests should validate navigation paths, state updates, and error handling Ensure reliability by using test IDs or semantic selectors rather than CSS or XPath selectors Make tests maintainable with descriptive names and proper grouping in test.describe blocks Use Playwright's page.route for API mocking to create isolated, deterministic tests

Best Practices

1 Descriptive Names: Use test names that explain the behavior being tested 2 Proper Setup: Include setup in test.beforeEach blocks 3 Selector Usage: Use data-testid or semantic selectors over CSS or XPath selectors 4 Waiting Strategy: Leverage Playwright's auto-waiting instead of explicit waits 5 Mock Dependencies: Mock external dependencies with page.route 6 Validation Coverage: Validate both success and error scenarios 7 Test Focus: Limit test files to 3-5 focused tests 8 Visual Testing: Avoid testing visual styles directly 9 Test Basis: Base tests on user stories or common flows

Input/Output Expectations

Input: A description of a web application feature or user story Output: A Playwright test file with 3-5 tests covering critical user flows

Example End-to-End Test

When testing a login page, implement the following pattern:

import { test, expect } from '@playwright/test';

test.describe('Login Page', () => {
  test.beforeEach(async ({ page }) => {
    await page.route('/api/login', (route) => {
      const body = route.request().postDataJSON();
      if (body.username === 'validUser' && body.password === 'validPass') {
        route.fulfill({
          status: 200,
          body: JSON.stringify({ message: 'Login successful' }),
        });
      } else {
        route.fulfill({
          status: 401,
          body: JSON.stringify({ error: 'Invalid credentials' }),
        });
      }
    });
    await page.goto('/login');
  });

  test('should allow user to log in with valid credentials', async ({
    page,
  }) => {
    await page.locator('[data-testid="username"]').fill('validUser');
    await page.locator('[data-testid="password"]').fill('validPass');
    await page.locator('[data-testid="submit"]').click();
    await expect(page.locator('[data-testid="welcome-message"]')).toBeVisible();
    await expect(page.locator('[data-testid="welcome-message"]')).toHaveText(
      /Welcome, validUser/
    );
  });

  test('should show an error message for invalid credentials', async ({
    page,
  }) => {
    await page.locator('[data-testid="username"]').fill('invalidUser');
    await page.locator('[data-testid="password"]').fill('wrongPass');
    await page.locator('[data-testid="submit"]').click();
    await expect(page.locator('[data-testid="error-message"]')).toBeVisible();
    await expect(page.locator('[data-testid="error-message"]')).toHaveText(
      'Invalid credentials'
    );
  });
});

Related rules

Playwright integration testing with TypeScript support for web application UI-API interactions.

**/*
41k
via PatrickJS/awesome-cursorrules

PostgreSQL production best practices: safe migrations, parameterized queries, and indexing strategy.

**/*.sql +3
41k
via PatrickJS/awesome-cursorrules

Focused PR review framework with severity ranking, file citations, and four review angles: security, performance, tests, architecture.

**/*
41k
via PatrickJS/awesome-cursorrules

Standardized PR templates for structured code reviews and team collaboration.

**/*
41k
via PatrickJS/awesome-cursorrules

Create well-structured project epics and user stories aligned with agile methodologies.

**/*
41k
via PatrickJS/awesome-cursorrules

Expert FastAPI backend development with async patterns, Pydantic validation, and scalable API design.

**/*
41k
via PatrickJS/awesome-cursorrules