WebdriverIO работает поверх WebDriver-протокола и сильно зависит от асинхронного выполнения операций. Каждое взаимодействие с браузером, элементами страницы или ожидание состояния требует асинхронного подхода. Основная причина — коммуникация с браузером осуществляется через удалённый сервер (например, Selenium Server или ChromeDriver), и операции могут занимать непредсказуемое время.
В современном WebdriverIO используется синтаксис async/await, который делает асинхронный код более читаемым и последовательным, по сравнению с использованием промисов напрямую.
it('должен открыть страницу и проверить заголовок', async () => {
await browser.url('https://example.com');
const title = await browser.getTitle();
console.log(title);
});
В этом примере метод browser.url выполняется асинхронно
и возвращает промис. Ключевое слово await заставляет
выполнение теста ждать завершения операции перед переходом к следующей
строке.
Все команды WebdriverIO, связанные с браузером и элементами страницы, являются асинхронными. Основные категории:
browser.url(),
browser.back(), browser.forward(),
browser.refresh()$(selector),
$$(), element.click(),
element.setValue()element.waitForDisplayed(),
browser.waitUntil()browser.switchToFrame(),
browser.switchToWindow()browser.saveScreenshot(),
element.takeScreenshot()Каждая из этих команд возвращает промис, и игнорирование
await может привести к непредсказуемому поведению
тестов.
Поиск элементов через $ и $$ всегда
возвращает объект Element или массив элементов, обернутых в
прокси WebdriverIO. Важно помнить, что сам элемент может не быть сразу
доступен на странице, поэтому часто требуется ожидание:
const button = await $('#submit');
await button.waitForClickable({ timeout: 5000 });
await button.click();
Метод waitForClickable позволяет дождаться, пока элемент
не станет кликабельным, предотвращая ошибки типа
element not interactable.
Асинхронность в тестах требует контроля времени ожидания состояния элементов. WebdriverIO предоставляет гибкие методы:
Позволяет ждать выполнение произвольного условия:
await browser.waitUntil(async () => {
const text = await $('#status').getText();
return text === 'Готово';
}, {
timeout: 10000,
timeoutMsg: 'Статус не обновился за 10 секунд'
});
Специализированные методы для проверки появления элементов:
const alert = await $('#alert');
await alert.waitForDisplayed({ timeout: 5000 });
Использование этих методов гарантирует стабильность тестов, даже если страница загружается медленно.
WebdriverIO позволяет использовать хуки для асинхронной подготовки и очистки тестовой среды:
before: выполняется перед всеми тестами в файлеbeforeEach: выполняется перед каждым тестомafterEach: выполняется после каждого тестаafter: выполняется после всех тестовПример использования:
beforeEach(async () => {
await browser.url('https://example.com');
await $('#login').setValue('user');
});
Все хуки поддерживают async/await, что делает
последовательное выполнение действий надежным.
Асинхронный код в WebdriverIO должен корректно обрабатывать
исключения. Обычная практика — использование try/catch:
try {
const modal = await $('#modal');
await modal.waitForDisplayed({ timeout: 3000 });
await modal.close();
} catch (error) {
console.log('Модальное окно не появилось:', error.message);
}
Это предотвращает падение всего теста из-за непредвиденного отсутствия элемента или задержек в загрузке страницы.
В реальных сценариях тесты часто включают последовательные асинхронные действия: переход по страницам, заполнение форм, проверку уведомлений.
it('регистрация нового пользователя', async () => {
await browser.url('/register');
const username = await $('#username');
const password = await $('#password');
const submit = await $('#submit');
await username.setValue('testuser');
await password.setValue('securepass');
await submit.click();
const successMsg = await $('#success');
await successMsg.waitForDisplayed({ timeout: 5000 });
});
Правильное использование await обеспечивает корректный
порядок действий и стабильность тестов.
WebdriverIO поддерживает создание пользовательских команд через
browser.addCommand или element.addCommand,
которые также могут быть асинхронными:
browser.addCommand('login', async (username, password) => {
await $('#username').setValue(username);
await $('#password').setValue(password);
await $('#submit').click();
});
await browser.login('admin', 'adminpass');
Это позволяет инкапсулировать повторяющиеся действия и сохранять чистоту тестового кода.
Асинхронность в WebdriverIO — ключевой элемент архитектуры,
обеспечивающий надежное взаимодействие с браузером и элементами
страницы. Понимание принципов работы async/await, ожиданий
и обработки ошибок формирует основу стабильных и масштабируемых
тестов.