Перейти к основному содержимому

Playwright

Тестировщику Разработчику
Теория данных (раздел 3)

Playwright — это современный бесплатный фреймворк с открытым исходным кодом от Microsoft, предназначенный для автоматизации веб-браузеров и комплексного (End-to-End) тестирования веб-приложений. Он позволяет разработчикам и QA-инженерам писать надежные тесты, которые работают во всех популярных браузерных движках с использованием единого API. Поддерживает Chromium (Google Chrome, Microsoft Edge), WebKit (Apple Safari) и Firefox. Тесты можно писать на JavaScript/TypeScript, Python, Java и C# (.NET). Избавляет от нестабильных тестов (flakiness), самостоятельно дожидаясь появления элементов на экране перед кликом или вводом текста.

Playwright создаёт изолированные профили браузеров (Browser Contexts) за миллисекунды, позволяя симулировать многопользовательские сценарии без запуска новых окон самого браузера, а также умеет записывать действия пользователя в браузере и автоматически превращать их в готовый код теста. Записывает видео, скриншоты и сетевые логи во время выполнения теста, что упрощает отладку при сбоях в CI/CD.

Selenium — классика с долгой историей. Playwright (Microsoft) чаще выбирают для новых веб-проектов — стабильные ожидания, три движка браузера, встроенные скриншоты и trace. Здесь — путь от нуля до прогона в CI, плюс архитектура (Page Object, pytest, Allure, SPA/React) и ориентиры для портфолио и собеседований.


Что такое E2E-автоматизация

E2E (end-to-end) — тест проходит весь путь пользователя в реальном браузере: открыть сайт → войти → оформить заказ → увидеть подтверждение.

Единый формат практики в статье:

  • когда выбирать Playwright для команды;
  • минимальный рабочий сценарий и CI-профиль;
  • антифлейк-чеклист для стабильного регресса.

Практический ориентир: E2E-тесты закрывают критичные сквозные риски, а основную массу логики выгоднее закрывать на unit и integration/API. Тогда регресс остаётся быстрым и стабильным.

Мини-маршрут внедрения в команде:

  1. Выбрать 3-10 P0-сценариев.
  2. Зафиксировать данные и критерии в документации.
  3. Автоматизировать сценарии в Playwright и включить их в CI.
  4. Еженедельно анализировать flaky-падения и чистить технический долг.
УровеньЧто проверяетИнструмент (примеры)
UnitОдна функция/классpytest, JUnit
APIHTTP без UIPostman, REST-клиент в коде
E2EUI + браузер + сетьPlaywright, Selenium

E2E медленнее и хрупче (ломается при смене вёрстки), зато ловит ошибки интеграции, которые unit не видит. Обычно их меньше, чем unit, но на критичных сценариях (оплата, регистрация) они обязательны.

Ручная проверка того же сценария — Ручное тестирование веба. Общая теория автоматизации — Автоматизация тестирования.


Selenium или Playwright?

Выбирайте Playwright для новых проектов и веб-приложений, а Selenium — для поддержки масштабной legacy-инфраструктуры или специфического тестирования на редких браузерах и реальных мобильных устройствах. Playwright стал индустриальным стандартом для современной UI-автоматизации благодаря своей скорости, стабильности и богатой функциональности «из коробки». Selenium сохраняет огромную долю рынка за счет колоссального количества уже написанных корпоративных тестов.

Сравнение
SeleniumPlaywright
Возраст экосистемыОчень зрелая, много legacyМоложе, активно растёт
Ожидания элементовЧасто пишут вручнуюAuto-wait по умолчанию
БраузерыЧерез отдельные драйверыChromium, Firefox, WebKit из коробки
ОтладкаЛоги + скрины самиTrace Viewer, video, screenshot on fail
Когда братьEnterprise, старый стек, Appium-опытНовый фронт, React/Vue, CI на GitHub Actions

Обе технологии валидны. Для обучения начните с Playwright на зелёном проекте; Selenium — если команда уже на нём сидит.

Главные преимущества Playwright:

  • Никаких sleep() и явных ожиданий. Playwright автоматически ждет, пока элемент станет видимым, доступным для клика и анимирование завершится. Это убирает 90% случайных падений тестов.
  • Встроенные инструменты. Инструмент Trace Viewer позволяет поминутно разобрать упавший тест, посмотреть сетевые запросы, консоль и состояние DOM в момент ошибки. Также есть генератор тестов (Codegen), записывающий действия пользователя.
  • Изоляция и скорость. Тесты запускаются в изолированных браузерных контекстах за миллисекунды, что позволяет легко параллелить тысячи сценариев.
  • Работа с API и перехватом сети. Можно легко подменять (мокать) ответы бэкенда прямо в тесте.

Когда всё же стоит выбрать Selenium?

  • Существующий проект. Если в компании уже написаны тысячи тестов на Selenium, миграция может быть слишком дорогой.
  • Реальные мобильные устройства. Playwright лишь эмулирует мобильные экраны и геопозицию. Для полноценного тестирования на реальных смартфонах Android/iOS связка Selenium + Appium остается незаменимой.
  • Редкие конфигурации браузеров. Selenium поддерживает практически любые версии браузеров (включая старые), тогда как Playwright поставляет фиксированные сборки Chromium, Firefox и WebKit.

Миграция с Selenium на Playwright

Если команда уже сидит на Selenium, переход обычно делают поэтапно:

  1. Оставляют стабильный legacy-регресс на Selenium.
  2. Новые E2E-сценарии пишут сразу на Playwright.
  3. Постепенно переносят самые flaky и дорогие в поддержке сценарии.
  4. После стабилизации CI сокращают Selenium-набор до необходимого минимума.

Такой путь снижает риск "сломать всё сразу" и позволяет измерить выгоду на практике — время прогона, стабильность, скорость разбора падений.

Что переносить первым

Начинайте с smoke P0 — логин, ключевой бизнес-поток, подтверждение результата. Именно эти сценарии быстрее всего показывают выигрыш от auto-wait и trace в Playwright.


Словарь

ТерминЗначение
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

--uiUI 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, локально прошёл. Частая причина — элемент ещё не появился или изменился селектор.

Приоритет локаторов (от устойчивых к хрупким):

ПриоритетЛокаторПример
1getByRolepage.getByRole('button', { name: 'Войти' })
2getByLabelpage.getByLabel('Email')
3getByTestIdpage.getByTestId('checkout-submit')
4getByTextосторожно при смене языка
5CSS/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();

Продвинутые локаторы — CSS и XPath

Когда getByRole / getByTestId недоступны, Playwright поддерживает CSS и XPath через page.locator(...). Используйте их осознанно: они чаще ломаются при рефакторинге вёрстки.

ПодходПримерКогда уместен
CSS по атрибутуpage.locator('[data-testid="cart-badge"]')Стабильный data-testid от команды фронта
CSS по структуреpage.locator('form.checkout >> button[type=submit]')Вложенные блоки без роли ARIA
XPath по текстуpage.locator('xpath=//button[contains(., "Оплатить")]')Legacy-страницы без testid
Фильтр Playwrightpage.locator('.row').filter({ hasText: 'Итого' })Уточнение среди похожих элементов
Цепочкаpage.locator('#sidebar').getByRole('link', { name: 'Заказы' })Сначала контейнер, потом устойчивый локатор
const row = page.locator('tr.order-row').filter({ hasText: 'Оплачен' });
await expect(row.getByRole('cell', { name: 'Статус' })).toHaveText('Оплачен');
Антипаттерн

XPath вида /html/body/div[3]/div[1]/button привязан к дереву DOM и почти гарантированно даст flaky-тесты. Лучше договориться с разработчиками о data-testid на P0-элементах.


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 в одном сценарии.


SPA и React — что учитывать в E2E

SPA (Single Page Application) — маршрут меняется без полной перезагрузки страницы. React, Vue и Angular рендерят UI через виртуальный DOM; элементы появляются асинхронно после запросов к API.

Особенность SPAРиск для тестаПриём в Playwright
Клиентский роутингgoto прошёл, контент ещё пустойawait expect(locator).toBeVisible() вместо фиксированной паузы
Скелетоны и спиннерыКлик по "невидимой" кнопкеЖдать исчезновения loader или появления целевого блока
Модальные окна и порталыЭлемент вне основного DOMЛокатор внутри page.getByRole('dialog')
Состояние в памятиТесты зависят от порядкаИзолировать данные, уникальные email, API seed
Hydration (SSR)Расхождение серверного и клиентского HTMLПервое действие — дождаться стабильного UI
await page.goto('/orders');
await expect(page.getByRole('heading', { name: 'Мои заказы' })).toBeVisible();
await page.getByRole('button', { name: 'Создать' }).click();
await expect(page.getByTestId('order-form')).toBeVisible();

Для React-команд договоритесь о data-testid на формах оплаты, корзине и авторизации. Сетевые заглушки (page.route) помогают стабилизировать сценарии без реального платёжного шлюза — тот же приём описан в кейсе автоматизации.

Подробнее про уровень E2E и паттерны UI — End-to-End и системное тестирование.


Авторизация без повторного логина

Долгий логин в каждом тесте замедляет прогон. Паттерн 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' для проектов, которым нужна сессия. Один раз залогинились — остальные тесты стартуют уже авторизованными.


Архитектура UI-автотестов и паттерны проектирования

Когда сценариев больше пяти, плоские spec-файлы превращаются в "спагетти" из селекторов. Три рабочих уровня абстракции — Page Object, Page Component и фабрика страниц (Page Factory). Общая теория POM и Screenplay — в End-to-End и системное тестирование, структура репозитория в кейсе — Автоматизация тестирования.

Page Object Model

Класс страницы инкапсулирует локаторы и действия. Тест описывает бизнес-шаги, страница — как кликнуть.

Код ITЗагрузка примера кода…

В тесте: const login = new LoginPage(page); await login.login(...). Селектор кнопки изменился — правка в одном файле.

Page Component

Повторяющиеся блоки UI (шапка, сайдбар, модалка, таблица) выносят в компонент, который принимают несколько страниц.

Код ITЗагрузка примера кода…

Так избегают копирования локаторов шапки в LoginPage, CatalogPage и CheckoutPage.

Page Factory — фабрика страниц

Page Factory — слой, который создаёт готовые Page Object’ы с уже переданным page (или browser context). Тесты остаются короткими, зависимости собираются в одном месте.

Код ITЗагрузка примера кода…

В Python + pytest ту же роль часто играют фикстуры, возвращающие страницы (см. раздел про pytest ниже).

Масштабируемая структура проекта

Типовая раскладка для команды SDET (TypeScript или Python):

ui-automation/
├── config/ # окружения, таймауты (Pydantic / .env)
├── pages/ # Page Object по экранам
├── components/ # переиспользуемые блоки UI
├── tests/ # spec — только сценарии
├── fixtures/ # данные, auth state, API helpers
├── reports/ # allure-results (в .gitignore)
├── playwright.config.ts # или conftest.py для Python
├── .github/workflows/ # CI
└── README.md # как запустить, ссылка на отчёт
СлойОтветственность
tests/Сценарий "логин → заказ → проверка"
pages/, components/Локаторы и действия
fixtures/Пользователи, тестовые заказы, моки API
config/URL стенда, секреты из переменных окружения

playwright.config.ts — что трогать чаще всего

Код ITЗагрузка примера кода…

ОпцияСмысл
baseURLКороткие goto('/catalog') вместо полного URL
timeoutМаксимум на один тест
traceЗапись шагов при падении / ретрае
projectsПрогон в нескольких браузерах

Минимальный CI-профиль команды

Для большинства проектов удобно разделить прогоны на три слоя:

  • PR: только smoke-набор (быстрый фидбек до merge);
  • nightly: полный регресс во всех целевых браузерах;
  • pre-release: smoke + критичный регресс + обязательная публикация артефактов.

Пример практичного профиля:

  • trace: "on-first-retry" для экономии места;
  • video: "retain-on-failure" для разборов падений;
  • retries: 1 в CI как временная страховка, но с обязательным разбором причин флейков.

Видео, скриншоты и Trace Viewer

В playwright.config.ts артефакты настраиваются в блоке use:

ОпцияЗначенияЗачем
screenshotonly-on-failure, on, offСнимок экрана в момент падения
videoretain-on-failure, on, offВидео прогона для разбора таймингов
traceon-first-retry, on, retain-on-failureПошаговая запись для Trace Viewer
use: {
screenshot: 'only-on-failure',
video: 'retain-on-failure',
trace: 'on-first-retry',
},

После падения в CI скачайте артефакты workflow и откройте trace:

npx playwright show-trace test-results/.../trace.zip

Trace Viewer показывает timeline действий, DOM на каждом шаге, сетевые запросы и консоль браузера. Это основной инструмент разбора "упало только на CI".

Дополнительно:

npx playwright test --debug
npx playwright codegen https://test.shop.example

codegen записывает действия в код — стартовая заготовка, затем рефакторинг на устойчивые локаторы.


Pytest и экосистема (Python + Playwright)

Многие команды QA пишут E2E на Python: тот же Playwright, но раннер pytest. Базовый unit-практикум — Подготовка среды и создание первого теста; каталог плагинов — Инструменты для ручного и автоматизированного тестирования.

Установка

pip install pytest pytest-playwright allure-pytest pytest-xdist
playwright install

Фикстуры и "фабрика" страниц

conftest.py — центр pytest — браузер, контекст, авторизация, Page Object’ы.


import pytest

from playwright.sync_api import Page
from pages.login_page import LoginPage

@pytest.fixture
def login_page(page: Page) -> LoginPage:
return LoginPage(page)

@pytest.fixture(scope="session")
def base_url() -> str:
return "https://test.shop.example"

В тесте: def test_login(login_page): login_page.login(...).

Параметризация и маркеры


import pytest

@pytest.mark.smoke
@pytest.mark.parametrize("browser_name", ["chromium", "firefox"])
def test_home_title(page, browser_name):
...
Маркер / механизмНазначение
@pytest.mark.smokeБыстрый набор на PR
@pytest.mark.regressionПолный регресс nightly
@pytest.mark.parametrizeОдин тест — несколько входных данных
pytest -m smokeЗапуск только помеченных тестов

Зарегистрируйте маркеры в pyproject.toml или pytest.ini, чтобы CI и IDE не ругались на неизвестные имена.

Плагины и параллельный запуск

ПакетЗадача
pytest-playwrightФикстуры page, browser, конфиг из CLI
pytest-xdistПараллель на нескольких ядрах: pytest -n auto
allure-pytestШаги и вложения в Allure
pytest-rerunfailuresВременный ретрай flaky (с обязательным разбором)

Параллель ускоряет регресс, но требует изолированных тестовых данных — два воркера не должны бронировать один и тот же email.

Моки и оптимизация

  • Сеть: page.route("**/api/orders", lambda route: route.fulfill(...)) — стабильный ответ без реального бэкенда.
  • API setup: создать пользователя через REST до UI, затем только проверить экран — меньше шагов в браузере.
  • storageState: один раз залогиниться в setup-фикстуре, переиспользовать cookie в тестах.
  • Моки Python: unittest.mock / pytest-mock для unit-слоя; в E2E чаще мокируют HTTP, а не DOM.

Подробнее про моки в unit — Подготовка среды и создание первого теста, про дублёры — Объекты и уровни тестирования.


Отчётность и инфраструктура

Allure Report и Allure TestOps

Allure Report собирает HTML-отчёт из результатов прогона — шаги, вложения (скрин, trace), история падений.

pytest --alluredir=allure-results
allure serve allure-results

В Playwright (TypeScript) подключают репортер @playwright/test + allure-playwright или выгружают артефакты pytest в CI.

Allure TestOps — корпоративная платформа поверх тех же результатов — дашборды, связь с Jira, анализ стабильности, ручные + автотесты в одном месте. Для учебного проекта достаточно локального allure serve; в компании TestOps подключают через upload API после CI.

Слой отчётности в архитектуре автоматизации — Автоматизация тестирования.

CI/CD и публикация отчётов

Типовый pipeline (GitHub Actions, GitLab CI, Jenkins):

  1. Установка зависимостей и браузеров (playwright install --with-deps).
  2. Прогон smoke на PR, полный регресс на main / nightly.
  3. Загрузка playwright-report/, allure-results/, trace и video при падении.
  4. Публикация Allure на GitHub Pages или внутренний nginx.

Общий вводный материал — DevOps и CI/CD. Пример workflow с Playwright — в разделе ниже.

Конфигурация через Pydantic и переменные окружения

Секреты и URL стендов не хранят в репозитории. Модуль настроек читает .env и переменные CI:

from pydantic_settings import BaseSettings, SettingsConfigDict

class Settings(BaseSettings):
model_config = SettingsConfigDict(env_file=".env", extra="ignore")

base_url: str = "http://localhost:3000"
qa_user_email: str
qa_user_password: str
headless: bool = True

settings = Settings()

В conftest.py: page.goto(settings.base_url). В GitHub Actions — secrets QA_USER_PASSWORD, в локальной разработке — .env в .gitignore. Подробнее про Pydantic — Pydantic — валидация входящих данных.


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 на полный DOMgetByRole / getByTestId
Один огромный тест на 200 строкtest.describe + Page Object
Тесты зависят от порядкаИзолировать данные, уникальный email
Гоняют только локально headless=falseПериодически прогон как в CI

Антифлейк-чеклист для команды

  • используйте только устойчивые локаторы: role/label/testid;
  • не храните хрупкое состояние между тестами, данные должны быть изолированы;
  • избегайте sleep, опирайтесь на expect и события;
  • фиксируйте окружение — версия браузера, node, зависимости;
  • любое нестабильное падение разбирайте через trace в тот же спринт;
  • держите короткий "карантинный список" flaky-тестов и срок их исправления.

Практика и карьера

Автотесты на Playwright — сильный аргумент в резюме junior/middle QA (автоматизатор, SDET). Ниже — что оформить в портфолио и как готовиться к собеседованию.

Git и GitHub для тестового репозитория

ШагДействие
РепозиторийПубличный qa-playwright-demo с README на русском или английском
Веткиfeature/QA-1-login-e2e → Pull Request, как в продуктовой команде
CIBadge в README: статус workflow GitHub Actions
СекретыПароли только в Secrets, пример — .env.example без значений

Минимум команд и review-процесс — Дополнительные модули для тестировщика и раздел Git.

Оформление проекта в портфолио

В README укажите:

  • Стек — Playwright, pytest или TypeScript, Allure, GitHub Actions.
  • Что проверяете — 3–5 P0-сценариев (логин, корзина, оплата с моком API).
  • Как запустить: git clone, pip install -r requirements.txt, playwright install, pytest.
  • Отчёт: скрин Allure или ссылка на опубликованный Pages.
  • Архитектура — схема папок pages/, tests/, conftest.py.

Ревьюер на собеседовании смотрит на читаемость тестов и устойчивые локаторы, а не на количество файлов.

Резюме и собеседование

Тема на интервьюЧто подготовить
Пирамида тестированияГде у вас unit, API, E2E; почему E2E мало
ЛокаторыПочему getByRole / data-testid лучше XPath
FlakyПример, как нашли через trace и исправили
CIКак падение блокирует merge, куда смотрят артефакты
Page ObjectЗачем выносили страницу в класс, пример рефакторинга
PytestФикстуры, маркеры smoke/regression, параллель -n

Рассказ о проекте на 2–3 минуты: продукт → ваша роль → стек → один конкретный баг, пойманный автотестом. Карьера и soft skills — Карьера в IT, бонус-модули — Дополнительные модули для тестировщика. Вопросы для самопроверки — Тестирование программного обеспечения — чек-лист.


Практика в этом разделе

ШагМатериал
Ручная проверка UIРучное тестирование веба
Практикум E2E (Selenium)Проверка пользовательского сценария — пользовательский сценарий
Практикум JSПрактикум JavaScript — Playwright и Jest — Playwright и Jest
Практикум Python1011 pytest → эта статья (E2E)
Git, резюме, собеседованиеДополнительные модули для тестировщика
Каталог инструментовИнструменты для ручного и автоматизированного тестирования — UI и E2E
Данные после сценарияSQL для тестировщика

Куда дальше


Навигация по разделу "Тестирование"


Содержание