🐛 Частые ошибки: продвинутый Selenium
⚡ Топ-5 ошибок
- NoAlertPresentException — обратились к alert без ожидания его появления
- NoSuchElementException в iframe — забыли
switch_to.frame()перед поиском - NoSuchWindowException — вызвали
driver.close()и не переключились на другую вкладку - Drag&drop не работает — элемент в iframe, не переключились перед операцией
- File upload — файл не найден — передали относительный путь вместо абсолютного
1. NoAlertPresentException
Симптом:
selenium.common.exceptions.NoAlertPresentException: Message: no such alert
Причина
Попытка переключиться на Alert, которого ещё нет на странице. Или Alert уже закрылся.
# НЕПРАВИЛЬНО — нет ожидания Alert
button.click()
alert = driver.switch_to.alert # Падение, если alert ещё не появился
Решение
# ПРАВИЛЬНО — дождаться Alert через EC
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
button.click()
wait = WebDriverWait(driver, 10)
alert = wait.until(EC.alert_is_present())
alert.accept()
2. NoSuchElementException внутри iframe
Симптом:
selenium.common.exceptions.NoSuchElementException для элемента, который явно есть на странице
Причина
Элемент находится внутри iframe, а Selenium работает в контексте основной страницы.
# НЕПРАВИЛЬНО — не переключились в iframe
driver.get("https://example.com/page-with-iframe.html")
element = driver.find_element(By.ID, "inside-iframe") # NoSuchElementException
Решение
# ПРАВИЛЬНО — сначала переключиться, потом искать
iframe = driver.find_element(By.TAG_NAME, "iframe")
driver.switch_to.frame(iframe)
element = driver.find_element(By.ID, "inside-iframe") # OK
driver.switch_to.default_content() # Вернуться
3. NoSuchWindowException после close()
Симптом:
selenium.common.exceptions.NoSuchWindowException: no such window
Причина
Вызвали driver.close() для закрытия вкладки, но не переключились на другую вкладку. Selenium больше не знает, с каким окном работать.
# НЕПРАВИЛЬНО
driver.switch_to.window(tabs[1])
driver.close() # Закрыли вкладку
driver.find_element(By.ID, "some-id") # NoSuchWindowException
Решение
# ПРАВИЛЬНО — после close() переключиться на оставшуюся вкладку
driver.switch_to.window(tabs[1])
driver.close()
driver.switch_to.window(tabs[0]) # Переключиться на первую вкладку
driver.find_element(By.ID, "some-id") # OK
4. Drag and Drop не работает (элемент в iframe)
Симптом:
NoSuchElementException при поиске source/target для drag&drop
Причина
Drag&drop виджет находится внутри iframe. Попытка найти элементы без переключения контекста.
# НЕПРАВИЛЬНО — drag и drop элементы в iframe, но не переключились
source = driver.find_element(By.ID, "draggable") # NoSuchElementException
Решение
# ПРАВИЛЬНО — переключиться в iframe перед поиском
driver.switch_to.frame(driver.find_element(By.TAG_NAME, "iframe"))
source = driver.find_element(By.ID, "draggable")
target = driver.find_element(By.ID, "droppable")
ActionChains(driver).drag_and_drop(source, target).perform()
Примечание: в некоторых браузерах и на некоторых сайтах нативный
drag_and_drop Selenium может не работать из-за особенностей реализации JS-событий. В таком случае рассмотрите альтернативу — drag_and_drop_by_offset или JavaScript-подход. Это выходит за рамки данного урока.
⚠️ Проверить по документации: альтернативные методы drag&drop при проблемах с ActionChains
5. Загрузка файла — Invalid or corrupt file
Симптом: Файл не загружается или браузер сообщает о некорректном пути
Причина
Передан относительный путь к файлу. Браузер не может его найти относительно своей рабочей директории.
# НЕПРАВИЛЬНО — относительный путь
file_input.send_keys("test_data/file.txt") # Может не работать
Решение
# ПРАВИЛЬНО — абсолютный путь
import os
file_path = os.path.abspath("test_data/file.txt")
file_input.send_keys(file_path)
# На Windows путь выглядит так:
# C:\Users\user\project\test_data\file.txt
6. Забыли .perform() в ActionChains
Симптом: Никаких действий не происходит, тест не падает с ошибкой, но UI не изменяется
Причина
Цепочка ActionChains накапливает действия, но без .perform() они не отправляются браузеру.
# НЕПРАВИЛЬНО — действие не выполнится
ActionChains(driver).move_to_element(element) # Нет .perform()
Решение
# ПРАВИЛЬНО
ActionChains(driver).move_to_element(element).perform()