Работа с таймерами

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

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

Статические задержки

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

it('Ожидание 2 секунды перед проверкой', () => {
    browser.pause(2000);  // Задержка на 2000 миллисекунд
    const element = $('#element');
    expect(element.isDisplayed()).toBe(true);
});

Метод browser.pause() принимает один параметр — время задержки в миллисекундах. Важно понимать, что использование таких статичных ожиданий не всегда оптимально, так как тесты могут работать медленно или зависеть от условий выполнения. Поэтому, если возможно, стоит использовать более гибкие методы ожидания.

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

Если задача заключается в том, чтобы дождаться появления элемента на странице после выполнения какого-либо действия, можно использовать метод waitForExist(). Этот метод позволяет задать максимально возможное время ожидания, в течение которого WebdriverIO будет проверять наличие элемента в DOM. Если элемент не появляется за указанное время, тест будет завершён с ошибкой.

it('Ожидание появления элемента', () => {
    const element = $('#element');
    element.waitForExist({ timeout: 5000 });  // Максимальное время ожидания - 5 секунд
    expect(element.isDisplayed()).toBe(true);
});

Метод waitForExist() имеет параметр timeout, который указывает, сколько времени WebdriverIO будет проверять наличие элемента в DOM. Если элемент появляется до истечения времени ожидания, тест продолжится, а если нет — тест завершится с ошибкой.

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

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

it('Ожидание появления и видимости элемента', () => {
    const element = $('#element');
    element.waitForDisplayed({ timeout: 3000 });  // Элемент должен стать видимым в течение 3 секунд
    expect(element.isDisplayed()).toBe(true);
});

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

В некоторых случаях необходимо дождаться исчезновения элемента с страницы. Это можно сделать с помощью метода waitForExist() с параметром { reverse: true }. Этот метод позволяет удостовериться, что элемент больше не существует в DOM, что бывает полезно для тестирования процессов удаления или скрытия элементов.

it('Ожидание исчезновения элемента', () => {
    const element = $('#element');
    element.waitForExist({ timeout: 5000, reverse: true });
    expect(element.isDisplayed()).toBe(false);
});

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

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

it('Ожидание кликабельности кнопки', () => {
    const button = $('#submit-button');
    button.waitForClickable({ timeout: 4000 });  // Ждём, пока кнопка станет кликабельной
    button.click();
});

Работа с асинхронными событиями

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

Одним из вариантов решения может быть комбинированное использование waitUntil(), который позволяет задать пользовательское условие и ожидать его выполнения. Например, можно ожидать, пока на странице не появится определённое количество элементов.

it('Ожидание загрузки данных', () => {
    const list = $$('#items-list .item');
    browser.waitUntil(() => list.length > 0, {
        timeout: 5000,
        timeoutMsg: 'Элементы не появились на странице за 5 секунд'
    });
    expect(list.length).toBeGreaterThan(0);
});

Метод waitUntil() принимает два параметра:

  1. Условие (функция), которое должно быть выполнено для продолжения выполнения теста.
  2. Опции, где можно указать время ожидания (timeout) и сообщение, которое будет выведено в случае неудачи (timeoutMsg).

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

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

Пример настройки времени ожидания для всех элементов:

browser.setTimeout({
    'pageLoad': 10000,  // Тайм-аут загрузки страницы
    'script': 5000,     // Тайм-аут выполнения скрипта
    'implicit': 3000    // Тайм-аут для implicit wait
});

Кроме этого, можно настроить тайм-ауты непосредственно в методах, которые поддерживают такую опцию.

const element = $('#element');
element.waitForExist({ timeout: 10000 });  // Тайм-аут для поиска элемента

Заключение

Правильное использование времени ожидания в WebdriverIO — ключ к стабильным и надёжным тестам. Использование методов, таких как waitForExist(), waitForDisplayed(), waitForClickable() и других, позволяет тестам адаптироваться к динамичным веб-приложениям, минимизируя зависимость от производительности системы и сети. Важно правильно настроить тайм-ауты и учитывать особенности асинхронных операций, чтобы обеспечить точность тестирования без лишних задержек.