🐛 Типичные ошибки — Ожидания в Selenium
⚡ Топ-3 ошибки
- TimeoutException — таймаут слишком мал или EC не то
- presence vs visibility — элемент в DOM, но не виден
- Смешивание implicit + explicit — непредсказуемые задержки
Ошибка 1. TimeoutException — истёк таймаут ожидания
Симптом
selenium.common.exceptions.TimeoutException: Message:
Причины и исправление
| Причина | Решение |
|---|---|
| Таймаут слишком мал | Увеличьте таймаут: для slow calculator — 50 сек |
| Неправильный локатор | Проверьте локатор в DevTools браузера |
| Не то условие EC | Например, ждёте visibility, а элемент в DOM но скрыт — используйте presence |
| Страница изменилась | Проверьте, что тестовый сайт доступен и не изменил DOM |
Ошибка 2. presence vs visibility — неправильный выбор EC
Проблема
# НЕПРАВИЛЬНО: ждём visibility, но элемент скрыт (display:none)
element = wait.until(EC.visibility_of_element_located((By.ID, "hidden-input")))
# TimeoutException — элемент в DOM, но не виден
Исправление
# ПРАВИЛЬНО: для скрытых элементов — presence
element = wait.until(EC.presence_of_element_located((By.ID, "hidden-input")))
# Для кнопок, которые нужно нажать — clickable
button = wait.until(EC.element_to_be_clickable((By.ID, "submit-btn")))
Запомните разницу:
presence— элемент существует в DOM (может бытьdisplay:none)visibility— элемент виден пользователю (не скрыт, не за экраном)clickable— виден И включён (не disabled)
Ошибка 3. Смешивание implicitly_wait и WebDriverWait
Проблема
# ПЛОХО: оба типа ожиданий активны одновременно
driver.implicitly_wait(10)
wait = WebDriverWait(driver, 10)
# Поведение непредсказуемо: задержки могут суммироваться или конфликтовать
element = wait.until(EC.presence_of_element_located((By.ID, "some-id")))
Исправление
# ПРАВИЛЬНО: используйте только один подход
# Вариант 1 — только WebDriverWait + EC (рекомендуется)
wait = WebDriverWait(driver, 10)
element = wait.until(EC.presence_of_element_located((By.ID, "some-id")))
# Вариант 2 — только implicitly_wait (для простых случаев)
driver.implicitly_wait(10)
element = driver.find_element(By.ID, "some-id")
Ошибка 4. StaleElementReferenceException
Симптом
selenium.common.exceptions.StaleElementReferenceException:
Message: stale element reference: element is not attached to the page document
Причина
Элемент был найден, потом страница обновилась (AJAX-запрос перерисовал DOM), и ссылка на элемент устарела.
Исправление
# НЕПРАВИЛЬНО: находим элемент, затем страница обновляется — элемент устарел
button = driver.find_element(By.ID, "ajaxButton")
button.click()
# ...AJAX запрос обновляет DOM...
old_element = driver.find_element(By.ID, "some-dynamic-element")
wait.until(EC.staleness_of(old_element))
old_element.click() # StaleElementReferenceException!
# ПРАВИЛЬНО: находим элемент ПОСЛЕ обновления DOM
button = driver.find_element(By.ID, "ajaxButton")
button.click()
# Ждём обновления DOM
wait.until(EC.text_to_be_present_in_element((By.ID, "result"), "loaded"))
# Находим элемент заново
new_element = driver.find_element(By.ID, "some-dynamic-element")
new_element.click()
Ошибка 5. Забыть clear() перед send_keys()
Проблема
# НЕПРАВИЛЬНО: поле уже содержит "5", вводим "45" → получаем "545"
delay_input = driver.find_element(By.CSS_SELECTOR, "#delay")
delay_input.send_keys("45") # Вместо "45" в поле будет "545"!
Исправление
# ПРАВИЛЬНО: сначала очистить поле
delay_input = driver.find_element(By.CSS_SELECTOR, "#delay")
delay_input.clear() # Сбрасываем существующее значение
delay_input.send_keys("45") # Вводим нужное значение
Ошибка 6. time.sleep вместо явного ожидания
Проблема
# НЕПРАВИЛЬНО: жёсткое ожидание
import time
driver.find_element(By.ID, "ajaxButton").click()
time.sleep(15) # Ждём 15 секунд — даже если ответ пришёл через 2 сек
element = driver.find_element(By.CLASS_NAME, "bg-success")
Исправление
# ПРАВИЛЬНО: явное ожидание завершается как только условие выполнено
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
driver.find_element(By.ID, "ajaxButton").click()
wait = WebDriverWait(driver, 15)
wait.until(
EC.text_to_be_present_in_element(
(By.CLASS_NAME, "bg-success"), "Data loaded"
)
)
Ошибка 7. Неправильный таймаут для slow calculator
Проблема
# НЕПРАВИЛЬНО: задержка 45 сек, но таймаут только 10 сек
delay_input.send_keys("45")
# ...
wait = WebDriverWait(driver, 10) # TimeoutException через 10 сек!
Исправление
# ПРАВИЛЬНО: таймаут должен быть БОЛЬШЕ задержки
delay_input.send_keys("45")
# ...
wait = WebDriverWait(driver, 50) # 45 сек задержки + 5 сек запас