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

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

⚡ ДЗ 3: тест навигации itcareerhub.de

Написать автотест на Python/pytest, который открывает https://itcareerhub.de/ru, проверяет наличие элементов навигации, кликает «Контакты», кликает «Обратный звонок» и проверяет текст во всплывающем окне.

Файл: tests/test_itcareerhub.py. Запуск: python -m pytest tests/ -v.

Задание из LMS (оригинальный текст)

Auto QA: Домашнее задание 3

Написать автотест с использованием Python и Pytest, который:

  1. Открывает https://itcareerhub.de/ru
  2. Проверяет, что на странице отображаются:
    • Логотип ITCareerHub
    • Ссылка «Программы»
    • Ссылка «Способы оплаты»
    • Ссылка «О нас»
    • Ссылка «Контакты»
    • Ссылка «Отзывы»
    • Ссылка «Блог»
    • Кнопки переключения языка (ru и de)
  3. Кликнуть по разделу «Контакты»
  4. Кликнуть по кнопке «Обратный звонок»
  5. Проверить, что текст «Запишитесь на бесплатную карьерную консультацию» отображается во всплывающем окне

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

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

# Windows PowerShell — в папке вашего проекта
python -m venv venv
.\venv\Scripts\Activate.ps1

# Проверка активации (в начале строки появится (venv))
python --version

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

# Установка selenium и pytest
pip install selenium pytest

# Проверка
pip list | Select-String "selenium"
pip list | Select-String "pytest"

3. Структура проекта

hw3/
├── venv/
├── conftest.py
└── tests/
    └── test_itcareerhub.py

4. Исследуйте страницу через DevTools

Откройте itcareerhub.de/ru в Chrome, нажмите F12 и найдите:

  • Логотип — обычно <img> или <svg> с классом, связанным с «logo»
  • Ссылки навигации — теги <a> с текстом «Программы», «Контакты» и т.д.
  • Кнопки языка — элементы с текстом «ru» и «de»
  • Кнопку «Обратный звонок» — ищите <button> или <a> с этим текстом (появляется после клика по «Контакты»)
  • Текст во всплывающем окне — модальный элемент с нужным текстом
Важно: структура HTML на реальном сайте может меняться. Ниже показан подход с рекомендуемыми стратегиями локаторов — используйте DevTools для уточнения конкретных значений.

Пошаговое решение

Шаг 1: conftest.py — фикстура с настройками

# conftest.py
import pytest
from selenium import webdriver
from selenium.webdriver.chrome.options import Options

@pytest.fixture
def driver():
    """Фикстура: запуск Chrome, открытие страницы, закрытие после теста."""
    options = Options()
    # options.add_argument("--headless")  # раскомментировать для фонового режима
    options.add_argument("--window-size=1920,1080")

    driver = webdriver.Chrome(options=options)
    driver.get("https://itcareerhub.de/ru")
    driver.implicitly_wait(5)  # неявное ожидание 5 секунд
    yield driver
    driver.quit()

Шаг 2: тест — проверка логотипа

# tests/test_itcareerhub.py
from selenium.webdriver.common.by import By

def test_logo_is_displayed(driver):
    """Логотип ITCareerHub отображается на странице."""
    # Ищем изображение-логотип по частичному совпадению alt или src
    # Уточните локатор через DevTools на реальной странице
    logo = driver.find_element(By.CSS_SELECTOR, "[class*='logo'] img, img[alt*='ITCareerHub'], img[alt*='Career']")
    assert logo.is_displayed(), "Логотип не отображается"
Локаторы для логотипа и кнопок зависят от реальной вёрстки сайта. Используйте DevTools (F12 → Elements → Ctrl+F) для нахождения точных селекторов. Пример показывает подход — атрибут alt изображения или класс-контейнера.

Шаг 3: тест — проверка ссылок навигации

# tests/test_itcareerhub.py
from selenium.webdriver.common.by import By

def test_navigation_links_displayed(driver):
    """Все ссылки навигации отображаются на странице."""
    nav_links = [
        "Программы",
        "Способы оплаты",
        "О нас",
        "Контакты",
        "Отзывы",
        "Блог",
    ]
    for link_text in nav_links:
        # By.LINK_TEXT ищет точный текст ссылки <a>
        link = driver.find_element(By.LINK_TEXT, link_text)
        assert link.is_displayed(), f"Ссылка '{link_text}' не отображается"

Шаг 4: тест — кнопки переключения языка

# tests/test_itcareerhub.py
def test_language_buttons_displayed(driver):
    """Кнопки переключения языка (ru и de) отображаются."""
    # Найдите кнопки языка через DevTools — они могут быть <a> или <button>
    # Пример с LINK_TEXT:
    lang_ru = driver.find_element(By.LINK_TEXT, "ru")
    lang_de = driver.find_element(By.LINK_TEXT, "de")
    assert lang_ru.is_displayed(), "Кнопка 'ru' не отображается"
    assert lang_de.is_displayed(), "Кнопка 'de' не отображается"

Шаг 5: тест — клик по «Контакты» и «Обратный звонок»

# tests/test_itcareerhub.py
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_callback_modal(driver):
    """Клик по 'Контакты', затем 'Обратный звонок' — всплывающее окно с нужным текстом."""

    # 1. Кликнуть по разделу «Контакты»
    contacts_link = driver.find_element(By.LINK_TEXT, "Контакты")
    contacts_link.click()

    # 2. Дождаться появления кнопки «Обратный звонок»
    # (страница может скроллиться или элемент появляется после анимации)
    wait = WebDriverWait(driver, 10)
    callback_btn = wait.until(
        EC.element_to_be_clickable((By.XPATH, "//*[contains(text(), 'Обратный звонок')]"))
    )

    # 3. Кликнуть по кнопке «Обратный звонок»
    callback_btn.click()

    # 4. Дождаться появления модального окна с нужным текстом
    modal_text = wait.until(
        EC.visibility_of_element_located(
            (By.XPATH, "//*[contains(text(), 'Запишитесь на бесплатную карьерную консультацию')]")
        )
    )

    # 5. Проверить текст
    assert modal_text.is_displayed(), \
        "Текст 'Запишитесь на бесплатную карьерную консультацию' не отображается"

Полный тест-файл

# tests/test_itcareerhub.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_logo_is_displayed(driver):
    """Логотип ITCareerHub отображается."""
    logo = driver.find_element(
        By.CSS_SELECTOR, "[class*='logo'] img, img[alt*='Career']"
    )
    assert logo.is_displayed(), "Логотип не отображается"


def test_navigation_links_displayed(driver):
    """Все ссылки навигации отображаются."""
    nav_links = ["Программы", "Способы оплаты", "О нас", "Контакты", "Отзывы", "Блог"]
    for link_text in nav_links:
        link = driver.find_element(By.LINK_TEXT, link_text)
        assert link.is_displayed(), f"Ссылка '{link_text}' не отображается"


def test_language_buttons_displayed(driver):
    """Кнопки переключения языка отображаются."""
    lang_ru = driver.find_element(By.LINK_TEXT, "ru")
    lang_de = driver.find_element(By.LINK_TEXT, "de")
    assert lang_ru.is_displayed(), "Кнопка 'ru' не отображается"
    assert lang_de.is_displayed(), "Кнопка 'de' не отображается"


def test_callback_modal(driver):
    """Клик 'Контакты' → 'Обратный звонок' → всплывающее окно."""
    wait = WebDriverWait(driver, 10)

    # Клик по «Контакты»
    contacts_link = driver.find_element(By.LINK_TEXT, "Контакты")
    contacts_link.click()

    # Ожидание и клик «Обратный звонок»
    callback_btn = wait.until(
        EC.element_to_be_clickable(
            (By.XPATH, "//*[contains(text(), 'Обратный звонок')]")
        )
    )
    callback_btn.click()

    # Проверка текста во всплывающем окне
    modal_text = wait.until(
        EC.visibility_of_element_located((
            By.XPATH,
            "//*[contains(text(), 'Запишитесь на бесплатную карьерную консультацию')]"
        ))
    )
    assert modal_text.is_displayed(), \
        "Текст 'Запишитесь на бесплатную карьерную консультацию' не найден"

Проверка в VS Code

Запуск через терминал

# Убедитесь, что venv активирован
.\venv\Scripts\Activate.ps1

# Запуск всех тестов с подробным выводом
python -m pytest tests/ -v

# Ожидаемый вывод:
# tests/test_itcareerhub.py::test_logo_is_displayed PASSED
# tests/test_itcareerhub.py::test_navigation_links_displayed PASSED
# tests/test_itcareerhub.py::test_language_buttons_displayed PASSED
# tests/test_itcareerhub.py::test_callback_modal PASSED
# 4 passed in X.XXs

Запуск через F5 в VS Code (launch.json)

// .vscode/launch.json
{
    "version": "0.2.0",
    "configurations": [
        {
            "name": "pytest: ДЗ3",
            "type": "debugpy",
            "request": "launch",
            "module": "pytest",
            "args": ["tests/test_itcareerhub.py", "-v"],
            "cwd": "${workspaceFolder}",
            "console": "integratedTerminal",
            "justMyCode": false
        }
    ]
}

После создания файла нажмите F5 — откроется браузер, тесты запустятся, результат появится в панели Debug Console.

Отладка с точками останова

  1. Откройте tests/test_itcareerhub.py в VS Code
  2. Кликните на номер строки слева от contacts_link.click() — появится красная точка
  3. Нажмите F5 для запуска в режиме отладки
  4. Когда выполнение остановится на точке, в панели Variables вы увидите переменные
  5. F10 — следующий шаг; F5 — продолжить до следующей точки

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

  • By.LINK_TEXT — стратегия поиска ссылок по точному тексту. Подробнее: theory.html, commands.html
  • By.XPATH с contains(text(),...) — поиск по частичному тексту. Примеры: examples.html
  • is_displayed() — проверка видимости. Объяснение: theory.html
  • WebDriverWait + expected_conditions — явные ожидания для динамических элементов. Тема будет подробнее в уроке 07.
Совет: если тест для логотипа падает с NoSuchElementException, откройте DevTools, нажмите Ctrl+F в панели Elements и введите CSS-селектор или XPath, чтобы проверить его прямо в браузере, без запуска Python.