TimeoutError в Protractor — один из ключевых типов ошибок, напрямую связанных с асинхронной природой браузерного тестирования. Он возникает, когда ожидаемое состояние приложения не наступает за отведённое время. Глубокое понимание причин, механизмов и способов обработки TimeoutError критично для стабильности и воспроизводимости e2e-тестов.
Protractor построен поверх WebDriverJS и использует механизм ожиданий (waits), который контролирует синхронизацию тестов с состоянием Angular-приложения и DOM. TimeoutError выбрасывается в следующих случаях:
browser.wait);Фактически TimeoutError означает не «ошибку теста», а нарушение предположения о времени реакции приложения.
browser.wait)Используется для явных ожиданий:
browser.wait(EC.visibilityOf(element(by.css('.loader'))), 5000);
Если условие ExpectedConditions не выполнится за 5000
мс, будет выброшен TimeoutError.
Ключевые особенности:
browser.manage().timeouts())Protractor управляет тремя типами таймаутов WebDriver:
browser.manage().timeouts().implicitlyWait(0);
browser.manage().timeouts().pageLoadTimeout(30000);
browser.manage().timeouts().scriptTimeout(10000);
implicitlyWait Отвечает за неявные ожидания поиска элементов. При ненулевом значении может маскировать проблемы и затруднять диагностику TimeoutError.
pageLoadTimeout Возникает при слишком долгой загрузке страницы (редиректы, тяжёлые ресурсы).
scriptTimeout Связан с выполнением асинхронных
скриптов, включая executeAsyncScript.
Protractor по умолчанию ожидает завершения $http,
$timeout, $interval в Angular. TimeoutError
возможен, если:
$digest;Управление:
browser.waitForAngularEnabled(false);
Отключение синхронизации часто используется для гибридных или не-Angular страниц.
ExpectedConditions — основной инструмент управления
ожиданиями. Неправильный выбор условия напрямую ведёт к
TimeoutError.
Примеры типичных ошибок:
presenceOf, когда элемент есть в DOM, но
скрыт;visibilityOf, когда элемент перекрыт
другим;elementToBeClickable, когда атрибут
disabled меняется динамически.Комбинирование условий снижает риск таймаутов:
browser.wait(
EC.and(
EC.presenceOf(el),
EC.visibilityOf(el)
),
7000
);
TimeoutError редко является корневой проблемой. Он — симптом.
Эффективная диагностика включает:
afterEach;Пример получения информации об элементе:
el.getOuterHtml().then(html => console.log(html));
Protractor поддерживает async/await, что позволяет явно обрабатывать TimeoutError:
try {
await browser.wait(EC.visibilityOf(el), 5000);
} catch (e) {
if (e.name === 'TimeoutError') {
// обработка
}
}
Подход полезен для:
Простое увеличение таймаута:
browser.wait(EC.visibilityOf(el), 30000);
часто скрывает архитектурные проблемы:
Допустимо только при:
TimeoutError может возникать не на уровне Protractor, а тестового фреймворка.
jasmine.DEFAULT_TIMEOUT_INTERVAL = 60000;
Если тест не завершился за это время, будет выброшена ошибка, внешне похожая на TimeoutError, но с другим источником.
this.timeout(60000);
Важно различать:
Многие TimeoutError вызваны гонками:
Решения:
EC.urlContains);Отказ от implicit wait Явные ожидания предсказуемее и легче отлаживаются.
Единая стратегия ожиданий Использование централизованных helper-функций для ожиданий.
Синхронизация с бизнес-событиями Ожидание результата действия, а не самого действия.
Контроль Angular-синхронизации Явное
включение/отключение waitForAngularEnabled.
TimeoutError неизбежен в e2e-тестировании, особенно в распределённых средах CI. Качество тестовой архитектуры определяется не отсутствием таймаутов, а:
Грамотная работа с TimeoutError превращает его из случайной помехи в управляемый инструмент контроля над поведением приложения и тестов.