Типичные проблемы и их решения

Ошибка: элемент не найден (Element not found)

Одной из самых распространённых проблем при автоматизации тестов является невозможность найти элемент на странице. В Playwright это часто проявляется как TimeoutError: waiting for selector "...".

Причины:

  • Элемент ещё не загружен или находится в DOM после асинхронного запроса.
  • Селектор некорректен или слишком общий.
  • Элемент находится внутри iframe.

Решения:

  • Использовать явное ожидание появления элемента:
await page.waitForSelector('#my-element', { state: 'visible', timeout: 5000 });
  • Проверять корректность селекторов через DevTools.
  • Для iframe:
const frame = page.frame({ url: /example.com/ });
await frame.click('button#submit');

Проблема синхронизации (Timing issues)

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

Решения:

  • Использовать встроенные методы ожидания:
await page.locator('button#save').waitFor({ state: 'attached' });
  • Применять page.waitForLoadState() для ожидания полной загрузки страницы:
await page.goto('https://example.com');
await page.waitForLoadState('networkidle');

Ошибки взаимодействия с элементами (Element is not clickable / detached from DOM)

Может возникнуть, если элемент исчезает или перекрыт другим элементом в момент клика.

Решения:

  • Проверка видимости и доступности элемента перед действием:
const button = page.locator('#submit');
await button.waitFor({ state: 'visible' });
await button.click();
  • Использование force: true только в исключительных случаях:
await page.click('#submit', { force: true });

Это обходит проверку видимости, но может скрыть реальные ошибки взаимодействия.

Ошибки авторизации и состояния сессии

Тесты, зависящие от авторизации, могут падать при истечении токена или несогласованности состояния страницы.

Решения:

  • Хранение и восстановление состояния сессии:
await page.context().storageState({ path: 'state.json' });
  • При запуске теста использовать сохранённое состояние:
const context = await browser.newContext({ storageState: 'state.json' });
const page = await context.newPage();
  • Обновление токена перед критическими действиями.

Проблемы с локаторами и динамическими элементами

Селекторы на динамических страницах часто изменяются, что приводит к падению тестов.

Решения:

  • Использовать Locator API вместо прямых селекторов:
const button = page.locator('button', { hasText: 'Отправить' });
await button.click();
  • Применять регулярные выражения для поиска элементов:
await page.locator('text=/Отправ.*?/').click();
  • Предпочтительно использовать data-testid или уникальные атрибуты для стабильности селекторов.

Проблемы с загрузкой ресурсов и асинхронными запросами

Тесты могут завершаться раньше, чем завершатся все AJAX-запросы, что приводит к неполным проверкам.

Решения:

  • Использование waitForResponse для конкретных сетевых запросов:
await page.waitForResponse(response => response.url().includes('/api/data') && response.status() === 200);
  • Комбинация с waitForSelector для элементов, которые появляются после загрузки данных.

Ошибки при работе с всплывающими окнами и диалогами

Диалоги типа alert, confirm или prompt могут блокировать тесты.

Решения:

  • Обработка диалогов с помощью события dialog:
page.on('dialog', dialog => dialog.accept());
  • Для промтов можно передавать значение:
page.on('dialog', dialog => dialog.accept('Текст ответа'));

Проблемы с мультиязычными интерфейсами и локализацией

Тесты могут ломаться при смене языка интерфейса из-за изменения текста или формата дат.

Решения:

  • Определять элементы через атрибуты, а не текст.
  • Создавать универсальные локаторы, чувствительные к структуре DOM, а не к содержимому.
  • Проверки текста вынести в отдельные словари или файлы локализации.

Ошибки при параллельном запуске тестов

Одновременный запуск нескольких тестов может вызвать конфликты состояния, особенно если используется общий контекст браузера.

Решения:

  • Каждый тест запускать в отдельном контексте или даже браузере:
const context = await browser.newContext();
const page = await context.newPage();
  • Избегать глобальных состояний и общих ресурсов между тестами.

Отладка и логирование

Для быстрого нахождения причин падений тестов важно правильно использовать отладку.

Инструменты:

  • page.pause() — приостанавливает выполнение теста и открывает Playwright Inspector.
  • console.log и page.on('console', ...) — отслеживание событий и ошибок в браузере.
  • Скриншоты и видео:
await page.screenshot({ path: 'screenshot.png', fullPage: true });
await context.tracing.start({ screenshots: true, snapshots: true });
// после теста
await context.tracing.stop({ path: 'trace.zip' });

Частые рекомендации для стабильности тестов

  • Всегда использовать Locator API вместо прямых селекторов.
  • Сочетать проверки состояния элемента (visible, enabled, attached) с действиями.
  • Минимизировать использование sleep или фиксированных таймаутов.
  • Изолировать тесты, избегая общих состояний.
  • Логировать критические шаги для быстрого анализа ошибок.

Эти подходы помогают предсказать и решать большинство проблем, с которыми сталкиваются при автоматизации тестирования с Playwright на JavaScript.