К основному содержанию
правило

playwright — правило для Cursor: E2E-тесты на TypeScript

Правило задаёт Cursor стандарты написания end-to-end тестов на Playwright: официальный раннер, устойчивые локаторы, отказ от ручных задержек.

Установить в Cursor · Вручную: положить файлы Все способы и платформы ↓
.cursor/rules/playwright.mdc
Открыть на GitHub

Что делает playwright

Это файл правил playwright.mdc, который Cursor подхватывает для файлов **/*.{js,ts}. Внутри восемь разделов с примерами «плохо» и «хорошо»: импорт из @playwright/test вместо низкоуровневой библиотеки playwright, локаторы через getByRole, getByLabel и getByTestId вместо хрупких CSS-цепочек, авторетраи в expect вместо page.waitForTimeout(). Дальше — Page Object Model с вынесением селекторов и действий в отдельные классы.

Есть разделы про производительность и изоляцию: переиспользование состояния авторизации через storageState и global-setup.ts, блокировка лишних запросов через context.route, мок ответов API через page.route. Отдельный блок — настройка playwright.config.ts с трейсами, скриншотами и видео для разбора падений в CI. Последний раздел про линтеры и форматтеры обрывается на середине.

Правило рассчитано на проекты, где тесты пишут на TypeScript. Если у вас JavaScript без типов или другой раннер, часть примеров придётся переписывать — они опираются на типы Page и Locator. Установка сводится к одному файлу в .cursor/rules/.

Какие задачи решает

  • убрать page.waitForTimeout() и прочие ручные паузы из тестов
  • заменить хрупкие CSS-селекторы на локаторы по роли и метке
  • вынести повторяющиеся шаги логина в Page Object
  • переиспользовать сессию авторизации между тестами через storageState
  • замокать ответы API, чтобы тесты не зависели от бэкенда

Примеры запросов агенту

  • Напиши E2E-тест на Playwright для страницы логина по правилам из playwright.mdc
  • Перепиши этот тест: убери waitForTimeout и замени селекторы на getByRole
  • Сделай Page Object для страницы оформления заказа и подключи его в тестах

Как установить playwright

Вручную: положить файлы

.cursor/rules/playwright.mdc

Во frontmatter: description, globs, alwaysApply

По шагам, с командами для каждой платформы: Cursor rules: файлы .mdc, четыре режима и замена .cursorrules

Из того же набора69

qwik Правило Cursor, которое подсказывает агенту, как писать Qwik-приложения: component$, useStore, QRL с суффиксом $ и загрузка данных через loader$. ★ 3 579звёзд репо pyramid Правило для Cursor с набором практик по Python-фреймворку Pyramid: структура проекта, конфигурация, транзакции и предикаты представлений. ★ 3 579звёзд репо pygame Правило для Cursor задаёт каркас Pygame-проекта: один UIManager, фиксированный шаг времени, вёрстка на якорях и темы в JSON. ★ 3 579звёзд репо prisma Правило для Cursor, которое задаёт агенту порядок работы с Prisma ORM: один клиент на приложение, выборки без лишних полей, аккуратные миграции. ★ 3 579звёзд репо phoenix Правило для Cursor задаёт, как писать Phoenix-приложения на Elixir: контексты, форматирование, тесты. Пригодится, если агент уже правит ваш код. ★ 3 579звёзд репо pandas Правило для Cursor задаёт стиль работы с pandas: векторизация вместо циклов, явные .loc и .iloc, экономные типы данных. Пригодится, если агент часто пишет медленный код. ★ 3 579звёзд репо notion-api Правило для Cursor задаёт, как писать код интеграций с Notion API: модули, токены в переменных окружения, официальные SDK и пагинация. ★ 3 579звёзд репо nginx Правило для Cursor задаёт, как писать конфиги NGINX: модульные include-файлы, современный TLS, кэш и лимиты. Пригодится, если агент правит nginx.conf в вашем проекте. ★ 3 579звёзд репо

Похожие

playwright-e2e-testing fugazi Скилл для написания и поддержки E2E-тестов на Playwright с TypeScript: пользовательские сценарии, формы, авторизация, моки и визуальные сравнения. CX Codex +1 615установок playwright-automation kindlmann Учит агента писать стабильные E2E-тесты на Playwright в TypeScript: Page Object Model, фикстуры, автоожидание, параллельный запуск. Пригодится, когда заводите новый набор тестов или переписываете флакающие. CX Codex +1 1 900установок playwright-best-practices currents.dev Справочник по тестированию на Playwright: от написания E2E-сценариев до Page Object Model. Помогает разбирать флакующие тесты, настраивать мокирование API и проверять доступность. CX Codex +1 98 500установок playwright-core testdino-hq Скилл даёт готовые паттерны Playwright для сквозных тестов, API и моков в проектах на TypeScript и JavaScript. Пригодится при отладке упавших сценариев и настройке фикстур. CX Codex +1 778установок playwright-skill testdino.com Скилл снабжает агента 79 справочниками по Playwright 1.64 на TypeScript и JavaScript. Помогает писать тесты, разбирать падения в CI, настраивать моки и устранять флаки-сценарии. CX Codex +1 6 200установок playwright-expert https://github.com/Jeffallan Настраивает E2E-тестирование на Playwright, создаёт классы Page Object и помогает устранять нестабильные проверки через трассировку. CX Codex +1 5 300установок

Рядом в теме «Тесты и QA»

Всё по теме «Тесты и QA» →

Вопросы о playwright

Как установить правило playwright в Cursor?

Создайте файл .cursor/rules/playwright.mdc в корне проекта и вставьте в него содержимое правила.

Что делает правило playwright?

Задаёт Cursor стандарты для E2E-тестов на Playwright: официальный раннер @playwright/test, семантичные локаторы, авторетраи в expect, Page Object Model, мок API и настройку трейсов в конфиге.

Нужен ли TypeScript для этого правила?

Примеры написаны на TypeScript и используют типы Page и Locator из @playwright/test, поэтому в проекте на чистом JavaScript их придётся адаптировать.

Исходный текст

playwright.mdc · CC0-1.0
---
description: Definitive guidelines for writing robust, maintainable, and high-quality end-to-end tests with Playwright in TypeScript.
globs: **/*.{js,ts}
---
# Playwright Best Practices

Playwright is the gold standard for reliable E2E testing. These rules ensure your tests are fast, stable, and easy to maintain, aligning with modern 2025 development standards for reliability, quality, and structure.

## 1. Always Use `@playwright/test`

Leverage the official test runner for built-in fixtures, isolation, and web-first assertions. Avoid the low-level `playwright` library for E2E tests.

❌ BAD: Using `playwright` directly
```typescript
import { chromium } from 'playwright';
// ... manual browser/context setup and teardown
const browser = await chromium.launch();
const page = await browser.newPage();
// ...
await browser.close();
```

✅ GOOD: Using `@playwright/test`
```typescript
import { test, expect } from '@playwright/test';
test('should navigate to home', async ({ page }) => {
  await page.goto('/');
  await expect(page).toHaveTitle(/Home/);
});
```

## 2. Prioritize Robust Locators

Use Playwright's built-in Locators API, favoring user-facing attributes over brittle CSS selectors. This drastically improves test stability.

❌ BAD: Fragile, implementation-dependent selectors
```typescript
await page.locator('div.container > ul > li:nth-child(2) > button').click();
```

✅ GOOD: Semantic, user-facing locators
```typescript
await page.getByRole('button', { name: 'Add to Cart' }).click();
await page.getByLabel('Username').fill('testuser');
await page.getByTestId('product-item-123').click();
```

## 3. Embrace Web-First Assertions

Playwright's `expect` assertions automatically retry until conditions are met, eliminating manual waits and flakiness. Never use `page.waitForTimeout()`.

❌ BAD: Manual, flaky waits and generic assertions
```typescript
await page.waitForTimeout(2000); // 🚨 Flaky!
const title = await page.title();
assert.equal(title, 'My Page'); // 🚨 Not web-first
```

✅ GOOD: Reliable, auto-retrying assertions
```typescript
await expect(page).toHaveTitle(/My Page/);
await expect(page.getByText('Welcome')).toBeVisible();
await expect(page.getByRole('checkbox')).toBeChecked();
```

## 4. Implement the Page Object Model (POM)

Encapsulate selectors and actions within dedicated classes. This improves readability, reusability, and maintainability.

❌ BAD: Repeated selectors and logic across tests
```typescript
// test-login.spec.ts
await page.getByLabel('Username').fill('user');
await page.getByLabel('Password').fill('pass');
await page.getByRole('button', { name: 'Login' }).click();

// test-profile.spec.ts
// ... same login steps repeated ...
```

✅ GOOD: Centralized Page Object
```typescript
// pages/LoginPage.ts
import { Page, Locator } from '@playwright/test';

export class LoginPage {
  readonly page: Page;
  readonly usernameInput: Locator;
  readonly passwordInput: Locator;
  readonly loginButton: Locator;

  constructor(page: Page) {
    this.page = page;
    this.usernameInput = page.getByLabel('Username');
    this.passwordInput = page.getByLabel('Password');
    this.loginButton = page.getByRole('button', { name: 'Login' });
  }

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

  async login(username: string, password: string) {
    await this.usernameInput.fill(username);
    await this.passwordInput.fill(password);
    await this.loginButton.click();
  }
}

// tests/login.spec.ts
import { test, expect } from '@playwright/test';
import { LoginPage } from '../pages/LoginPage';

test('should successfully log in', async ({ page }) => {
  const loginPage = new LoginPage(page);
  await loginPage.navigate();
  await loginPage.login('testuser', 'password');
  await expect(page).toHaveURL(/dashboard/);
});
```

## 5. Optimize Performance with Auth State & Route Blocking

Reduce test execution time by reusing authenticated sessions and blocking unnecessary network requests.

❌ BAD: Logging in for every test and loading all assets
```typescript
test('view profile', async ({ page }) => {
  await page.goto('/login');
  await page.getByLabel('Username').fill('user');
  await page.getByLabel('Password').fill('pass');
  await page.getByRole('button', { name: 'Login' }).click();
  await page.goto('/profile'); // Loads all images, analytics, etc.
});
```

✅ GOOD: Reusing auth state and blocking requests
```typescript
// playwright.config.ts
import { defineConfig } from '@playwright/test';
export default defineConfig({
  use: {
    storageState: 'playwright-auth.json', // Path to save/load auth state
  },
});

// global-setup.ts (run once before all tests)
import { chromium, expect } from '@playwright/test';
export default async function globalSetup() {
  const browser = await chromium.launch();
  const page = await browser.newPage();
  await page.goto('/login');
  await page.getByLabel('Username').fill('testuser');
  await page.getByLabel('Password').fill('password');
  await page.getByRole('button', { name: 'Login' }).click();
  await expect(page).toHaveURL(/dashboard/);
  await page.context().storageState({ path: 'playwright-auth.json' });
  await browser.close();
}

// tests/profile.spec.ts
import { test, expect } from '@playwright/test';
test('should display user profile', async ({ page, context }) => {
  // Block unnecessary resources for faster tests
  await context.route('**/*.{png,jpg,jpeg,gif,webp,svg,css}', route => route.abort());
  await page.goto('/profile'); // Automatically uses saved auth state
  await expect(page.getByText('Welcome, testuser!')).toBeVisible();
});
```

## 6. Mock APIs for Deterministic Tests

Isolate your UI tests from backend flakiness by intercepting and mocking API responses.

❌ BAD: Relying on a live, potentially unstable backend
```typescript
test('display products', async ({ page }) => {
  await page.goto('/products'); // Fetches from real API
  await expect(page.getByText('Product A')).toBeVisible();
});
```

✅ GOOD: Mocking API responses
```typescript
test('display mocked products', async ({ page }) => {
  await page.route('**/api/products', route => {
    route.fulfill({
      status: 200,
      contentType: 'application/json',
      body: JSON.stringify([{ id: 1, name: 'Mock Product' }]),
    });
  });
  await page.goto('/products');
  await expect(page.getByText('Mock Product')).toBeVisible();
});
```

## 7. Leverage CI/CD Features for Debugging

Configure tracing, screenshots, and video recording in your `playwright.config.ts` to instantly diagnose failures in CI.

```typescript
// playwright.config.ts
import { defineConfig } from '@playwright/test';
export default defineConfig({
  reporter: [['html'], ['list']],
  use: {
    trace: 'on-first-retry', // Record trace only on first retry
    screenshot: 'on',       // Always take a screenshot on failure
    video: 'on-first-retry',// Record video on first retry
  },
});
```

## 8. Maintain Code Quality with Linters & Formatters

Integrate ESLint (with Playwright plugin) and Prettier into your workflow via pre-commit hooks to enforce consistent code style and catch errors early.

```json
// package.json (example scripts)
{
  "scripts": {
    "lint": "eslint . --ext .ts",
    "format": "prettier --write .",
    "test:e2e": "playwright test"
  },
  "devDependencies": {
    "@playwright/test": "^1.x.x",
    "@typescript-eslint/eslint-plugin": "^7.x.x",
    "@typescript-eslint/parser": "^7.x.x",
    "eslint": "^8.x.x",
    "eslint-plugin-playwright": "^1.x.x",
    "prettier": "^3.x.x",
    "husky": "^9.x.x",
    "lint-staged": "^15.x.x"
  }
}
```
```javascript
// .eslintrc.js
module.exports = {
  root: true,
  parser: '@typescript-eslint/parser',
  plugins: ['@typescript-eslint', 'playwright'],
  extends: [
    'eslint:recommended',
    'plugin:@typescript-eslint/recommended',
    'plugin:playwright/recommended',
  ],
  rules: {
    // Add custom rules or override defaults here
  },
  env: {
    node: true,
    browser: true,
  },
};
```
```json
// .prettierrc
{
  "singleQuote": true,
  "semi": true,
  "trailingComma": "all"
}
```
```json
// .husky/pre-commit
#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"

npx lint-staged
```
```json
// .lintstagedrc.js
module.exports = {
  '*.{ts,js}': ['eslint --fix', 'prettier --write'],
};
```

© sanjeed5 · CC0-1.0 · sanjeed5/awesome-cursor-rules-mdc

Смотрите также

Спонсоры проекта

Компании, которые помогают держать аналитику открытой