Python мануфактураJavaDesign Patterns для автоматизаторів

Терміни, нюанси та джерела

Приклад коду · 3:00

Instance state через self та __init__

page є instance attribute: кожен PageObject отримує власний стан через __init__, а method читає його через self.

Команда друкує Page: checkout і assertion проходить.

__init__, self, page та принципи ООП →

Практика · 0:00

Зібрати Page Object без довгоживучих WebElement

Створіть BasePage з wait-aware click() і type_text().
Збережіть локатори login page як tuple (By.CSS_SELECTOR, value).
Створіть предметний login() і перевірку success state.
Перерендерте один компонент у test page та переконайтеся, що дія повторно знаходить елемент за locator.
Тест читається через предметні Page Object methods і не використовує implicit wait або довгоживучі WebElement fields.

2. Selenium організація PageObject's та Очікувань →

Приклад коду · 0:00

Мінімальний Playwright Page Object із readiness check

Class name позначає page, methods описують actions, locators зберігаються в одному місці, а open завершується мінімальною readiness check.

Після open() test продовжується лише коли heading Sign in видимий; fill_email() приховує locator details від test code.

Неймінг та структура automation-проєкту →

Приклад коду · 10:03

Мінімальний Playwright pytest test

Показує sync API, injected page fixture, navigation і web-first assertion без залежності від мінливого повного title.

pytest знаходить один test і він проходить у Chromium.

2. Перший автотест на Python з Playwright →

Практика · 21:24

Створити file template для Page Object

Створіть custom file template з імпортом Page, класом, __init__, self.page і return self.
Використайте ${NAME} для назви створюваного класу або файла.
Створіть пробний Page Object і виправте всі syntax та inspection errors у самому шаблоні.
Новий Page Object створюється одним пунктом меню та не містить syntax або unresolved reference errors.

Майструємо IDE під себе →

Python мануфактура · Програма курсу · 7:54–10:03

Синхронний Playwright API і фікстура `page`

У курсі використовується синхронний API Playwright, щоб кроки тесту виконувалися послідовно без додаткової складності `async`/`await`. Фікстуру можна типізувати класом `Page`, а PyCharm імпортує потрібне ім’я через quick fix: ```python from playwright.sync_api import Page, expect def test_open_home_page(page: Page): ... ``` Важливо імпортувати `Page` і `expect` саме з `playwright.sync_api`, а не з асинхронного API.

2. Перший автотест на Python з Playwright →

Python мануфактура · Програма курсу · 21:24–27:20

File template для Page Object

Page Object і Page Component мають повторювану основу: імпорти Playwright, клас, `__init__`, збереження `page`, базову перевірку завантаження та часто `return self`. Замість копіювання цієї «шапки» створено власний шаблон у `Settings → Editor → File and Code Templates`. У file template змінна `${NAME}` підставляє назву, яку вводять під час створення файлу. Після збереження в меню `New` з’являється окремий тип `Page Object`; вибір цього пункту створює клас з підготовленими імпортами й методами. Під час live coding шаблон кілька разів виправляється: додаються пропущені `self`, закривається дужка, коригуються відступи. Це нормальний цикл налаштування: створити пробний файл, дочекатися синтаксичних та інспекційних підказок IDE, виправити шаблон і повторити генерацію. Перевіряти потрібно саме згенерований файл, а не лише текст у вікні налаштувань. Оскільки поточні Page Object і Page Component мають однакову основу, одного file template достатньо. Окремі шаблони варто додавати лише тоді, коли їхня структура реально розійдеться.

Майструємо IDE під себе →

Python мануфактура · Сесії: AMA та PMP · 6:00–8:16

Що зберігає Playwright `page`

Playwright `Page` представляє окрему вкладку або сторінку в browser context. Переданий у Page Object екземпляр визначає, з яким саме браузерним контекстом працюватимуть locators, переходи й assertions. Збереження `page` як `self.page` прибирає потребу передавати його в кожен метод. Залежність залишається явною в initializer, а всі дії конкретного Page Object використовують одну й ту саму вкладку.

__init__, self, page та принципи ООП →

Python мануфактура · Програма курсу · 10:03–13:12

Перехід на сторінку та перша перевірка

Тест відкриває сайт через `page.goto(...)`, після чого `expect(page).to_have_title(...)` перевіряє заголовок вкладки. `expect` виконує очікування протягом заданого тайм-ауту, тому така перевірка стійкіша за миттєве порівняння значень. ```python def test_open_home_page(page: Page): page.goto("https://testomat.io") expect(page).to_have_title("очікуваний заголовок") ``` Автодоповнення PyCharm шукає методи не лише за початком, а й за частиною назви. Методи з подвійними підкресленнями є службовими й у звичайному тесті не потрібні.

2. Перший автотест на Python з Playwright →

Python мануфактура · Програма курсу · 0:00–4:00

Від сирого сценарію до Page Object

Стартовий тест напряму викликає `driver.find_element()`, `WebDriverWait(...).until(...)` і браузерні дії. Він придатний для перевірки ідеї, але змішує бізнес-сценарій із технікою Selenium, тому наступний крок — дати діям читабельні назви й рознести їх по Page Objects. Замість Playwright `Page` у конструктор Page Object передається Selenium WebDriver. Спільний `BasePage` зберігає driver і один раз ініціалізує стандартне очікування, щоб кожен клас сторінки не дублював timeout та polling configuration. Найпрактичніше представлення локатора — tuple на кшталт `(By.CSS_SELECTOR, "...")`. Воно зберігає і стратегію, і значення пошуку та напряму сумісне з locator-based expected conditions.

2. Selenium організація PageObject's та Очікувань →

Python мануфактура · Програма курсу · 22:00–27:00

DRY: допоміжні функції без прихованих даних

Коли логін повторився у двох тестах, його винесено у `login_user(page, email, password)`. Дані не хардкодяться всередині helper-функції: тест передає `Page`, email і пароль явно. Type hints допомагають IDE підказувати доступні операції та помічати неправильні аргументи ще до запуску. Так само через Extract Method створюється `open_home_page(page)`. Допоміжні функції розміщуються нижче тестів, щоб під час code review спочатку читалися сценарії, а вже потім технічні деталі.

1. Рефакторинг та оптимізація, KISS, DRY, DAMP, YAGNI →

Python мануфактура · Програма курсу · 23:40–29:25

Передача `project_id` у page object

Тест викликає `api_client.get_projects()`, обирає цільовий проєкт і передає його `id` у метод `project_page.open_by_id()`. Це прибирає створення проєкту та пошук його URL через UI. Перші падіння спричинені не API, а неправильним типом fixture: замість авторизованої page повернувся context або вже закрита сторінка. Setup повинен передавати саме ту page, яку створив і авторизував, без другого `new_page()`.

3. API preconditions →

Python мануфактура · Програма курсу · 5:32–6:31

Page Object і component boundaries

`LoginPage.login(email, password)` ховає locators і послідовність fill/click за дією користувача. Великий product page можна розкласти на логічні components, наприклад product card або related products, якщо вони мають власну поведінку. Page Object не повинен ставати контейнером усієї test logic.

10 ооп →

Python мануфактура · Сесії: AMA та PMP · 6:00–9:30

OOP, патерни й ізоляція browser state

На базовому рівні потрібно розуміти primitives/value types, reference/object types, класи, об'єкти та принципи OOP. Із прикладних патернів найчастіше зустрічається Page Object; корисно впізнавати Singleton, Builder, Facade та інші рішення, але не впроваджувати їх без проблеми, яку вони реально спрощують. Page Factory виник навколо старих Selenium-підходів із lazy initialization елементів. Для сучасного Selenium або Playwright його не варто застосовувати за інерцією. У багатопоточному WebDriver framework кожен тест/worker повинен мати власний browser context або driver; спільний mutable driver спричиняє взаємний вплив тестів.

Що має вміти та знати мідл автоматизатор →

Python мануфактура · Програма курсу · 24:00–30:00

Shared page та очищення стану

Перші версії fixture щоразу відкривають нову вкладку або неправильно закривають page. Реалізацію уточнюють так, щоб параметризовані cases працювали на тій самій page, але перед новою ітерацією очищали cookies і local storage та поверталися у відомий початковий стан. Простого `localStorage.clear()` недостатньо для універсальної ізоляції: стан також може бути в session storage, IndexedDB, service workers або server-side session. Тому shared context має сенс лише тоді, коли перелік станів відомий і cleanup перевірений. Новий `BrowserContext` залишається надійнішою межею ізоляції.

2. Pytest fixtures, playwright fixture, прараметризація тестів →
Запитати в чаті про «page» →