Explicit waits: явные ожидания

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

Основы использования ExpectedConditions

Protractor предоставляет объект ExpectedConditions (обычно сокращенно EC), содержащий набор предопределенных условий для ожидания. Он импортируется следующим образом:

const EC = protractor.ExpectedConditions;

Простейший пример использования явного ожидания:

const button = element(by.id('submit'));
browser.wait(EC.elementToBeClickable(button), 5000);
button.click();

В этом примере тест будет ждать до 5 секунд, пока кнопка не станет кликабельной, прежде чем вызвать метод click(). Если условие не выполнится за отведенное время, тест завершится с ошибкой.

Основные методы ExpectedConditions

  1. visibilityOf(element) – ожидает, пока элемент станет видимым на странице.
  2. invisibilityOf(element) – ожидает, пока элемент исчезнет или станет невидимым.
  3. elementToBeClickable(element) – проверяет, что элемент видим и доступен для клика.
  4. presenceOf(element) – ожидает появления элемента в DOM, не обязательно видимого.
  5. textToBePresentInElement(element, text) – ждет появления заданного текста внутри элемента.
  6. urlContains(substring) и urlIs(url) – ожидают изменения URL страницы.
  7. alertIsPresent() – ждет появления всплывающего окна alert.

Каждое условие можно использовать в сочетании с browser.wait(), задавая таймаут ожидания и необязательное сообщение об ошибке.

Примеры сложных ожиданий

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

const items = element.all(by.css('.list-item'));
browser.wait(EC.visibilityOf(items.get(0)), 5000, 'Первый элемент списка не появился');

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

2. Ожидание сочетания условий:

const input = element(by.id('username'));
browser.wait(EC.and(
    EC.visibilityOf(input),
    EC.elementToBeClickable(input)
), 5000);

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

3. Ожидание текста элемента с динамическим содержимым:

const status = element(by.id('status'));
browser.wait(EC.textToBePresentInElement(status, 'Завершено'), 10000);

Такое ожидание особенно полезно для проверки завершения фоновых операций на странице.

Использование таймаутов и сообщений

Метод browser.wait() принимает три аргумента:

browser.wait(condition, timeoutInMs, message);
  • condition – функция условия (например, метод из ExpectedConditions).
  • timeoutInMs – максимальное время ожидания в миллисекундах.
  • message – текст ошибки, выводимый при истечении таймаута.

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

Пользовательские условия ожидания

Помимо встроенных условий, можно создавать собственные. Это делается через функцию, возвращающую Promise<boolean> или boolean:

const customCondition = () => {
    return element(by.id('status')).getText().then(text => text.includes('Готово'));
};

browser.wait(customCondition, 7000, 'Статус не изменился на Готово');

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

Отличие явных ожиданий от неявных

  • Неявные ожидания задаются один раз глобально (browser.manage().timeouts().implicitlyWait(5000)) и применяются ко всем элементам.
  • Явные ожидания позволяют контролировать каждую ситуацию отдельно, делая тест более предсказуемым и стабильным.

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

Рекомендации по применению

  • Выбирать условие максимально близкое к фактической задаче (например, elementToBeClickable, а не просто presenceOf).
  • Указывать информативное сообщение об ошибке, чтобы легче было анализировать падения тестов.
  • Сочетать явные ожидания с проверками состояния страницы и элементами Angular, чтобы минимизировать нестабильность.

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