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?