Python: Selenium
Теория: Механизмы ожиданий
Разница между implicitly_wait и WebDriverWait
Когда Selenium работает с браузером, страница может загружаться не сразу: часть элементов появляется с задержкой, особенно при асинхронной подгрузке через JavaScript. Если тест попытается найти элемент раньше, чем он появится, возникнет ошибка NoSuchElementException. Чтобы этого избежать, в Selenium есть механизмы ожиданий — они позволяют подождать появления элемента перед тем, как к нему обращаться.
Неявное ожидание (implicitly_wait)
Неявное ожидание действует глобально. Его достаточно один раз установить, и Selenium будет автоматически ждать появления каждого элемента до заданного времени. Если элемент появился раньше, выполнение продолжается сразу, без паузы.
Если за 5 секунд элемент так и не появился, выбрасывается ошибка. Это простой и удобный вариант, когда все элементы загружаются примерно одинаково. Но если на странице есть разные задержки, неявное ожидание не всегда подходит — оно одинаковое для всех случаев.
Явное ожидание (WebDriverWait)
Явное ожидание используют, когда нужно дождаться конкретного события или элемента. В отличие от implicitly_wait, оно настраивается точечно для каждой ситуации.
Метод until() ждёт, пока выполняется переданное условие. Если условие стало истинным раньше — ожидание завершается сразу. Если нет — по истечении времени выбрасывается TimeoutException.
Примеры условий из модуля expected_conditions:
Разница между implicitly_wait и WebDriverWait
implicitly_wait — это общий таймер на все поиски. Он прост, но не гибок. Selenium просто повторяет попытки поиска, пока не истечёт заданное время. WebDriverWait — это явное ожидание для конкретного действия. Оно используется тогда, когда важно дождаться определённого состояния элемента: появления, кликабельности, исчезновения и т.д.
В одном проекте можно использовать оба механизма, но в большинстве случаев предпочтительнее WebDriverWait. Он даёт полный контроль над поведением теста и снижает риск случайных сбоев из-за нестабильной загрузки страницы.
ExpectedConditions
Когда используется явное ожидание (WebDriverWait), ему нужно передать условие, при котором ожидание завершится. Эти условия находятся в модуле selenium.webdriver.support.expected_conditions, который обычно сокращают до EC. Он содержит готовые проверки — их не нужно писать вручную. Selenium каждые 500 мс проверяет, выполняется ли условие. Как только оно становится истинным — тест идёт дальше.
Импорт выглядит так:
Рассмотрим самые часто используемые условия.
-
presence_of_element_located. Ждёт, пока элемент появится в DOM. Видимым он при этом может и не быть. -
visibility_of_element_located. Ждёт, пока элемент станет видимым на странице (присутствует в DOM и имеет ненулевые размеры).
element_to_be_clickable. Ждёт, пока элемент станет доступен для клика — то есть видим и не заблокирован.
-
text_to_be_present_in_element. Ждёт, пока в элементе появится нужный текст. Полезно при проверке сообщений или уведомлений. -
invisibility_of_element_located. Ждёт, пока элемент исчезнет со страницы. Часто применяют для загрузочных спиннеров. -
frame_to_be_available_and_switch_to_itЖдёт, пока появится iframe, и автоматически переключается внутрь. -
alert_is_presentЖдёт появления системного окна (alert, confirm, prompt). -
element_located_selection_state_to_beЖдёт, пока чекбокс или радиокнопка перейдёт в нужное состояние.
Все эти функции возвращают найденный элемент (или True в случае условий без элемента), если условие выполнилось, или вызывают TimeoutException, если время истекло.
ExpectedConditions делают тесты устойчивыми. Они позволяют синхронизировать действия Selenium с поведением страницы и исключают случайные ошибки вроде «элемент не найден» или «не кликабелен».
Ожидания видимости, кликабельности и других состояний элементов
Когда страница загружается, элементы не всегда сразу становятся доступны для действий. Они могут быть созданы JavaScript-ом позже, находиться под оверлеем, быть прозрачными или заблокированными. Если попытаться кликнуть слишком рано — Selenium выбросит ошибку ElementNotInteractableException или ElementClickInterceptedException. Чтобы избежать этого, используют ожидания состояний элементов — специальные проверки, которые гарантируют, что элемент готов к взаимодействию.
Ожидание видимости
EC.visibility_of_element_located() ждёт, пока элемент появится в DOM и станет видимым — то есть не имеет display: none и имеет размеры больше нуля. Это одно из самых частых ожиданий при загрузке контента или сообщений.
Если элемент появился и стал видим, wait.until() возвращает его. Если нет — по истечении тайм-аута вылетит TimeoutException.
Ожидание кликабельности
EC.element_to_be_clickable() проверяет два условия одновременно: элемент видим и не заблокирован (disabled=False). Это важно для кнопок и ссылок, особенно когда интерфейс сначала рисует кнопку, а потом делает её активной.
Без этого ожидания тест может кликнуть по элементу в момент, когда он ещё не активен — и клик не сработает.
Ожидание присутствия
EC.presence_of_element_located() ждёт, пока элемент появится в DOM. Он не обязан быть видимым, но уже существует в структуре страницы. Это базовое ожидание при поиске динамически подгружаемых элементов.
Ожидание исчезновения
EC.invisibility_of_element_located() используется, когда нужно дождаться, чтобы элемент пропал со страницы. Часто применяется для загрузочных спиннеров или всплывающих блоков.
Это гарантирует, что страница полностью готова к дальнейшим действиям.
Ожидание появления текста
EC.text_to_be_present_in_element() ждёт, пока в элементе появится конкретный текст. Применяется для проверки уведомлений, статусов или результатов выполнения действий.
Ожидание алерта
EC.alert_is_present() ждёт появления системного окна. Без этого тест не сможет взаимодействовать с alert, confirm или prompt.
Ожидание появления и перехода в iframe
EC.frame_to_be_available_and_switch_to_it() дожидается появления iframe и автоматически переключает контекст Selenium внутрь него.
В итоге
Каждое ожидание решает свою задачу.
presence_of_element_located— элемент появился.visibility_of_element_located— элемент виден.element_to_be_clickable— элемент доступен для клика.invisibility_of_element_located— элемент исчез.text_to_be_present_in_element— появился нужный текст.alert_is_present— появилось окно.
Тайм-ауты и обработка ошибок ожиданий
Когда тест ждёт появления элемента или нужного состояния, Selenium проверяет условие каждые полсекунды. Если за заданное время условие не выполнилось — выбрасывается исключение. Это исключение называется TimeoutException. Оно означает, что элемент так и не появился, не стал кликабельным или не исчез, как ожидалось. Работа теста останавливается, если ошибку не перехватить.
Тайм-ауты
Тайм-аут задаётся в секундах при создании ожидания. Например, WebDriverWait(driver, 10) — это 10 секунд. Если элемент появится через 2 секунды, ожидание завершится сразу. Если не появится, Selenium будет проверять условие каждые 0.5 секунды до конца тайм-аута.
Тайм-аут можно изменить под конкретный тест. Если страница грузится дольше, значение увеличивают. Если все элементы появляются мгновенно — уменьшают.
Обработка ошибок ожиданий
Чтобы тест не падал при каждом тайм-ауте, ошибки можно перехватывать через try/except. Это особенно важно, когда элемент может появляться не всегда, например, сообщение об ошибке после неудачного логина.
В этом примере тест не рухнет, если элемент не найден за 10 секунд. Он просто выведет сообщение в консоль. Такой подход помогает сделать тесты устойчивыми: ошибки контролируются, а сценарий может продолжать выполнение.
Тайм-аут при исчезновении элементов
Иногда нужно дождаться, пока элемент пропадёт. Если он не исчез вовремя, тест тоже получит TimeoutException. Например:
Это полезно для проверки стабильности интерфейса — если спиннер не пропал, значит, страница не готова.
Разница между тайм-аутами WebDriver и WebDriverWait
У браузера есть собственный тайм-аут загрузки страницы (set_page_load_timeout) и ожидания скриптов (set_script_timeout). Они отвечают за общие процессы, а не за элементы. WebDriverWait — это точечное ожидание конкретных условий. Его используют чаще всего в тестах, потому что он даёт полный контроль над проверкой состояний.
Selenium не ждёт автоматически, что всё появится мгновенно. Любое действие с элементом нужно защищать ожиданием. Тайм-аут определяет, сколько секунд тест будет проверять условие. Если время вышло — срабатывает TimeoutException, и дальше всё зависит от того, обрабатываете вы её или нет.


