🏠 Домашнее задание 5

← К оглавлению урока

📋 2 задания 🎯 Сложность: Средняя

⚡ Суть ДЗ

  • Задание 1: Найти iframe, переключиться в него, проверить наличие текста
  • Задание 2: Перетащить фото в корзину (drag&drop), проверить счётчики
  • Концепции: switch_to.frame(), default_content(), ActionChains.drag_and_drop()

Условие задания (из LMS)

Задание 1: Проверка наличия текста в iframe
  1. Открыть страницу: https://bonigarcia.dev/selenium-webdriver-java/iframes.html
  2. Проверить наличие текста:
    • Найти фрейм (iframe), в котором содержится искомый текст.
    • Переключиться в этот iframe.
    • Найти элемент, содержащий текст "semper posuere integer et senectus justo curabitur."
    • Убедиться, что текст отображается на странице.
Задание 2: Тестирование Drag & Drop (перетаскивание изображения в корзину)
  1. Открыть страницу Drag & Drop Demo: https://www.globalsqa.com/demo-site/draganddrop/
  2. Выполнить следующие шаги:
    • Захватить первую фотографию (верхний левый элемент).
    • Перетащить её в область корзины (Trash).
    • Проверить, что после перемещения:
      • В корзине появилась одна фотография.
      • В основной области осталось 3 фотографии.
  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()

Связь с теорией

Пошаговое решение — Задание 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()

Связь с теорией

Запуск и проверка

Запуск в терминале (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

  1. Открыть папку homework_05 в VS Code.
  2. В левой панели нажать значок «Testing» (колба).
  3. Нажать «Configure Python Tests» → выбрать pytest → выбрать папку homework_05.
  4. Запустить все тесты нажатием кнопки «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 вручную.