Механизмы ожидания в Selenium

В Selenium механизм ожидания играет ключевую роль в обеспечении загрузки элементов страницы перед выполнением операций.

Поскольку на скорость загрузки веб-страницы влияют такие факторы, как сеть и производительность сервера, прямая работа с элементами, которые ещё не завершили загрузку, может привести к сбоям скрипта.

Selenium предоставляет несколько механизмов ожидания для решения этой проблемы.

1. Неявное ожидание (implicitly_wait)

1.1 Что такое неявное ожидание?

Неявное ожидание — это глобальный механизм ожидания, который ждёт определённое время при поиске элементов. Если элемент найден в течение указанного времени, Selenium сразу продолжит выполнение последующих операций; если элемент так и не найден по истечении тайм-аута, будет выброшено исключениеNoSuchElementExceptionисключение.

1.2 Как использовать неявное ожидание?

Неявное ожидание задаётся черезimplicitly_wait()метод. Этот метод нужно вызвать только один раз, и все последующие операции поиска элементов будут использовать это время ожидания.

Пример

from selenium import webdriver
from selenium.webdriver.chrome.service import Service as ChromeService

# Установите правильный путь к драйверу
service = ChromeService(executable_path="./chromedriver-mac-arm64/chromedriver")
options = webdriver.ChromeOptions()
driver = webdriver.Chrome(service=service, options=options)

# Установить время неявного ожидания в 10 секунд
driver.implicitly_wait(10)

# Открыть веб-страницу
driver.get("https://example.com")

# Найти элемент
element = driver.find_element_by_id("element_id")

# Закройте браузер
driver.quit()

1.3 Плюсы и минусы неявного ожидания

Преимущества:

  • Простое и удобное в использовании; задаётся один раз и применяется ко всем операциям поиска элементов.
  • Подходит для большинства простых сценариев.

Недостатки:

  • Глобальное ожидание может приводить к излишнему времени ожидания.
  • Не может обрабатывать некоторые сложные условия ожидания, например ожидание, пока элемент станет кликабельным.

2. Явное ожидание (WebDriverWait и expected_conditions)

2.1 Что такое явное ожидание?

Явное ожидание — это более гибкий механизм ожидания, который позволяет задавать условия ожидания для конкретных операций. Явное ожидание обычно используется вместе сWebDriverWaitкласс иexpected_conditionsмодуль.

2.2 Как использовать явное ожидание?

Базовое использование явного ожидания выглядит следующим образом:

Пример

from selenium import webdriver
from selenium.webdriver.chrome.service import Service as ChromeService
from selenium.webdriver.common.by import С помощью
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

# Установите правильный путь к драйверу
service = ChromeService(executable_path="./chromedriver-mac-arm64/chromedriver")
options = webdriver.ChromeOptions()
driver = webdriver.Chrome(service=service, options=options)

# Открыть веб-страницу
driver.get("https://example.com")

# Установить явное ожидание, ждать до 10 секунд, пока не появится элемент
element = WebDriverWait(driver, 10).until(
    EC.presence_of_element_located((By.ID, "element_id"))
)

# Закройте браузер
driver.quit()

2.3 Часто используемые expected_conditions

expected_conditionsМодуль предоставляет множество предопределённых условий ожидания. Вот некоторые часто используемые из них:

  • presence_of_element_located: Ожидать, пока элемент появится в DOM.
  • visibility_of_element_located: Ожидать, пока элемент появится в DOM и станет видимым.
  • element_to_be_clickable: Ожидать, пока элемент станет кликабельным.
  • text_to_be_present_in_element: Ожидать, пока текст элемента будет содержать указанный текст.

2.4 Плюсы и минусы явного ожидания

Преимущества:

  • Высокая гибкость; можно задавать разные условия ожидания для разных операций.
  • Позволяет обрабатывать сложные сценарии ожидания.

Недостатки:

  • Код относительно сложен и требует больше кода.
  • Условия ожидания нужно задавать отдельно для каждой операции.

3. Фиксированное ожидание (time.sleep)

3.1 Что такое фиксированное ожидание?

Фиксированное ожидание — простейший механизм ожидания. Оно приостанавливает выполнение скрипта на заданное время с помощьюtime.sleep()метода. Независимо от того, завершилась ли загрузка страницы, скрипт ждёт указанное время, прежде чем продолжить.

3.2 Как использовать фиксированное ожидание?

Пример

import time
from selenium import webdriver
from selenium.webdriver.chrome.service import Service as ChromeService

# Установите правильный путь к драйверу
service = ChromeService(executable_path="./chromedriver-mac-arm64/chromedriver")
options = webdriver.ChromeOptions()
driver = webdriver.Chrome(service=service, options=options)

# Открыть веб-страницу
driver.get("https://example.com")

# Фиксированное ожидание на 5 секунд
time.sleep(5)

# Найти элемент
element = driver.find_element_by_id("element_id")

# Закройте браузер
driver.quit()

3.3 Плюсы и минусы фиксированного ожидания

Преимущества:

  • Просто и легко использовать; подходит для простых тестовых сценариев.

Недостатки:

  • Неэффективно и может приводить к излишнему времени ожидания.
  • Невозможно динамически регулировать время ожидания в зависимости от условий загрузки страницы.

4. Гибкое ожидание (Fluent Wait)

Назначение:Динамически задавать условия ожидания, настраивать частоту опроса и игнорировать определённые исключения.

Метод:WebDriverWait в сочетании с polling_every и ignoring

Особенности:Более гибкое, подходит для сценариев, требующих динамической настройки времени ожидания.

Пример

from selenium import webdriver
from selenium.webdriver.chrome.service import Service as ChromeService
from selenium.webdriver.common.by import С помощью
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.common.exceptions import NoSuchElementException

# Установите правильный путь к драйверу
service = ChromeService(executable_path="./chromedriver-mac-arm64/chromedriver")
options = webdriver.ChromeOptions()
driver = webdriver.Chrome(service=service, options=options)

driver.get("https://www.example.com")

# Настроить Fluent Wait
wait = WebDriverWait(driver, timeout=10, poll_frequency=1, ignored_exceptions=[NoSuchElementException])
element = wait.until(EC.presence_of_element_located((By.ID, "username")))

5. Итоги

  • Неявное ожидание: подходит для простых сценариев, глобальное ожидание, но может приводить к ненужному времени ожидания.
  • Явное ожидание: подходит для сложных сценариев, обладает высокой гибкостью, но код относительно сложен.
  • Фиксированное ожидание: просто и удобно в использовании, но неэффективно; не рекомендуется для сложных тестовых сценариев.
  • Fluent Wait:: подходит для сценариев, требующих динамической настройки времени ожидания.

В реальном автоматизированном тестировании рекомендуется выбирать подходящий механизм ожидания в зависимости от конкретных требований теста. Как правило, явное ожидание является наиболее рекомендуемым подходом, поскольку оно обеспечивает лучшую гибкость и эффективность.


6. Комплексный пример

Ниже приведён полный пример, демонстрирующий, как использовать неявное ожидание и явное ожидание:

Пример

from selenium import webdriver
from selenium.webdriver.chrome.service import Service as ChromeService
from selenium.webdriver.common.by import С помощью
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

# Установите правильный путь к драйверу
service = ChromeService(executable_path="./chromedriver-mac-arm64/chromedriver")
options = webdriver.ChromeOptions()
driver = webdriver.Chrome(service=service, options=options)

# Установить неявное ожидание
driver.implicitly_wait(5)

# Открыть веб-страницу
driver.get("https://www.example.com")

# Использовать явное ожидание для видимости элемента
username = WebDriverWait(driver, 10).until(
    EC.visibility_of_element_located((By.ID, "username"))
)
username.send_keys("testuser")

# Использовать явное ожидание для кликабельности элемента
submit_button = WebDriverWait(driver, 10).until(
    EC.element_to_be_clickable((By.ID, "submit-btn"))
)
submit_button.click()

# Закройте браузер
driver.quit()
Другие расширения