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

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

Термін · 2:32

Load readiness check

Виняткова перевірка всередині Page Object, яка підтверджує, що правильна page та її critical elements готові до operations; business assertions залишаються в test code.

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

Приклад коду · 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-проєкту →

Java · Основний курс · 26:30–30:30

Page Object і проблема передавання драйвера

Login-сценарій переноситься до `LoginPage`: тест передає login і password, а Page Object виконує технічні дії з полями та кнопкою. Поширений варіант — передавати `WebDriver` у constructor кожного Page Object, але це повторює однакову залежність у тестах і сторінках. Для навчального врапера обирається централізований provider, з якого Page Objects отримуватимуть поточний драйвер без constructor plumbing. Водночас пакети розділяються за призначенням: web pages залишаються окремо від common-коду обгортки та від можливих API tests.

Selenium: очікування та мікрообгортки →

Java · Основний курс · 40:28–51:04

Assertions і побудова Page Object

Замість довгого `locator.waitFor` для очікуваного стану використовується динамічний Playwright assertion на `Locator`, наприклад перевірка видимості або тексту. Так очікування і причина падіння залишаються частиною перевірки, а не окремим технічним кроком. Для `HomePage`, `SignInPage`, `ProjectsPage` і сторінки окремого проєкту створюються Page Object-и. Кожен отримує спільний `Page` через constructor, зберігає дії на своїй сторінці та повертає наступний Page Object там, де сценарій переходить далі. Початковий лінійний тест рефакториться у послідовність доменних дій: відкрити home page, увійти, знайти проєкт, відкрити його й перевірити title. Це прибирає locator-и з тесту та залишає у ньому читабельний користувацький сценарій.

Playwright для Java: основи та поглиблення →

Java · Основний курс · 8:44–15:33

Page Object, пакети та доступність залежностей

Page Object визначається як клас, що описує логічну частину сторінки: цілу сторінку або окремий повторно використовуваний компонент. Для початкового варіанта кожна сторінка отримує окремий клас із діями, доступними користувачеві на ній. У `src/main/java` створюється окрема структура пакетів для вебчастини та сторінок. Після перенесення методу авторизації Selenide стає недоступним у production-коді, бо залежність оголошена через `testImplementation`; її змінюють на `implementation`, тоді як test runner залишається лише в тестовій області. Після синхронізації Gradle IntelliJ IDEA може додати потрібні імпорти через quick fix; невикористані імпорти потрібно регулярно прибирати.

Page Objects: рефакторинг тестів →

Java · Основний курс · 1:01:50–1:10:00

Дії, очікування та значення для перевірки

Дії та динамічні очікування переносяться в Page Object у порядку, в якому їх викликає сценарій. Перевірку точного тексту можна інкапсулювати методом, що приймає очікуване значення і використовує Selenide `shouldHave`. Це дозволяє Selenide чекати, доки елемент набуде потрібного стану. Якщо перевірка потребує довільної логіки, наприклад порівняння кількості тест-кейсів із порогом, Page Object повертає текст або оброблене значення, а assertion залишається в тесті. TestNG не переносять до `src/main/java`; production-частина отримує дані зі сторінки, тест явно формулює очікування. Викладач рекомендує динамічні очікування там, де це можливо, замість одноразового читання нестабільного UI.

Page Objects: рефакторинг тестів →

Java · Основний курс · 10:20–14:20

Fluent interface у Page Objects

Щоб будувати виклики через крапку, метод Page Object замість `void` повертає поточний тип і завершується `return this`. Так `open()` може повернути `SignInPage`, після чого одразу викликається `loginUser(...)`. У відео цей стиль пов'язують із назвами fluent interface та chain of invocation; у заголовку уроку також використано Chain of responsibility. Повернення `this` зручне для послідовності дій у межах одного Page Object. Повертати з кожного методу наступну сторінку викладач не радить: довгі ланцюжки приховують переходи й ускладнюють code review. Допустимий локальний виняток — компонент або popup, який належить поточній сторінці й природно стає наступним об'єктом взаємодії. Спільні значення, потрібні кільком тестам, переносяться до наявного `BaseTest`, а не дублюються. Для них обирається найвужча достатня видимість, у прикладі — `protected` для класів-нащадків.

Selenide: iframe, fluent interface та конфігурація →

Java · Основний курс · 1:16:02–1:25:30

Application facade і потокобезпечна ініціалізація

Щоб не створювати Page Object-и безпосередньо в кожному тесті, будується невеликий application facade. Він один раз приймає `Page`, створює `HomePage`, `SignInPage`, `ProjectsPage` та інші сторінки у правильному порядку й віддає їх тесту через короткі методи. Під час рефакторингу перевіряється момент ініціалізації: Page Object-и не можна створювати раніше, ніж JUnit integration надасть валідний `Page`. Після перенесення створення у constructor application object отримується стабільний lifecycle без повторюваних `new ...Page(page)` у тесті. У вбудованій Playwright JUnit implementation показано зберігання instances через `ThreadLocal`. Це дає окремі Playwright, Browser, BrowserContext і Page для кожного test thread; tracing lifecycle додатково враховує завершення, падіння або скасування тесту.

Playwright для Java: основи та поглиблення →

Java · Сесії: AMA та PMP · 0:00–2:32

Звідки брати назву Page Object

Першим джерелом назви сторінки є route: кореневий шлях підказує home page, а змістовний path — конкретний екран. Якщо це SPA або URL не змінюється, наступним джерелом стає видима назва сторінки: `h1`, `h2`, title чи інший семантичний заголовок. Коли framework генерує сторінку переважно з `div`, треба орієнтуватися на мову продукту та стабільні атрибути DOM. Мета — щоб назва в automation-коді відповідала тому, як екран уже називають користувачі й розробники.

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

Java · Основний курс · 1:16:56–1:19:00

Підсумок і практика іменування

Заняття підсумовує перехід від простого KISS-тесту, доповненого YAGNI, DRY і DAMP, до Page Object-структури з очікуваннями та двома способами перевірок: очікувати значення безпосередньо в об'єкті сторінки або повернути дані в тест для окремого порівняння. Для іменування класів, методів, змінних і тестів радять використовувати терміни, уже закладені розробниками: назви з URL, HTML та мережевих запитів, а також фактичні дії користувача. Наступні тести пропонується одразу писати через Page Object і вдосконалювати назви практикою.

Page Objects: рефакторинг тестів →

Java · Сесії: 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 спричиняє взаємний вплив тестів.

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

Java · Сесії: AMA та PMP · 3:00–6:00

`__init__` задає обов’язковий стан об’єкта

Через `__init__` клас отримує залежності й початковий стан, без яких його методи не мають сенсу. Наприклад, компонент приймає кореневий locator, а Page Object — Playwright `page`; наступні методи перевикористовують ці значення через `self`. У повсякденній мові `__init__` часто називають constructor. Технічно екземпляр створює `__new__`, а `__init__` ініціалізує вже створений об’єкт. Для звичайного Page Object достатньо реалізувати саме `__init__`.

__init__, self, page та принципи ООП →
Запитати в чаті про «Page Object» →