🏠 Домашнее задание 5
⚡ Суть ДЗ
- Задание 1: Найти iframe, переключиться в него, проверить наличие текста
- Задание 2: Перетащить фото в корзину (drag&drop), проверить счётчики
- Концепции:
switch_to.frame(),default_content(),ActionChains.drag_and_drop()
Условие задания (из LMS)
Задание 1: Проверка наличия текста в iframe
- Открыть страницу: https://bonigarcia.dev/selenium-webdriver-java/iframes.html
- Проверить наличие текста:
- Найти фрейм (iframe), в котором содержится искомый текст.
- Переключиться в этот iframe.
- Найти элемент, содержащий текст
"semper posuere integer et senectus justo curabitur." - Убедиться, что текст отображается на странице.
Задание 2: Тестирование Drag & Drop (перетаскивание изображения в корзину)
- Открыть страницу Drag & Drop Demo: https://www.globalsqa.com/demo-site/draganddrop/
- Выполнить следующие шаги:
- Захватить первую фотографию (верхний левый элемент).
- Перетащить её в область корзины (Trash).
- Проверить, что после перемещения:
- В корзине появилась одна фотография.
- В основной области осталось 3 фотографии.
- Ожидаемый результат:
- Фотография успешно перемещается в корзину.
- Вне корзины остаются 3 фотографии.
Подготовка окружения
Windows + PowerShell
# Создаём папку для ДЗ
mkdir homework_05
cd homework_05
# Создаём и активируем виртуальное окружение
python -m venv .venv
.\.venv\Scripts\Activate.ps1
# Устанавливаем зависимости
pip install selenium pytest webdriver-manager
# Проверяем
python -c "import selenium; print(selenium.__version__)"
Структура файлов
# homework_05/
# ├── conftest.py — фикстура браузера
# ├── test_iframe.py — Задание 1
# └── test_drag_trash.py — Задание 2
conftest.py — общая фикстура
# conftest.py
import pytest
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from webdriver_manager.chrome import ChromeDriverManager
@pytest.fixture
def browser():
"""Фикстура: создаём Chrome, максимизируем окно, после теста закрываем."""
service = Service(ChromeDriverManager().install())
driver = webdriver.Chrome(service=service)
driver.maximize_window()
yield driver
driver.quit()
Пошаговое решение — Задание 1: iframe
Шаг 1: Исследуем страницу
Страница bonigarcia.dev/selenium-webdriver-java/iframes.html содержит iframe с Lorem Ipsum текстом. Нам нужно найти нужный iframe и текст внутри него.
Шаг 2: Пишем тест
# test_iframe.py
import pytest
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
def test_iframe_text(browser):
"""Переключаемся в iframe и проверяем наличие заданного текста."""
browser.get("https://bonigarcia.dev/selenium-webdriver-java/iframes.html")
# Ждём появления iframe на странице
wait = WebDriverWait(browser, 10)
iframe = wait.until(
EC.presence_of_element_located((By.TAG_NAME, "iframe"))
)
# Переключаемся в iframe
browser.switch_to.frame(iframe)
# Ищем текст внутри iframe
target_text = "semper posuere integer et senectus justo curabitur."
# Ждём, пока body iframe загрузится
body = wait.until(
EC.presence_of_element_located((By.TAG_NAME, "body"))
)
# Проверяем наличие текста
assert target_text in body.text, (
f"Текст '{target_text}' не найден в iframe.\n"
f"Найдено: {body.text[:200]}..."
)
# Возвращаемся в основной контекст страницы
browser.switch_to.default_content()
Связь с теорией
- Концепция iframe: Теория → Раздел 4: Работа с фреймами
- Метод
switch_to.frame(): Справочник → Фреймы - Ошибка «забыли default_content»: Ошибки → Ошибка 2
Пошаговое решение — Задание 2: Drag & Drop
Шаг 1: Исследуем страницу globalsqa
Страница содержит галерею фотографий и область «Trash». Фотографии находятся в контейнере, корзина — отдельный блок. Важно: drag&drop на этом сайте реализован через jQuery UI и размещён внутри iframe.
⚠️ Проверить по документации: globalsqa.com использует jQuery UI drag-and-drop внутри iframe. Сначала переключитесь в iframe, затем выполняйте drag_and_drop(). Если стандартный метод не работает — используйте JS-inject из Ошибок → Ошибка 4.
Шаг 2: Пишем тест
# test_drag_trash.py
import pytest
from selenium.webdriver.common.by import By
from selenium.webdriver.common.action_chains import ActionChains
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
def test_drag_photo_to_trash(browser):
"""Перетаскиваем первую фото в корзину, проверяем счётчики."""
browser.get("https://www.globalsqa.com/demo-site/draganddrop/")
wait = WebDriverWait(browser, 15)
# Страница содержит iframe с галереей — переключаемся в него
iframe = wait.until(
EC.presence_of_element_located((By.CSS_SELECTOR, "iframe.demo-frame"))
)
browser.switch_to.frame(iframe)
# Ждём загрузки галереи
wait.until(EC.presence_of_element_located((By.CSS_SELECTOR, "#gallery li")))
# Находим все фотографии в галерее
photos = browser.find_elements(By.CSS_SELECTOR, "#gallery li")
assert len(photos) == 4, f"Ожидали 4 фото, нашли: {len(photos)}"
# Находим первую фотографию (верхний левый)
first_photo = photos[0]
# Находим корзину
trash = browser.find_element(By.CSS_SELECTOR, "#trash")
# Выполняем drag and drop
actions = ActionChains(browser)
actions.drag_and_drop(first_photo, trash).perform()
# Ждём изменения состояния
wait.until(lambda d: len(d.find_elements(By.CSS_SELECTOR, "#gallery li")) == 3)
# Проверяем, что в галерее осталось 3 фото
remaining_photos = browser.find_elements(By.CSS_SELECTOR, "#gallery li")
assert len(remaining_photos) == 3, (
f"В галерее должно остаться 3 фото, найдено: {len(remaining_photos)}"
)
# Проверяем, что в корзине появилась 1 фотография
trash_photos = browser.find_elements(By.CSS_SELECTOR, "#trash li")
assert len(trash_photos) == 1, (
f"В корзине должна быть 1 фото, найдено: {len(trash_photos)}"
)
# Возвращаемся в основной контекст
browser.switch_to.default_content()
Связь с теорией
- ActionChains.drag_and_drop(): Теория → Раздел 3: ActionChains
- Справочник drag_and_drop: Справочник → ActionChains
- Drag&drop внутри iframe: Примеры → Пример 6
- Нюансы HTML5 DnD: Ошибки → Ошибка 4
Запуск и проверка
Запуск в терминале (PowerShell)
# Активируем окружение (если не активировано)
.\.venv\Scripts\Activate.ps1
# Запускаем все тесты ДЗ
pytest homework_05/ -v
# Только задание 1
pytest homework_05/test_iframe.py -v
# Только задание 2
pytest homework_05/test_drag_trash.py -v
# С подробным выводом при ошибке
pytest homework_05/ -v --tb=long
Ожидаемый вывод
collected 2 items
test_iframe.py::test_iframe_text PASSED [ 50%]
test_drag_trash.py::test_drag_photo_to_trash PASSED [100%]
============================== 2 passed in 8.42s ==============================
Запуск через VS Code
- Открыть папку
homework_05в VS Code. - В левой панели нажать значок «Testing» (колба).
- Нажать «Configure Python Tests» → выбрать pytest → выбрать папку
homework_05. - Запустить все тесты нажатием кнопки «Run All Tests».
Отладка через F5 (launch.json)
Создайте файл .vscode/launch.json в корне проекта:
// .vscode/launch.json
{
"version": "0.2.0",
"configurations": [
{
"name": "pytest: ДЗ 5 — iframe",
"type": "debugpy",
"request": "launch",
"module": "pytest",
"args": ["homework_05/test_iframe.py", "-v", "-s"],
"justMyCode": false
},
{
"name": "pytest: ДЗ 5 — drag & drop",
"type": "debugpy",
"request": "launch",
"module": "pytest",
"args": ["homework_05/test_drag_trash.py", "-v", "-s"],
"justMyCode": false
}
]
}
Точки останова
- В
test_iframe.py: поставьте точку останова на строкеbrowser.switch_to.frame(iframe)и на строкеassert target_text in body.text— проверьте значениеbody.textв панели Variables. - В
test_drag_trash.py: поставьте точку останова послеactions.drag_and_drop(...).perform()— в панели Variables проверьтеremaining_photosиtrash_photos.
Типичные проблемы при запуске
Drag&drop не перемещает элемент: globalsqa использует jQuery UI. Если
drag_and_drop() не срабатывает, проверьте — возможно, нужно использовать JS-inject. Смотрите Ошибки → Ошибка 4.
iframe не найден: сайт может использовать
iframe.demo-frame или другой класс. Откройте DevTools (F12) и найдите нужный iframe вручную.