Promise и их использование

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

Основы Promise

Promise может находиться в одном из трёх состояний:

  1. Pending (Ожидание) — начальное состояние Promise. Асинхронная операция ещё не завершена.
  2. Resolved (Исполнено) — операция завершена успешно, Promise возвращает результат.
  3. Rejected (Отклонено) — операция завершена с ошибкой, Promise возвращает причину ошибки.

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

Применение Promise в WebdriverIO

В WebdriverIO использование Promise предоставляет несколько преимуществ:

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

Пример использования Promise в WebdriverIO:

const button = await $('#submitButton');
await button.click();

Здесь $('#submitButton') — это метод, который возвращает Promise, и он асинхронно находит элемент на странице. Ожидание через await гарантирует, что тест не продолжится, пока элемент не будет найден.

Асинхронные методы WebdriverIO

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

Пример работы с асинхронными методами:

const inputField = await $('#inputField');
await inputField.setValue('Test value');

В данном примере setValue выполняется асинхронно, и тест будет ожидать завершения операции, прежде чем продолжить выполнение.

Обработка ошибок в Promise

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

Пример обработки ошибок:

try {
  const element = await $('#nonExistentElement');
  await element.click();
} catch (error) {
  console.error('Ошибка при взаимодействии с элементом:', error);
}

В этом примере, если элемент не будет найден, ошибка будет поймана и выведена в консоль.

Ожидания и Promise

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

Пример явного ожидания:

await browser.waitUntil(async () => {
  return (await $('#element')).isDisplayed();
}, {
  timeout: 5000,
  timeoutMsg: 'Элемент не появился на странице за 5 секунд'
});

Метод waitUntil возвращает Promise и будет ожидать выполнения указанной функции, пока она не вернёт true. Если за указанное время элемент не станет видимым, будет выброшена ошибка с указанным сообщением.

Promise.all и Promise.race

Иногда возникает необходимость выполнить несколько асинхронных операций одновременно. Для этого можно использовать Promise.all или Promise.race.

  • Promise.all: используется для выполнения нескольких операций параллельно и ожидания их завершения. Возвращает Promise, который разрешается, когда все переданные Promises будут исполнены.

Пример:

const [button, inputField] = await Promise.all([
  $('#submitButton'),
  $('#inputField')
]);

await button.click();
await inputField.setValue('Test value');

В этом примере два элемента на странице обрабатываются параллельно, что сокращает время выполнения теста.

  • Promise.race: возвращает Promise, который завершится, как только завершится первый из переданных Promises.

Пример:

const result = await Promise.race([
  browser.waitUntil(() => $('#element').isDisplayed(), { timeout: 5000 }),
  browser.waitUntil(() => $('#anotherElement').isDisplayed(), { timeout: 5000 })
]);

console.log(result);

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

Асинхронное выполнение и синхронность

Важно помнить, что WebdriverIO работает асинхронно, и ожидания или действия выполняются в фоновом режиме. Однако часто возникает необходимость взаимодействовать с синхронным кодом или ожидать нескольких асинхронных операций подряд. Использование async/await позволяет упрощать такую работу, делая код более читаемым.

Пример выполнения нескольких шагов синхронно:

const button = await $('#submitButton');
await button.click();

const result = await $('#result');
const text = await result.getText();

console.log(text);

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

Заключение

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