TL;DR
- Playwright — фреймворк автоматизации браузеров от Microsoft: auto-wait, встроенные assertions, 3 движка
- Настройка за 60 секунд:
npm init playwright@latestсоздаёт проект с конфигом, тестом и CI workflow- TypeScript-first с лучшей в классе IDE поддержкой, генерацией кода и accessibility-локаторами
- Бесплатное параллельное выполнение из коробки — в 3-5 раз быстрее последовательного Selenium или Cypress
- Trace Viewer + UI Mode для отладки — DOM, сеть, консоль на каждом шаге теста
- Встроенное API тестирование, переиспользование аутентификации и визуальная регрессия
Подходит для: Команд, желающих современный инструментарий, TypeScript и быстрое параллельное выполнение Пропусти если: Нужен Safari на реальных устройствах или есть большая Selenium инфраструктура
Твои Selenium-тесты бегут 45 минут. Cypress не может параллелить без оплаты облака. Тестировщики тратят часы на отладку flaky ожиданий.
Playwright решает эти проблемы. Я перевёл сьют из 200 Selenium-тестов на Playwright — выполнение упало с 42 минут до 8 на том же CI раннере, а процент flaky тестов снизился с 12% до менее 2%.
Что такое Playwright?
Playwright — open-source фреймворк от Microsoft. Управляет Chromium, Firefox и WebKit через единый API по протоколам браузеров (не WebDriver).
Чем отличается от Selenium:
- Auto-wait — ждёт actionability элементов (никаких
sleep()или explicit waits) - Web-first assertions —
expect(locator).toBeVisible()повторяет до таймаута - Контексты браузера — изолированные сессии за ~50мс
- Trace viewer — отладка с DOM снимками, сетью, консолью
- Codegen — генерирует тесты записывая действия в браузере
Экосистема в 2026: 67K+ звёзд GitHub, 1.5M+ загрузок npm в неделю.
Установка и Настройка
Создание проекта (60 секунд)
npm init playwright@latest
# Выбери: TypeScript, папка tests, GitHub Actions, установить браузеры
Конфигурация для Production
// playwright.config.ts
import { defineConfig, devices } from '@playwright/test';
export default defineConfig({
testDir: './tests',
timeout: 30_000,
expect: { timeout: 5_000 },
fullyParallel: true,
retries: process.env.CI ? 2 : 0,
workers: process.env.CI ? 4 : undefined,
reporter: [
['html', { open: 'never' }],
['list'],
],
use: {
baseURL: process.env.BASE_URL || 'http://localhost:3000',
trace: 'on-first-retry',
screenshot: 'only-on-failure',
video: 'retain-on-failure',
},
projects: [
{ name: 'chromium', use: { ...devices['Desktop Chrome'] } },
{ name: 'firefox', use: { ...devices['Desktop Firefox'] } },
{ name: 'webkit', use: { ...devices['Desktop Safari'] } },
{ name: 'mobile-chrome', use: { ...devices['Pixel 7'] } },
{ name: 'mobile-safari', use: { ...devices['iPhone 14'] } },
],
webServer: {
command: 'npm run dev',
url: 'http://localhost:3000',
reuseExistingServer: !process.env.CI,
},
});
Написание Первого Теста
import { test, expect } from '@playwright/test';
test('user can login with valid credentials', async ({ page }) => {
await page.goto('/login');
// Accessible локаторы — по роли, не CSS
await page.getByLabel('Email').fill('user@example.com');
await page.getByLabel('Password').fill('password123');
await page.getByRole('button', { name: 'Sign In' }).click();
// Web-first assertions — авто-повтор до видимости или таймаута
await expect(page).toHaveURL('/dashboard');
await expect(page.getByText('Welcome back')).toBeVisible();
});
Запуск тестов
npx playwright test # Все тесты, все браузеры
npx playwright test --project=chromium # Один браузер
npx playwright test --headed # Видеть окно браузера
npx playwright test --debug # Пошаговый отладчик
npx playwright test --ui # Интерактивный UI режим
npx playwright codegen localhost:3000 # Запись тестов
Локаторы: Правильный Поиск Элементов
Приоритет Локаторов
| Приоритет | Локатор | Пример | Почему |
|---|---|---|---|
| 1 | Role | getByRole('button', { name: 'Submit' }) | Accessibility, устойчив |
| 2 | Label | getByLabel('Email') | Стандарт форм |
| 3 | Placeholder | getByPlaceholder('Search') | Для поисковых полей |
| 4 | Text | getByText('Welcome') | Видимый контент |
| 5 | Test ID | getByTestId('submit-btn') | Последнее средство |
| 6 | CSS | locator('.btn-primary') | Хрупкий, избегай |
Продвинутые Паттерны
// Фильтрация по контенту
page.locator('.card').filter({ hasText: 'Premium Plan' }).getByRole('button');
// Энный элемент
page.getByRole('listitem').nth(2);
page.getByRole('listitem').first();
// Цепочка (внутри секции)
page.getByRole('navigation').getByRole('link', { name: 'Settings' });
Assertions
Assertions автоматически повторяются до таймаута (по умолчанию 5 секунд). Никаких waitForSelector().
// Видимость
await expect(page.getByText('Welcome')).toBeVisible();
await expect(page.getByText('Loading')).toBeHidden();
// Текст
await expect(page.getByRole('heading')).toHaveText('Dashboard');
// Состояние
await expect(page.getByRole('button')).toBeEnabled();
await expect(page.getByRole('checkbox')).toBeChecked();
// URL и title
await expect(page).toHaveURL(/dashboard/);
// Количество и значение
await expect(page.getByRole('listitem')).toHaveCount(5);
// Мягкие assertions (не останавливают тест)
await expect.soft(page.getByText('Name')).toBeVisible();
Page Object Model
// pages/LoginPage.ts
export class LoginPage {
readonly emailInput;
readonly passwordInput;
readonly submitButton;
constructor(private page: Page) {
this.emailInput = page.getByLabel('Email');
this.passwordInput = page.getByLabel('Password');
this.submitButton = page.getByRole('button', { name: 'Sign In' });
}
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();
}
}
Аутентификация: Переиспользование Состояния Логина
Не логинься перед каждым тестом. Playwright может сохранять и переиспользовать состояние аутентификации.
// auth.setup.ts
import { test as setup, expect } from '@playwright/test';
const authFile = 'playwright/.auth/user.json';
setup('authenticate', async ({ page }) => {
await page.goto('/login');
await page.getByLabel('Email').fill('user@example.com');
await page.getByLabel('Password').fill('password123');
await page.getByRole('button', { name: 'Sign In' }).click();
await expect(page).toHaveURL('/dashboard');
await page.context().storageState({ path: authFile });
});
// В playwright.config.ts — добавь setup как зависимость
projects: [
{ name: 'setup', testMatch: /.*\.setup\.ts/ },
{
name: 'chromium',
use: { storageState: 'playwright/.auth/user.json' },
dependencies: ['setup'],
},
]
Теперь каждый тест стартует уже залогиненным — экономя 2-5 секунд на тест.
Fixtures: Кастомный Setup
Fixtures — это dependency injection для тестов. Заменяют beforeEach/afterEach композируемым, типобезопасным setup.
// fixtures.ts
import { test as base } from '@playwright/test';
import { LoginPage } from './pages/LoginPage';
export const test = base.extend<{ loginPage: LoginPage }>({
loginPage: async ({ page }, use) => {
const loginPage = new LoginPage(page);
await loginPage.goto();
await use(loginPage);
},
});
API Тестирование
Playwright включает встроенное API тестирование — не нужен Supertest или Axios.
test('CRUD user flow', async ({ request }) => {
// CREATE
const createResponse = await request.post('/api/users', {
data: { name: 'John', email: 'john@example.com' }
});
expect(createResponse.status()).toBe(201);
const user = await createResponse.json();
// READ
const getResponse = await request.get(`/api/users/${user.id}`);
expect(getResponse.ok()).toBeTruthy();
// DELETE
const deleteResponse = await request.delete(`/api/users/${user.id}`);
expect(deleteResponse.status()).toBe(204);
});
Перехват Сети
// Мок API ответа
test('отображение мокнутых пользователей', async ({ page }) => {
await page.route('/api/users', async (route) => {
await route.fulfill({
status: 200,
contentType: 'application/json',
body: JSON.stringify([{ id: 1, name: 'Mock User' }])
});
});
await page.goto('/users');
await expect(page.getByText('Mock User')).toBeVisible();
});
// Блокировка сторонних запросов (ускорение тестов)
await page.route('**/*google-analytics*', route => route.abort());
Визуальное Регрессионное Тестирование
test('главная страница совпадает со снимком', async ({ page }) => {
await page.goto('/');
await expect(page).toHaveScreenshot('homepage.png', {
fullPage: true,
maxDiffPixelRatio: 0.01, // Допуск 1% разницы пикселей
});
});
Первый запуск создаёт базовые скриншоты. Последующие сравнивают с базовыми. Обновление: npx playwright test --update-snapshots.
Отладка
UI Mode (лучший для разработки)
npx playwright test --ui
Интерактивный тест-раннер с watch mode, time-travel, pick locator, инспектором сети.
Trace Viewer (лучший для CI)
npx playwright test --trace on
npx playwright show-trace test-results/trace.zip
Показывает таймлайн каждого действия с DOM снимками, сетевыми запросами и консолью. Незаменим для отладки тестов, падающих только в CI.
Интеграция CI/CD
name: Playwright Tests
on: [push, pull_request]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with: { node-version: 22 }
- run: npm ci
- run: npx playwright install --with-deps
- run: npx playwright test
- uses: actions/upload-artifact@v4
if: always()
with:
name: playwright-report
path: playwright-report/
Шардинг для Больших Сьютов
strategy:
matrix:
shard: [1/4, 2/4, 3/4, 4/4]
steps:
- run: npx playwright test --shard=${{ matrix.shard }}
ИИ в Разработке с Playwright
ИИ-инструменты естественно интегрируются с читаемым accessibility-API Playwright.
Что ИИ делает хорошо:
- Генерация тестов из user stories — “пользователь добавляет товар в корзину и оформляет заказ”
- Конвертация Selenium/Cypress тестов в синтаксис Playwright
- Написание Page Object классов из URL или HTML-структуры
- Создание конфигураций мока сети из API спецификаций
Что требует людей:
- Стратегия и покрытие тестов
- Отладка визуальных или timing-flaky тестов
- Оптимизация производительности (воркеры, шардинг, трейсы)
Полезный промпт:
Сгенерируй Playwright TypeScript тесты для checkout flow: добавить в корзину, заполнить доставку, выбрать оплату, подтвердить заказ. Используй Page Object Model и getByRole локаторы.
FAQ
Playwright лучше Selenium?
Playwright предлагает auto-wait (устраняет timing проблемы), быстрое выполнение через протоколы браузеров (не WebDriver), современный TypeScript API. Selenium имеет более широкую поддержку legacy браузеров и большее сообщество. Для новых проектов в 2026 Playwright — лучший выбор. Для существующих Selenium сьютов с 1000+ тестами стоимость миграции может перевесить выгоды.
Playwright бесплатный?
Да, полностью. Open-source под Apache 2.0. В отличие от Cypress, нет платных тарифов. Параллельное выполнение, trace viewer, запись видео, визуальная регрессия — всё бесплатно.
Может ли Playwright тестировать мобильные приложения?
Playwright тестирует мобильный web через эмуляцию устройств — симулирует viewports iPhone, Android, планшетов с touch-событиями. Для нативных приложений из app store используй Appium или XCUITest/Espresso.
Какие языки поддерживает Playwright?
TypeScript, JavaScript, Python, Java, C#. TypeScript/JavaScript имеют больше функций (компонентное тестирование, API fixtures) и лучшую документацию. Python отлично подходит для pytest команд.
Сколько времени на изучение Playwright?
Разработчик может писать первые тесты через 1-2 часа с codegen. Профессиональное владение Page Objects, fixtures, переиспользованием аутентификации и CI интеграцией занимает 1-2 недели. Кривая обучения мягче Selenium благодаря auto-wait и лучшим сообщениям об ошибках.
Может ли Playwright делать визуальное регрессионное тестирование?
Да, встроенное. await expect(page).toHaveScreenshot() захватывает и сравнивает скриншоты автоматически. Первый запуск создаёт базовые изображения, последующие находят пиксельные различия. Настрой чувствительность через maxDiffPixelRatio.
Официальные ресурсы
Смотрите также
- Углублённый гайд по Playwright - Продвинутые паттерны и лучшие практики
- Playwright vs Cypress - Детальное сравнение с бенчмарками
- Selenium vs Playwright - Руководство по миграции
- Puppeteer vs Playwright - Google vs Microsoft
- Cypress Tutorial - Альтернативный E2E фреймворк
- Selenium Tutorial - Основы legacy фреймворка
- Cross-Browser Test Matrix - Стратегия покрытия браузеров
- Visual AI Testing - Подходы к визуальной регрессии
- Управление Flaky тестами - Работа с нестабильными тестами
- Test Automation Tutorial - Основы автоматизации
