📖 Теория: POM, фикстуры, трассировка

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

⚡ Суть

  • POM: класс страницы хранит page и Locator-ы, методы = сценарии.
  • Фикстура page уже изолирована (свежий контекст на тест) — параллелить безопасно.
  • browser_context_args и --base-url настраивают окружение централизованно.
  • Трассировка retain-on-failure + show-trace — лучший инструмент отладки.

Page Object Model на Playwright

Идея та же, что в уроке 11: каждая страница — класс, локаторы хранятся в одном месте, тесты вызывают методы. Отличие — вместо driver.find_element используются Locator-ы, объявленные в конструкторе.

# pages/login_page.py
from playwright.sync_api import Page

class LoginPage:
    def __init__(self, page: Page):
        self.page = page
        self.username = page.get_by_placeholder("Username")
        self.password = page.get_by_placeholder("Password")
        self.login_btn = page.get_by_role("button", name="Login")

    def open(self):
        self.page.goto("/")          # относительный путь — работает с base_url

    def login(self, user: str, pwd: str):
        self.username.fill(user)
        self.password.fill(pwd)
        self.login_btn.click()
💡 На заметку: локаторы — «ленивые», поэтому их можно объявить в __init__ один раз, даже до загрузки страницы. Реальный поиск произойдёт при действии.

Фикстуры pytest-playwright

Плагин даёт готовые фикстуры. Главное — они изолируют тесты: на каждый тест создаётся свежий context и page.

ФикстураНазначение
pageВкладка (на каждый тест новая)
contextИзолированная сессия теста
browserБраузер (на всю сессию)
browser_context_argsНастройки контекста (viewport, locale, storage_state…)
# conftest.py
import pytest

@pytest.fixture(scope="session")
def browser_context_args(browser_context_args):
    return {**browser_context_args, "viewport": {"width": 1440, "height": 900}}

# своя фикстура страницы логина
@pytest.fixture
def login_page(page):
    from pages.login_page import LoginPage
    return LoginPage(page)

Базовый URL задаётся флагом --base-url (тогда в коде — относительные пути page.goto("/inventory")).

Трассировка и отладка

Trace — это запись всего прогона: снимки DOM на каждом шаге, действия, сеть, консоль. Открывается в Trace Viewer.

# записывать трассировку только для упавших тестов
pytest --tracing=retain-on-failure

# открыть результат
playwright show-trace test-results/.../trace.zip

Также доступны --video=retain-on-failure и --screenshot=only-on-failure.

Совет: в CI всегда включайте retain-on-failure и сохраняйте папку артефактов — по трассировке падение чинится за минуты.

Параллельный запуск

Так как тесты изолированы контекстами, их легко гонять параллельно через pytest-xdist:

pip install pytest-xdist
pytest -n auto        # по числу ядер
pytest -n 4           # 4 воркера

Условие — тесты независимы (не делят глобальное состояние, не зависят от порядка).

Мостик к API: APIRequestContext

Playwright умеет ходить в REST API без браузера — удобно готовить данные для UI-теста или проверять результат через API.

# подготовить данные через API, проверить в UI
def test_setup_via_api(api_request_context, page):
    api_request_context.post("/issues", data={"title": "Bug"})
    page.goto("/issues")
    expect(page.get_by_text("Bug")).to_be_visible()
⚠️ Имена флагов и API-методов зависят от версии — сверяйтесь с документацией плагина и API testing.