Protractor является инструментом для end-to-end тестирования Angular и не только. Одной из ключевых особенностей успешных тестов является корректная работа с асинхронностью и динамическим содержимым страницы. Веб-элементы часто загружаются с задержкой, а прямой доступ к ним без ожидания может привести к нестабильным тестам.
Protractor использует WebDriverJS, который оперирует промисами. Это значит, что операции над элементами часто происходят асинхронно, и правильное управление ожиданиями критично для стабильности тестов.
Implicit Wait Implicit wait задается глобально для драйвера и заставляет WebDriver проверять наличие элемента заданное количество времени перед выбросом исключения.
browser.manage().timeouts().implicitlyWait(5000); // 5 секунд
Особенности:
Explicit Wait (ExpectedConditions) Explicit wait
позволяет ожидать определенных условий для конкретного элемента.
Protractor предоставляет модуль ExpectedConditions.
const EC = protractor.ExpectedConditions;
const myElement = element(by.css('.my-class'));
browser.wait(EC.visibilityOf(myElement), 5000, 'Элемент не появился за 5 секунд');
Основные условия:
visibilityOf(element) — элемент видим на странице.presenceOf(element) — элемент присутствует в DOM, не
обязательно видим.elementToBeClickable(element) — элемент видим и
доступен для клика.textToBePresentInElement(element, text) — в элементе
появляется нужный текст.Лучшие практики:
Fluent Wait (кастомные ожидания) Fluent wait
позволяет задавать интервал повторных проверок и игнорировать ошибки. В
Protractor это реализуется через комбинацию browser.wait и
кастомной функции:
const myElement = element(by.css('.my-class'));
browser.wait(() => {
return myElement.isDisplayed().then(displayed => displayed);
}, 5000, 'Элемент не стал видимым за 5 секунд');
Преимущества:
Не использовать sleep для ожидания Жесткая пауза
(browser.sleep(5000)) может привести к ненужному замедлению
тестов и нестабильности.
Всегда проверять видимость или доступность
элемента Даже если элемент присутствует в DOM, он может быть
скрыт или перекрыт другими элементами. Использование
visibilityOf и elementToBeClickable
обеспечивает корректное взаимодействие.
Комбинировать ожидания для сложных сценариев Например, перед кликом на кнопку, которая появляется после загрузки данных:
const EC = protractor.ExpectedConditions;
const button = element(by.id('submit'));
browser.wait(EC.presenceOf(button), 5000);
browser.wait(EC.elementToBeClickable(button), 5000);
button.click();
Такой подход снижает вероятность ошибок
ElementNotInteractableError.
Использовать таймауты разумно Большие таймауты увеличивают стабильность тестов, но замедляют их выполнение. Оптимальный диапазон — 3–10 секунд для большинства веб-приложений.
Логирование ожиданий Сообщения об ошибках при таймауте должны быть информативными: указывают, какой элемент и какое состояние не было достигнуто. Это облегчает отладку.
Protractor автоматически синхронизируется с Angular через
waitForAngular. Однако:
Для элементов, которые появляются после асинхронного запроса не
Angular ($http, AJAX, сторонние скрипты), нужно
использовать explicit wait.
Для ng-model и ng-repeat можно проверять количество элементов:
const items = element.all(by.repeater('item in items'));
browser.wait(() => items.count().then(count => count > 0), 5000);Минимизировать количество ожиданий в тестах, объединяя условия.
Создавать вспомогательные функции ожидания для повторяющихся сценариев:
function waitForVisible(el, timeout = 5000) {
const EC = protractor.ExpectedConditions;
return browser.wait(EC.visibilityOf(el), timeout);
}Использовать Page Object Model, чтобы централизованно управлять ожиданиями для каждого элемента страницы.
Эффективное использование ожиданий является основой стабильных и быстрых тестов в Protractor. Правильное сочетание explicit, implicit и кастомных ожиданий позволяет создать тесты, которые корректно реагируют на динамическое поведение веб-приложений, избегая ненужных сбоев и повышая поддерживаемость кода.