Убедитесь, что он есть

В предыдущем посте мы рассмотрели, как находить элементы перед взаимодействием с ними. В этом посте мы рассмотрим, как работают ожидания в 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 вида ожидания:

  1. Скрытый
  2. Явный
  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-адресами, окнами и фреймами.

использованная литература

  1. https://www.selenium.dev/documentation/en/webdriver/waits/
  2. https://www.softwaretestingo.com/selenium-wait-commands/
  3. https://selenium-python.readthedocs.io/waits.html
  4. https://github.com/SeleniumHQ/selenium/blob/trunk/py/selenium/webdriver/support/wait.py

Спасибо за уделенное время.