Убедитесь, что он есть
В предыдущем посте мы рассмотрели, как находить элементы перед взаимодействием с ними. В этом посте мы рассмотрим, как работают ожидания в Selenium, чтобы убедиться, что элементы представлены в DOM, прежде чем взаимодействовать с ними.
Свойство document.readyState
HTML document
описывает состояние загрузки текущего документа. По умолчанию запрос driver.get
возвращается вызывающей стороне, когда состояние готовности становится complete
.
Существует 3 вида стратегий загрузки страниц для Selenium WebDriver.
нормальный
Подождите, пока загрузится вся страница, что определяется событием load
.
нетерпеливый
Подождите, пока исходный документ HTML не будет полностью загружен и проанализирован без таблиц стилей, изображений и подфреймов, указанных событием DOMContentLoaded
.
нет
Если стратегия загрузки страницы не установлена, Selenium WebDriver только ждет, пока загрузится начальная страница.
Когда Selenium WebDriver загружает страницу, по умолчанию используется стратегия normal
.
Различные элементы на странице могут загружаться в разное время. Это может привести к сбоям в поиске элементов. Если элемент отсутствует в структуре DOM, мы получаем исключение, когда пытаемся получить к нему доступ и работать с ним. Эти проблемы можно решить с помощью ожидания в Selenium.
Элементы, добавленные после завершения загрузки документа, не могут быть найдены методами find_*
. В этом случае наш код автоматизации поднимет NoSuchElementException
. Ожидание позволяет автоматическому выполнению задачи пройти определенное время, прежде чем перейти к следующему шагу.
Существует 3 вида ожидания:
- Скрытый
- Явный
- Беглый
Неявное ожидание
С неявным ожиданием WebDriver опрашивает DOM в течение указанного периода времени, прежде чем вызвать исключение. Значение по умолчанию — 0. После установки оно действует в течение всего срока службы экземпляра WebDriver.
В следующем примере id преднамеренно указан неправильно для метода find_element_by_id
. Поскольку мы устанавливаем неявное ожидание на 10 секунд, мы получим исключение через 10 секунд ожидания.
# output after 10 seconds Message: Unable to locate element: [id="typer"]
Неявные ожидания просты в использовании, но, поскольку интервал ожидания действителен для всех элементов и в течение времени жизни экземпляра WebDriver, они увеличивают общее время выполнения.
Selenium предоставляет явные ожидания, чтобы избежать недостатков этих жестко запрограммированных глобальных ожиданий.
Явное ожидание
В отличие от жестко запрограммированного неявного ожидания, явное ожидание ожидает выполнения определенного условия. Это также относится только к конкретному заданному элементу, а не ко всем элементам глобально.
Условие вызывается с определенной периодичностью (по умолчанию 0,5 секунды), пока не истечет время ожидания. Если условие не выполняется, поднимается TimeoutException
.
Есть несколько методов, предоставляемых Selenium Python API для общих случаев.
Они определены в модуле expected_conditions
пакета selenium.webdriver.support
.
Список ожидаемых условий
* alert_is_present
* element_located_selection_state_to_be
* element_located_to_be_selected
* element_selection_state_to_be
* element_to_be_clickable
* element_to_be_selected
* frame_to_be_available_and_switch_to_it
* invisibility_of_element
* invisibility_of_element_located
* new_window_is_opened
* number_of_windows_to_be
* presence_of_all_elements_located
* presence_of_element_located
* staleness_of
* text_to_be_present_in_element
* text_to_be_present_in_element_value
* title_contains
* title_is
* url_changes
* url_contains
* url_matches
* url_to_be
* visibility_of
* visibility_of_all_elements_located
* visibility_of_any_elements_located
* visibility_of_element_located
В следующем примере конец текста проверяется на анимированный элемент. Как только условие выполнено, функция ожидания возвращает значение true, и можно распечатать полный текст.
# output Full text typed: Ask Doctor Python to fix your code...
Пользовательские условия ожидания
Вы также можете создать свои собственные условия ожидания, если предыдущие методы не отвечают вашим требованиям. Пользовательское условие ожидания можно создать с помощью класса с методом __call__
, который возвращает False
, если условие не соответствует.
В следующем примере показана реализация пользовательского условия ожидания, которая проверяет, имеет ли элемент определенный класс css.
Поскольку неявные ожидания применяются глобально, рекомендуется не смешивать неявные и явные ожидания.
Свободное ожидание
FluentWait
определяет максимальное время ожидания условия, а также частоту проверки условия. Python API не имеет класса FluentWait
, но поддерживает его с помощью аргументов с ключевыми словами.
Я предлагаю вам прочитать Пост о свободном интерфейсе Мартина Фаулера.
То, что нужно запомнить
- Когда Selenium WebDriver загружает страницу, он по умолчанию использует стратегию загрузки страницы
normal
, которая ожидает возврата событияload
вызывающей стороне из запросаdriver.get
. - С неявным ожиданием WebDriver опрашивает DOM в течение указанного периода времени, прежде чем вызвать исключение. После того, как он установлен, он действителен в течение всей жизни экземпляра WebDriver и для всех элементов на странице.
- Явное ожидание ожидает выполнения определенного условия для определенного элемента.
В следующем посте я напишу о навигации между URL-адресами, окнами и фреймами.
использованная литература
- https://www.selenium.dev/documentation/en/webdriver/waits/
- https://www.softwaretestingo.com/selenium-wait-commands/
- https://selenium-python.readthedocs.io/waits.html
- https://github.com/SeleniumHQ/selenium/blob/trunk/py/selenium/webdriver/support/wait.py
Спасибо за уделенное время.