Избежание hard-coded задержек

Тестирование с использованием WebdriverIO подразумевает взаимодействие с браузером, что всегда связано с определенной непредсказуемостью в скорости выполнения действий. Чтобы избежать нестабильности тестов, часто используются задержки. Однако наличие hard-coded задержек (жестко заданных временных пауз) может привести к значительным проблемам, таким как:

  • Низкая производительность — каждый лишний вызов задержки увеличивает время выполнения тестов.
  • Нестабильность — тесты могут пройти неудачно, если время задержки не соответствует фактическому времени загрузки элемента.
  • Сложности в поддержке — изменения в скорости работы приложения могут потребовать обновления всех временных задержек.

Вместо этого рекомендуется применять более гибкие подходы для ожидания элементов и состояний на странице.

Разница между жесткими задержками и динамическими ожиданиями

Hard-coded задержки представляют собой фиксированное время ожидания, которое устанавливается в тестах вручную. Например, использование метода browser.pause() для установки паузы в 2 секунды:

browser.pause(2000);

Этот подход не учитывает времени, необходимого для реальной загрузки элемента или изменения состояния страницы. Время задержки устанавливается “наугад”, что может быть неэффективно. К тому же, если приложение будет работать быстрее, тесты могут стать излишне медленными, а если медленнее — они могут быть ненадежными.

Динамические ожидания гораздо более точны. Вместо ожидания заранее заданного времени, они подразумевают ожидание, пока не выполнится нужное условие (например, пока элемент не станет видимым или не получит нужное состояние).

Использование ожиданий в WebdriverIO

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

1. Ожидание видимости элемента

Одним из самых популярных способов является ожидание, когда элемент становится видимым на странице. Для этого можно использовать метод waitForDisplayed(), который позволяет подождать, пока элемент не появится на странице или не станет доступен для взаимодействия:

const button = $('#submitButton');
button.waitForDisplayed({ timeout: 5000 }); // Подождать 5 секунд, пока элемент не станет видимым

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

2. Ожидание наличия элемента на странице

Для проверки, что элемент присутствует на странице, используется метод waitForExist(). Этот метод позволяет подождать, пока элемент не появится в DOM-дереве:

const menu = $('#mainMenu');
menu.waitForExist({ timeout: 3000 }); // Ожидание появления элемента в DOM

Этот метод будет полезен, если элемент должен быть загружен, но не обязательно видим.

3. Ожидание кликабельности

Когда необходимо дождаться, пока элемент станет доступен для взаимодействия (например, кнопка или ссылка), можно использовать метод waitForClickable():

const loginButton = $('#loginButton');
loginButton.waitForClickable({ timeout: 4000 });

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

Тайм-ауты и настройки ожиданий

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

В файле конфигурации можно настроить глобальный тайм-аут для всех методов ожидания:

exports.config = {
  waitforTimeout: 10000, // Ожидание по умолчанию для всех элементов
};

Этот параметр можно адаптировать под специфику тестируемого приложения. Если приложение быстро реагирует на действия, можно установить меньший тайм-аут, чтобы ускорить тесты. В случае медленных приложений можно увеличить время ожидания, чтобы избежать ложных сбоев.

Использование ожиданий с элементами в списках

Иногда требуется подождать, пока несколько элементов на странице станут видимыми или будут соответствовать определенному состоянию. В таких случаях WebdriverIO поддерживает работу с коллекциями элементов. Например, если нужно дождаться, пока все элементы в списке станут видимыми:

const items = $$('#itemList .item');
items.forEach(item => {
  item.waitForDisplayed({ timeout: 3000 });
});

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

Ожидание состояния элемента

Методы waitForEnabled(), waitForSelected() и другие дают возможность проверять не только видимость элемента, но и его состояние. Например, если нужно дождаться, пока поле ввода станет активным для взаимодействия:

const inputField = $('#username');
inputField.waitForEnabled({ timeout: 4000 });

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

Использование ожиданий для асинхронных действий

В случае, если тест зависит от асинхронных процессов (например, AJAX-запросов или анимаций), можно использовать методы waitUntil(), которые дают возможность ожидать выполнения какого-либо условия.

Пример использования waitUntil для проверки изменения текста элемента после выполнения запроса:

const statusText = $('#status');
browser.waitUntil(() => {
  return statusText.getText() === 'Загрузка завершена';
}, {
  timeout: 10000,
  timeoutMsg: 'Статус не обновился в течение 10 секунд'
});

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

Преимущества динамических ожиданий

  • Точность — тесты будут зависеть от реального состояния элементов на странице, а не от заранее заданного времени.
  • Производительность — отсутствие лишних пауз сокращает время выполнения тестов.
  • Надежность — тесты не будут зависеть от скорости загрузки или изменения состояния страницы.
  • Поддерживаемость — код становится проще поддерживать, так как не нужно изменять время задержек в разных местах.

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