⚖️ Старый vs Новый: антипаттерны и современный подход
Этот раздел показывает устаревшие паттерны из лекции и их современную замену на Selenium 4.x. Старый код показан только для понимания — не копируйте его в продакшн.
1. Alert: time.sleep → EC.alert_is_present()
Из лекции (старое — антипаттерн)
# test_alert_old.py — из лекции (старое)
import time
from selenium import webdriver
driver = webdriver.Chrome()
driver.get("URL_СТРАНИЦЫ")
# Жёсткое ожидание перед обращением к alert
time.sleep(2)
alert = driver.switch_to.alert
print(alert.text)
alert.accept()
Проблема:
time.sleep(2) — фиксированная задержка. Если Alert появился раньше, тест теряет время. Если позже — тест упадёт с NoAlertPresentException.
Современный подход (Selenium 4.x)
# test_alert_new.py — современный подход
from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
driver = webdriver.Chrome()
driver.get("URL_СТРАНИЦЫ")
# Ждём Alert надёжно
wait = WebDriverWait(driver, 10)
alert = wait.until(EC.alert_is_present())
print(alert.text)
alert.accept()
2. Drag and Drop: time.sleep → явное ожидание состояния
Из лекции (старое — содержит time.sleep)
# Из лекции (старое) — использование time.sleep для ожидания анимации
import time
from selenium.webdriver.common.action_chains import ActionChains
actions = ActionChains(driver)
actions.drag_and_drop(photo, trash).perform()
time.sleep(2) # Ожидание завершения анимации
# Проверка
photos_in_trash = len(driver.find_elements(...))
Проблема:
time.sleep(2) после drag&drop — ненадёжно. При медленной сети анимация занимает больше. При быстрой — тест лишние 2 секунды ждёт впустую.
Современный подход (Selenium 4.x)
# test_dnd_new.py — современный подход
from selenium.webdriver.common.action_chains import ActionChains
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
actions = ActionChains(driver)
actions.drag_and_drop(source, target).perform()
# Ждать конкретного состояния — появления элемента в зоне drop
wait = WebDriverWait(driver, 10)
wait.until(EC.text_to_be_present_in_element((By.ID, "droppable"), "Dropped"))
3. iframe: поиск без переключения → switch_to.frame()
Типичная ошибка (неправильно)
# НЕПРАВИЛЬНО — попытка найти элемент внутри iframe без переключения
driver.get("https://example.com/page-with-iframe.html")
element = driver.find_element(By.ID, "element-inside-iframe")
# Выбросит: NoSuchElementException
Проблема: Selenium ищет элементы только в текущем контексте. iframe — это отдельный документ. Без
switch_to.frame() элементы внутри iframe невидимы.
Правильный подход
# ПРАВИЛЬНО — переключиться в iframe сначала
from selenium.webdriver.common.by import By
iframe = driver.find_element(By.ID, "my-iframe")
driver.switch_to.frame(iframe)
# Теперь найдём элемент
element = driver.find_element(By.ID, "element-inside-iframe")
# Не забыть вернуться!
driver.switch_to.default_content()
4. Загрузка файла: относительный путь → абсолютный путь
Типичная ошибка (из лекции)
# Из лекции — использование относительного пути (ненадёжно)
file_path = "/path/to/your/file.txt" # Прямой путь
file_input.send_keys(file_path)
Проблема: при запуске из разных рабочих директорий относительный путь не найдёт файл. На Windows слэши тоже могут быть проблемой.
Правильный подход (Selenium 4.x)
# ПРАВИЛЬНО — абсолютный путь через os или pathlib
import os
from pathlib import Path
# Вариант 1: os.path.abspath
file_path = os.path.abspath("test_data/file.txt")
file_input.send_keys(file_path)
# Вариант 2: pathlib (рекомендуется для Python 3.4+)
file_path = str(Path("test_data/file.txt").resolve())
file_input.send_keys(file_path)
5. Переключение вкладок: без явного switch_to → надёжная навигация
Типичная ошибка
# НЕПРАВИЛЬНО — попытка работать с новой вкладкой без переключения
driver.execute_script("window.open('https://google.com', '_blank');")
# Selenium всё ещё работает на первой вкладке!
title = driver.title # Вернёт заголовок ПЕРВОЙ вкладки, не Google
Правильный подход
# ПРАВИЛЬНО — явно переключаться после открытия
driver.execute_script("window.open('https://google.com', '_blank');")
tabs = driver.window_handles
driver.switch_to.window(tabs[-1]) # Переключиться на последнюю открытую вкладку
title = driver.title # Теперь заголовок Google