✅ Решения

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

⚡ Кратко

POM (4 страницы) + storage_state + проверки на шагах + parametrize + негативный кейс.

Часть 1. Ответы

  1. E2E проверяет весь путь пользователя и стыки страниц; проверка одного элемента — лишь маленький фрагмент.
  2. storage_state хранит cookies/localStorage; подставляется в browser_context_args, и тесты стартуют залогиненными.
  3. Чтобы при падении сразу видеть, на каком шаге сломалось, а не гадать.
  4. Через @pytest.mark.parametrize("product", [...]).
  5. Пустое обязательное поле доставки → проверяем сообщение об ошибке.

Часть 2. Страницы — эталон

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

class CartPage:
    def __init__(self, page: Page):
        self.page = page
        self.items = page.locator(".cart_item")
        self.checkout_btn = page.get_by_role("button", name="Checkout")

    def checkout(self):
        self.checkout_btn.click()
# pages/login_page.py
from playwright.sync_api import Page

class LoginPage:
    def __init__(self, page: Page):
        self.page = page

    def open(self):
        self.page.goto("https://www.saucedemo.com/")

    def login(self, user, pwd):
        self.page.get_by_placeholder("Username").fill(user)
        self.page.get_by_placeholder("Password").fill(pwd)
        self.page.get_by_role("button", name="Login").click()

Часть 3. Негативный сценарий — эталон

# tests/test_checkout_negative.py
from playwright.sync_api import expect
from pages.checkout_page import CheckoutPage

def test_empty_first_name(page, inventory_page):
    inventory_page.add_to_cart("Sauce Labs Backpack")
    inventory_page.go_to_cart()
    page.get_by_role("button", name="Checkout").click()

    # Continue без имени -> ошибка
    page.get_by_role("button", name="Continue").click()
    expect(page.locator("[data-test='error']")).to_contain_text("Error")
⚠️ Селекторы saucedemo (например [data-test='error']) проверяйте через codegen — могут отличаться. Важен подход: проверяем сообщение об ошибке через web-first expect.