Урок по треку Автоматизация тестирования 8 мин

Selenium и WebDriver за 8 минут

Протокол WebDriver, Selenium 4, ожидания, исключения, Grid.

Selenium самый старый и самый распространённый инструмент браузерной автоматизации. В РФ его до сих пор много в вакансиях, особенно в связке Java + Selenide или Python + pytest.

Как это устроено

WebDriver это стандарт W3C: HTTP-протокол, по которому клиент говорит браузеру «открой страницу», «найди элемент», «кликни». Цепочка такая:

тест (Python/Java/C#) → клиентская библиотека Selenium → драйвер (chromedriver, geckodriver) → браузер

Selenium 4 целиком работает по W3C-протоколу. Начиная с Selenium 4.6 есть Selenium Manager: он сам находит или скачивает подходящий драйвер, поэтому руками качать chromedriver больше не нужно.

Базовый тест на Python

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

driver = webdriver.Chrome()
try:
    driver.get("https://example.test/login")
    driver.find_element(By.NAME, "email").send_keys("qa@example.test")
    WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "[data-testid=submit]"))).click()
finally:
    driver.quit()

quit() закрывает браузер и завершает сессию драйвера. close() закрывает только текущее окно.

Поиск элементов

  • find_element возвращает первый найденный элемент или бросает NoSuchElementException.
  • find_elements возвращает список, если ничего нет, пустой. Удобно для проверки отсутствия.
  • Стратегии By: ID, NAME, CSS_SELECTOR, XPATH, CLASS_NAME, TAG_NAME, LINK_TEXT, PARTIAL_LINK_TEXT.

Исключения, которые надо знать

  • NoSuchElementException: элемента нет (или не дождались).
  • StaleElementReferenceException: элемент был найден, но DOM перерисовался, и ссылка протухла. Лечится повторным поиском, а не хранением элементов надолго.
  • ElementClickInterceptedException: клик попал в другой элемент сверху (модалка, лоадер).
  • ElementNotInteractableException: элемент есть, но с ним нельзя взаимодействовать (скрыт, нулевой размер).
  • TimeoutException: явное ожидание не дождалось условия.

Окна, фреймы, алерты

  • driver.switch_to.frame(...) и switch_to.default_content() для iframe. Элементы внутри фрейма не видны, пока не переключишься.
  • driver.window_handles и switch_to.window(handle) для вкладок.
  • driver.switch_to.alert.accept() для системных диалогов.

Действия и JavaScript

ActionChains для наведения, drag and drop, двойного клика, сочетаний клавиш. execute_script для прокрутки или чтения значения. Клик через JavaScript обходит проверки браузера: тест пройдёт, даже если реальный пользователь не смог бы нажать кнопку. Это последнее средство.

Selenium Grid

Grid запускает браузеры на удалённых машинах: тест создаёт webdriver.Remote(command_executor=..., options=...). Режимы Grid 4: standalone (всё в одном), hub и node, полностью распределённый. В контейнерах часто используют образы selenium/standalone-chrome или альтернативы вроде Selenoid и Moon.

Selenide и обёртки

Selenide (Java) добавляет к Selenium автоожидания, лаконичный синтаксис и скриншоты при падении. Часто встречается в российских командах.

Частые ошибки

  • Смешивать неявные и явные ожидания.
  • Хранить найденный элемент между действиями и ловить stale.
  • Кликать через JavaScript, чтобы «просто прошло».
  • Забывать quit(), оставляя висеть браузеры на агенте CI.

Что спросят на собесе

  • Как устроен WebDriver: что между тестом и браузером?
  • Чем find_element отличается от find_elements?
  • Что такое StaleElementReferenceException и как с ним бороться?
  • Как работать с iframe и новыми вкладками?
  • Зачем нужен Selenium Grid?

Закрепите за 5 минут

После урока в тренажёре 3-5 проверочных вопросов, дальше модуль уходит в повторения.