⚙️ Что это
E2E Testing Patterns — это сборник готовых шаблонов и практик для написания сквозных (end-to-end) тестов на Playwright. Набор включает в себя рекомендации по структуре проекта, реализации Page Object Model (POM), настройке CI/CD, управлению артефактами (скриншоты, видео, трассировки), а также стратегии борьбы с «плавающими» (flaky) тестами.
Навык ориентирован на Frontend- и QA-инженеров, которые хотят создавать стабильные, быстрые и легко поддерживаемые E2E-тесты. Он даёт готовую архитектуру, которую можно сразу адаптировать под свой проект.
🧠 Как работает
🏗️ Структура тестового набора
Файлы организованы по функциональным модулям, отдельно выделены фикстуры (fixtures) и конфигурация playwright.config.ts:
tests/
├── e2e/
│ ├── auth/ // тесты авторизации
│ ├── features/ // тесты функций
│ └── api/ // тесты API
├── fixtures/ // общие данные и setup
└── playwright.config.ts
🧩 Page Object Model (POM)
Для каждого экрана создаётся отдельный класс (Page Object), который инкапсулирует:
- Селекторы элементов — всегда через
data-testid (это надёжнее, чем CSS-классы).
- Методы взаимодействия — например,
search(query), goto().
- Ожидания — явное ожидание ответа от API (
waitForResponse) и полной загрузки страницы (waitForLoadState).
Пример: класс ItemsPage хранит searchInput, itemCards, createButton, а метод search заполняет поле и ждёт, пока придёт ответ от /api/search.
🧪 Структура теста
Каждый тест использует describe / it (или test.describe / test), в beforeEach создаётся Page Object и переход на нужную страницу:
test.describe('Item Search', () => {
let itemsPage: ItemsPage;
test.beforeEach(async ({ page }) => {
itemsPage = new ItemsPage(page);
await itemsPage.goto();
});
test('should search by keyword', async ({ page }) => {
await itemsPage.search('test');
await expect(itemsPage.itemCards.first()).toContainText(/test/i);
await page.screenshot({ path: 'artifacts/search-results.png' });
});
});
Тесты проверяют как позитивные сценарии (результаты есть), так и негативные (нет результатов — проверяется [data-testid="no-results"]).
⚙️ Конфигурация Playwright
В playwright.config.ts настраиваются ключевые параметры:
- Параллельный запуск (
fullyParallel: true) — все тесты в разных файлах идут параллельно.
- Повторы — в CI
retries: 2, локально retries: 0, чтобы только в CI перезапускать упавшие тесты.
- Репортеры — HTML (для локального просмотра), JUnit и JSON (для CI).
- Артефакты — скриншоты (
only-on-failure), видео (retain-on-failure), трассировка (on-first-retry).
- Таймауты —
actionTimeout: 10s, navigationTimeout: 30s.
- Проекты — Chromium, Firefox, WebKit, Mobile Chrome (Pixel 5).
- Web-сервер — автостарт
npm run dev (на CI сервер не переиспользуется).
🔁 Flaky-тесты — причины и лечение
Выявление: запуск теста 10 раз подряд (--repeat-each=10) или с --retries=3.
Карантин: маркировка test.fixme(true, 'Flaky - Issue #123') — тест не выполняется, но остаётся в коде.
Пропуск в CI: test.skip(process.env.CI, 'Flaky in CI') — тест бежит только локально.
Основные причины flaky и исправления:
- Гонки (race conditions) — вместо
page.click() используй locator.click(), который сам ждёт стабильности.
- Сеть — вместо
waitForTimeout жди ответа API (waitForResponse).
- Анимации — сначала дождись видимости элемента, потом
networkidle, потом кликай.
📸 Управление артефактами
- Скриншоты — всей страницы (
fullPage: true) или конкретного элемента (locator.screenshot()).
- Трассировка — запись всех действий (
browser.startTracing).
- Видео — настраивается в
playwright.config.ts как video: 'retain-on-failure'.
Все артефакты сохраняются в директорию artifacts/.
🔄 CI/CD интеграция
GitHub Actions workflow:
- Запуск на
push и pull_request.
- Установка зависимостей (
npm ci), браузеров (npx playwright install --with-deps).
- Запуск тестов с переменной окружения
BASE_URL из секретов.
- Загрузка отчёта в артефакты (
actions/upload-artifact) с хранением 30 дней.
Шаблон отчёта включает: дату, длительность, статус, список упавших тестов со скриншотами и рекомендованными исправлениями.
🦊 Web3 / Wallet тестирование
Для тестов, где нужен кошелёк (MetaMask), используется мок через context.addInitScript. Подменяется глобальный window.ethereum с методами eth_requestAccounts и eth_chainId. Это позволяет тестировать подключение кошелька без реального провайдера.
💰 Финансовые / критичные потоки
Пример — тест на исполнение сделки:
- Пропуск на продакшене (
test.skip(process.env.NODE_ENV === 'production')).
- Заполнение суммы, проверка превью, подтверждение, ожидание ответа от
/api/trade.
- Проверка элемента успеха
[data-testid="trade-success"].
✅ Когда использовать
- Когда проект на Playwright требует чёткой архитектуры тестов.
- Чтобы внедрить Page Object Model в существующий набор или начать новый без боли.
- Для настройки CI/CD с артефактами и отчётами.
- Если flaky-тесты отнимают время — применить стратегии карантина, пропуска и перезапуска.
- Для тестирования Web3 / финансовых сценариев с моками.
🔐 Важно знать
- Все селекторы основаны на
data-testid — убедись, что вёрстка содержит эти атрибуты.
- В финансовых тестах добавлена защита от случайного запуска на продакшене — стоит внедрить аналогичный
skip.
- Мок для Web3 актуален только для MetaMask-подобных провайдеров; для других кошельков нужна адаптация.
- Видео и трассировка заметно замедляют прогон в CI; в конфиге они включены только на перезапуск упавших тестов (
retain-on-failure, on-first-retry).
Комментарии
Комментариев пока нет. Будьте первым.