🏠 Домашнее задание 4 — Ожидания в Selenium

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

📌 LMS: Auto QA: Домашнее задание 4 🔗 Связано с: Теория, Примеры

⚡ ДЗ 4 — кратко

Задание 1: Text Input — ввести "ITCH" → нажать кнопку → проверить изменение надписи.
Задание 2: Loading Images — дождаться загрузки → alt третьего изображения == "award".

Текст задания из LMS

Задание 1: Проверка изменения текста кнопки

Тестируемый сайт: http://uitestingplayground.com/textinput

Шаги теста:

  1. Перейдите на сайт Text Input.
  2. Введите в поле ввода текст "ITCH".
  3. Нажмите на синюю кнопку.
  4. Проверьте, что текст кнопки изменился на "ITCH".

Задание 2: Проверка загрузки изображений

Тестируемый сайт: https://bonigarcia.dev/selenium-webdriver-java/loading-images.html

Шаги теста:

  1. Перейдите на сайт Loading Images.
  2. Дождитесь загрузки всех изображений.
  3. Получите значение атрибута alt у третьего изображения.
  4. Убедитесь, что значение атрибута alt равно "award".

Подготовка окружения

1. Создайте папку и виртуальное окружение

# PowerShell
mkdir hw04
cd hw04

python -m venv .venv
.venv\Scripts\Activate.ps1

2. Установите зависимости

# PowerShell (виртуальное окружение активно)
pip install selenium webdriver-manager pytest

3. Создайте файлы тестов

# PowerShell
New-Item test_text_input.py
New-Item test_loading_images.py

4. Инициализируйте git (опционально)

git init
git add .
git commit -m "init: hw04 selenium waits"

Пошаговое решение — Задание 1: Text Input

Анализ страницы

На странице uitestingplayground.com/textinput:

  • Есть поле ввода — вводим текст "ITCH"
  • Есть синяя кнопка — нажимаем её
  • После нажатия текст кнопки меняется на введённое значение
  • Изменение текста кнопки может занять время → нужно явное ожидание

Шаг 1: Открываем DevTools и находим локаторы

Открываем Chrome DevTools (F12 или правой кнопкой → «Просмотр кода»):

  • Поле ввода: input#newButtonName (id="newButtonName")
  • Синяя кнопка: button#updatingButton (id="updatingButton")

Шаг 2: Пишем тест

# test_text_input.py
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from webdriver_manager.chrome import ChromeDriverManager
from selenium.webdriver.chrome.service import Service


@pytest.fixture
def driver():
    service = Service(ChromeDriverManager().install())
    driver = webdriver.Chrome(service=service)
    driver.get("http://uitestingplayground.com/textinput")
    yield driver
    driver.quit()


def test_button_text_change(driver):
    wait = WebDriverWait(driver, 10)

    # Находим поле ввода и вводим "ITCH"
    input_field = driver.find_element(By.ID, "newButtonName")
    input_field.clear()
    input_field.send_keys("ITCH")

    # Нажимаем на синюю кнопку
    button = driver.find_element(By.ID, "updatingButton")
    button.click()

    # Ждём, пока текст кнопки изменится на "ITCH"
    updated_button = wait.until(
        EC.text_to_be_present_in_element((By.ID, "updatingButton"), "ITCH")
    )

    # Проверяем, что текст кнопки изменился
    assert updated_button, "Текст кнопки не изменился на 'ITCH'!"

    # Дополнительная проверка — читаем актуальный текст элемента
    button_text = driver.find_element(By.ID, "updatingButton").text
    assert button_text == "ITCH", f"Ожидалось 'ITCH', получено '{button_text}'"

Объяснение логики

  • clear() — очищаем поле на случай, если в нём есть значение по умолчанию
  • send_keys("ITCH") — вводим нужный текст
  • EC.text_to_be_present_in_element — ждём, пока текст кнопки изменится на "ITCH". Это надёжнее, чем сразу читать .text
  • Двойная проверка: assert updated_button (булево значение EC) + assert button_text == "ITCH" (точное значение)

Пошаговое решение — Задание 2: Loading Images

Анализ страницы

На странице loading-images.html несколько изображений загружаются с задержкой. Нас интересует третье изображение и его атрибут alt.

Шаг 1: Стратегия ожидания

Нужно дождаться загрузки всех изображений. Признак загруженного изображения — у него есть атрибут src с реальным URL (не пустой и не placeholder). Используем visibility_of_element_located для изображений.

Шаг 2: Находим локатор третьего изображения

В DevTools смотрим: изображения находятся в контейнере #image-container или просто теги img внутри div. Локатор третьего: CSS img:nth-child(3) или XPath (//img)[3].

# test_loading_images.py
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from webdriver_manager.chrome import ChromeDriverManager
from selenium.webdriver.chrome.service import Service


@pytest.fixture
def driver():
    service = Service(ChromeDriverManager().install())
    driver = webdriver.Chrome(service=service)
    driver.get("https://bonigarcia.dev/selenium-webdriver-java/loading-images.html")
    yield driver
    driver.quit()


def test_third_image_alt(driver):
    wait = WebDriverWait(driver, 20)  # Изображения могут грузиться долго

    # Ждём, пока появится хотя бы один загруженный элемент
    # Признак завершения загрузки — появляется элемент с id="image-container"
    wait.until(EC.presence_of_element_located((By.ID, "image-container")))

    # Ждём, пока все 4 изображения станут видимыми
    # Проверяем третье изображение по порядку (3-й img внутри контейнера)
    third_image = wait.until(
        EC.visibility_of_element_located(
            (By.XPATH, "(//div[@id='image-container']//img)[3]")
        )
    )

    # Получаем значение атрибута alt у третьего изображения
    alt_value = third_image.get_attribute("alt")

    # Проверяем, что значение alt равно "award"
    assert alt_value == "award", f"Ожидалось 'award', получено '{alt_value}'"

Объяснение логики

  • Сначала ждём появление контейнера — это сигнал, что страница загрузила основную структуру
  • Затем XPath (//div[@id='image-container']//img)[3] — третье изображение внутри контейнера
  • visibility_of_element_located — ждём, пока изображение станет видимым (реально отображается на странице)
  • get_attribute("alt") — читаем значение атрибута alt после загрузки

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

Вариант 1: через терминал

# PowerShell: запуск всех тестов ДЗ
pytest test_text_input.py test_loading_images.py -v

# Запуск конкретного теста
pytest test_text_input.py::test_button_text_change -v

Вариант 2: через F5 (отладчик)

Создайте файл .vscode/launch.json в папке hw04/:

// .vscode/launch.json
{
  "version": "0.2.0",
  "configurations": [
    {
      "name": "pytest: text input",
      "type": "debugpy",
      "request": "launch",
      "module": "pytest",
      "args": ["test_text_input.py", "-v"],
      "console": "integratedTerminal",
      "cwd": "${workspaceFolder}"
    },
    {
      "name": "pytest: loading images",
      "type": "debugpy",
      "request": "launch",
      "module": "pytest",
      "args": ["test_loading_images.py", "-v"],
      "console": "integratedTerminal",
      "cwd": "${workspaceFolder}"
    }
  ]
}

После создания файла: выберите конфигурацию в панели Run and Debug (Ctrl+Shift+D) и нажмите F5.

Точки останова для отладки

Поставьте точку останова (F9) на строке после button.click() в Задании 1 или после первого wait.until в Задании 2. В режиме отладки можно в панели Variables смотреть значения переменных и в Debug Console выполнять команды Selenium.

Ожидаемый результат

collected 2 items

test_text_input.py::test_button_text_change PASSED      [ 50%]
test_loading_images.py::test_third_image_alt PASSED     [100%]

========================= 2 passed in 8.42s =========================

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

  • Задание 1 использует EC.text_to_be_present_in_element — разобран в Теории и в Примере 2 (AJAX)
  • Задание 2 использует EC.visibility_of_element_located и get_attribute() — разобраны в Теории и Справочнике
  • Оба задания используют паттерн: фикстура с WebDriverManager + WebDriverWait + конкретный EC — стандарт из лекции