Таймауты и их управление

Эффективное управление таймаутами является ключевым аспектом автоматизации тестирования в WebdriverIO. Таймауты определяют, сколько времени тест должен ждать определённого события или состояния страницы перед тем, как завершить выполнение с ошибкой. Неправильная настройка таймаутов может привести к нестабильным тестам, ложным срабатываниям и увеличению времени выполнения тестового набора.

Виды таймаутов

WebdriverIO предоставляет несколько основных видов таймаутов, которые регулируют различные этапы взаимодействия с веб-приложением:

  1. Implicit Timeout Используется для автоматического ожидания элементов на странице при поиске. Если элемент не найден сразу, WebdriverIO будет повторно пытаться найти его до истечения заданного времени. Настройка производится через метод setTimeout или конфигурационный параметр implicit:

    browser.setTimeout({ implicit: 5000 }); // 5 секунд

    Особенности:

    • Подходит для элементов, которые могут загружаться с задержкой.
    • Длительное использование может замедлять тесты, если элементы отсутствуют.
  2. Explicit Timeout Позволяет ожидать конкретного состояния элемента, например, видимости или кликабельности, с помощью команд waitUntil, waitForDisplayed, waitForEnabled. Пример:

    const button = await $('#submit');
    await button.waitForDisplayed({ timeout: 7000, timeoutMsg: 'Кнопка не появилась' });

    Особенности:

    • Более точный контроль, чем implicit.
    • Можно задать кастомное сообщение об ошибке при превышении времени.
  3. Page Load Timeout Определяет, сколько времени WebdriverIO будет ждать полной загрузки страницы при переходе с помощью url() или navigateTo().

    browser.setTimeout({ pageLoad: 10000 }); // 10 секунд

    Особенности:

    • Влияет на команды перехода по URL.
    • Не влияет на поиск элементов после загрузки страницы.
  4. Script Timeout Определяет максимальное время выполнения асинхронного скрипта через executeAsync.

    browser.setTimeout({ script: 5000 }); // 5 секунд

    Особенности:

    • Предотвращает зависание при выполнении сложных JS-операций на странице.
    • Полезен для тестов, которые используют кастомные скрипты.

Управление таймаутами в конфигурации

WebdriverIO позволяет задавать таймауты глобально в файле конфигурации wdio.conf.js. Это обеспечивает единообразие и упрощает поддержку тестового набора:

exports.config = {
    waitforTimeout: 10000, // дефолтное время для waitFor* команд
    connectionRetryTimeout: 120000, // таймаут подключения к WebDriver
    connectionRetryCount: 3, // количество повторных попыток
    capabilities: [{
        browserName: 'chrome',
    }],
};
  • waitforTimeout используется как значение по умолчанию для всех waitFor* команд, если не указан отдельный таймаут.
  • connectionRetryTimeout и connectionRetryCount позволяют контролировать повторные подключения к браузеру или удаленному WebDriver серверу, что особенно важно в CI/CD средах.

Использование waitUntil для кастомных условий

waitUntil предоставляет гибкий механизм ожидания произвольных условий. Команда принимает функцию, которая должна вернуть true, когда условие выполнено:

await browser.waitUntil(
    async () => (await $('#status').getText()) === 'Готово',
    {
        timeout: 15000,
        timeoutMsg: 'Статус не стал "Готово" за 15 секунд'
    }
);

Особенности:

  • Позволяет контролировать любые условия на странице.
  • Можно задавать интервал повторных проверок через параметр interval.

Практические рекомендации

  • Использовать implicit timeout только как резервный вариант. Основные ожидания лучше реализовывать через explicit таймауты и waitUntil.
  • Для динамически загружаемых элементов применять waitForDisplayed или waitForEnabled с разумным таймаутом.
  • Всегда указывать timeoutMsg для упрощения диагностики в случае ошибки.
  • Не задавать слишком большие таймауты, чтобы тесты не зависали длительное время. Баланс между стабильностью и скоростью тестов критичен.
  • Настраивать глобальные таймауты через конфигурацию, а локальные — только для специфических сценариев.

Взаимодействие разных таймаутов

Важно понимать взаимодействие разных таймаутов:

  • Implicit + Explicit: использование implicit может замедлять explicit ожидания, так как implicit автоматически увеличивает время поиска элемента.
  • Page Load + waitFor* команды: page load timeout влияет только на переход по URL, а waitFor* команды — на состояние элементов после загрузки.
  • Script timeout + executeAsync: script timeout ограничивает длительные скрипты, но не влияет на синхронные команды.

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