Playwright
Зачем эта статья. Selenium — классика с долгой историей. Playwright (Microsoft) чаще выбирают для новых веб-проектов: стабильные ожидания, три движка браузера, встроенные скриншоты и trace. Здесь — путь от нуля до первого автотеста в CI с пояснением терминов для новичка.
Что такое E2E-автоматизация
E2E (end-to-end) — тест проходит весь путь пользователя в реальном браузере: открыть сайт → войти → оформить заказ → увидеть подтверждение.
| Уровень | Что проверяет | Инструмент (примеры) |
|---|---|---|
| Unit | Одна функция/класс | pytest, JUnit |
| API | HTTP без UI | Postman, REST-клиент в коде |
| E2E | UI + браузер + сеть | Playwright, Selenium |
E2E медленнее и хрупче (ломается при смене вёрстки), зато ловит ошибки интеграции, которые unit не видит. Обычно их меньше, чем unit, но на критичных сценариях (оплата, регистрация) они обязательны.
Ручная проверка того же сценария — Ручное тестирование веба. Общая теория автоматизации — 115.
Selenium или Playwright?
:::info Сравнение
| Selenium | Playwright | |
|---|---|---|
| Возраст экосистемы | Очень зрелая, много legacy | Моложе, активно растёт |
| Ожидания элементов | Часто пишут вручную | Auto-wait по умолчанию |
| Браузеры | Через отдельные драйверы | Chromium, Firefox, WebKit из коробки |
| Отладка | Логи + скрины сами | Trace Viewer, video, screenshot on fail |
| Когда брать | Enterprise, старый стек, Appium-опыт | Новый фронт, React/Vue, CI на GitHub Actions |
Обе технологии валидны. Для обучения начните с Playwright на зелёном проекте; Selenium — если команда уже на нём сидит. :::
Словарь
| Термин | Значение |
|---|---|
| Headless | Браузер без окна — быстрее в CI |
| Headed | С видимым окном — удобно при отладке |
| Локатор | Способ найти элемент на странице |
| Flaky-тест | Иногда падает без изменений кода — часто тайминги |
| Fixture | Подготовка окружения (браузер, авторизация) |
| Page Object | Класс страницы со своими кнопками и полями |
Установка
Нужны Node.js 18+ (или Python/Java — Playwright мультиязычен; ниже — TypeScript как самый частый выбор в E2E).
npm init playwright@latest
Мастер спросит: папку тестов (tests), базовый URL, установку браузеров. После установки:
npx playwright test
npx playwright test --ui
--ui — UI Mode: пошаговый прогон, удобно QA без глубокого опыта в коде.
Структура проекта (типично):
project/
playwright.config.ts # настройки
tests/
example.spec.ts # тесты
package.json
Первый тест — построчно
import { test, expect } from '@playwright/test';
test('главная страница открывается', async ({ page }) => {
await page.goto('https://example.com');
await expect(page).toHaveTitle(/Example Domain/);
});
| Строка | Что происходит |
|---|---|
test(...) | Один сценарий с именем для отчёта |
async ({ page }) | Playwright даёт вкладку браузера page |
goto | Переход по URL, ожидание загрузки |
expect(...).toHaveTitle | Проверка заголовка; ретраи до таймаута — без sleep |
Структура E2E как в автоматизации: подготовка → действие → проверка (assert).
Несколько тестов в файле
test.describe('Каталог', () => {
test.beforeEach(async ({ page }) => {
await page.goto('/catalog');
});
test('список товаров виден', async ({ page }) => {
await expect(page.getByRole('heading', { name: 'Каталог' })).toBeVisible();
});
});
beforeEach — общая подготовка перед каждым тестом в группе.
Локаторы — как не ловить flaky-тесты
Flaky — тест упал на CI, локально прошёл. Частая причина — элемент ещё не появился или изменился селектор.
Приоритет локаторов (от устойчивых к хрупким):
| Приоритет | Локатор | Пример |
|---|---|---|
| 1 | getByRole | page.getByRole('button', { name: 'Войти' }) |
| 2 | getByLabel | page.getByLabel('Email') |
| 3 | getByTestId | page.getByTestId('checkout-submit') |
| 4 | getByText | осторожно при смене языка |
| 5 | CSS/XPath | только если иначе никак |
Попросите разработчиков добавить data-testid на критичные элементы — договорённость команды.
await page.getByTestId('login-email').fill('qa@test.local');
await page.getByTestId('login-password').fill('Secret123!');
await page.getByRole('button', { name: 'Войти' }).click();
await expect(page.getByText('Личный кабинет')).toBeVisible();
Auto-wait и assertions
Playwright перед кликом ждёт, пока элемент visible, stable, enabled. Ошибка Selenium «element not interactable» встречается реже.
await expect(page.locator('.toast-success')).toHaveText('Заказ оформлен');
await expect(page).toHaveURL(/\/orders\/\d+/);
Проверка API в том же тесте
const responsePromise = page.waitForResponse('**/api/orders');
await page.getByRole('button', { name: 'Оформить' }).click();
const response = await responsePromise;
expect(response.status()).toBe(201);
Так вы связываете UI и проверку API в одном сценарии.
Авторизация без повторного логина
Долгий логин в каждом тесте замедляет прогон. Паттерн storageState:
// tests/auth.setup.ts
import { test as setup } from '@playwright/test';
setup('authenticate', async ({ page }) => {
await page.goto('/login');
await page.getByTestId('login-email').fill('qa@test.local');
await page.getByTestId('login-password').fill('Secret123!');
await page.getByRole('button', { name: 'Войти' }).click();
await page.context().storageState({ path: 'playwright/.auth/user.json' });
});
В playwright.config.ts укажите storageState: 'playwright/.auth/user.json' для проектов, которым нужна сессия. Один раз залогинились — остальные тесты стартуют уже авторизованными.
Page Object (кратко)
Когда тестов больше пяти, выносите страницы в классы — как в автоматизации:
// pages/LoginPage.ts
import { Page, Locator } from '@playwright/test';
export class LoginPage {
readonly email: Locator;
readonly password: Locator;
readonly submit: Locator;
constructor(private page: Page) {
this.email = page.getByTestId('login-email');
this.password = page.getByTestId('login-password');
this.submit = page.getByRole('button', { name: 'Войти' });
}
async login(email: string, password: string) {
await this.email.fill(email);
await this.password.fill(password);
await this.submit.click();
}
}
В тесте: const login = new LoginPage(page); await login.login(...). Вёрстка поменялась — правите один файл.
playwright.config.ts — что трогать чаще всего
import { defineConfig, devices } from '@playwright/test';
export default defineConfig({
testDir: './tests',
timeout: 30_000,
use: {
baseURL: 'https://test.shop.example',
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'] } },
],
});
| Опция | Смысл |
|---|---|
baseURL | Короткие goto('/catalog') вместо полного URL |
timeout | Максимум на один тест |
trace | Запись шагов при падении / ретрае |
projects | Прогон в нескольких браузерах |
Отладка падений
После падения:
npx playwright show-trace trace.zip
Trace Viewer — шаги, DOM, сеть; аналог «записи сессии» для разбора бага.
Дополнительно:
npx playwright test --debug
npx playwright codegen https://test.shop.example
codegen — запись действий в код (стартовая заготовка, потом рефакторинг локаторов).
CI (GitHub Actions)
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 20
- run: npm ci
- run: npx playwright install --with-deps
- run: npx playwright test
- uses: actions/upload-artifact@v4
if: failure()
with:
name: playwright-report
path: playwright-report/
Отчёт HTML — артефакт для команды QA. При падении скачайте trace и report из CI.
Типичные ошибки новичка
| Ошибка | Решение |
|---|---|
sleep(5000) везде | expect с auto-wait |
| XPath на полный DOM | getByRole / getByTestId |
| Один огромный тест на 200 строк | test.describe + Page Object |
| Тесты зависят от порядка | Изолировать данные, уникальный email |
| Гоняют только локально headless=false | Периодически прогон как в CI |
Практика в этом разделе
| Шаг | Материал |
|---|---|
| Ручная проверка UI | Ручное тестирование веба |
| Практикум E2E | 1013 — пользовательский сценарий |
| Каталог инструментов | 118 — UI и E2E |
| Данные после сценария | SQL для тестировщика |
Куда дальше
- Официальная документация: playwright.dev
- Сравнение с Cypress и Selenium — Автоматизация тестирования
- Полный справочник инструментов — 118.md
См. также
Другие статьи этого же раздела в боковом меню (как на странице «О разделе»). Что такое тестирование, чем оно отличается от QA, цепочка ошибка→дефект→сбой, верификация и валидация, виды проверок и роли в команде. Юнит-тест представляет собой автоматизированную проверку отдельной единицы программного кода. Практическое занятие и реализация интеграционного теста. Практическое занятие и реализация ручного тестирования. Практическое занятие и реализация нагрузочного тестирования. Тестирование разных признаков - доступ к коду, модульное, интеграционное, системное, приёмочное и прочие. Основные фазы - планирование и контроль, анализ и проектирование, реализация и выполнение, оценка критериев, отчетность. Что такое артефакты, каким целям и принципам они служат. Системное тестирование, в чём суть и чем отличается E2E. Использование программных средств для выполнения проверок без вмешательства человека. Порядок тестирования, как правильно проектировать стратегию реализации контроля качества. Тестирование программного обеспечения предполагает верификацию поведения отдельных компонентов и системы в целом при контролируемых и воспроизводимых условиях.Основы тестирования программного обеспечения
Подготовка среды и создание первого теста
Проверка взаимодействия компонентов
Проверка пользовательского сценария
Проверка надежности под нагрузкой
Классификация видов тестирования
Жизненный цикл тестирования
Артефакты качества в проекте
End-to-End и системное тестирование
Автоматизация тестирования
Последовательность этапов тестирования
Объекты и уровни тестирования