← Java

Конспект і таймкоди

0:00

WebDriver і двостороння модель Playwright

Selenium виконує команди через WebDriver: тест звертається до драйвера HTTP-запитами, а драйвер керує браузером. Перевірки стану та explicit waits багаторазово опитують браузер, тому на віддаленому запуску через BrowserStack або іншу інфраструктуру network latency відчутно сповільнює тести й змушує змінювати polling interval.

Playwright підтримує постійний двосторонній зв'язок із браузером і отримує результат виконаної команди через WebSocket. У відео це подається як причина меншої кількості мережевих затримок, кращої поведінки на remote execution і можливості працювати з Chromium, Firefox та WebKit через спільний API.

6:48

Auto-waiting і динамічні assertions

Перед діями Playwright автоматично перевіряє actionability елемента: видимість, стабільність, можливість отримувати події та, залежно від операції, enabled або editable. Через це для звичайних click, fill, hover чи drag-and-drop не потрібно вручну дублювати очікування, типові для Selenium.

Вбудовані Playwright assertions також повторюють перевірку до timeout, тому в них потрібно передавати Locator, а не вже отримане статичне значення. Автор називає сторінку документації про auto-waiting ключовою та застерігає від бездумного додавання waitFor перед кожною дією.

11:05

Підключення Playwright до Java-проєкту

Залежність com.microsoft.playwright знаходиться через Maven repository і додається у build.gradle; для Maven-проєкту потрібно обрати відповідний dependency snippet. Після синхронізації імпорт перевіряється через External Libraries, а сам тест створюється як JUnit test у пакеті Playwright.

Показано також конвертацію невеликого Selenium/Selenide прикладу в Playwright за допомогою LLM. Такий інструмент доречний для локального рефакторингу або перенесення синтаксису між мовами й бібліотеками, але початківцю все одно важливо самостійно писати код і вміти знаходити документацію.

Прямий Java API вимагає явно створити Playwright, BrowserType, Browser і Page. Нову вкладку створюють через browser context, тому автор вважає базовий API низькорівневішим за Selenide та радить згодом сховати повторювану ініціалізацію.

20:02

Перший тест і strict locator semantics

У перенесеному тесті навігація виконується через page.navigate, пошук — через page.locator, а перевірка — через Playwright assertions. Тест запускається у браузері й успішно проходить після коригування локатора.

Playwright locator може описувати кілька DOM-вузлів, але операція, що очікує один елемент, завершується помилкою strict mode. На відміну від Selenium findElement, який із множини повертає перший збіг, у Playwright потрібно зробити locator унікальним або явно вибрати first; правило стосується і дій, і assertions.

25:15

Стратегії пошуку та accessibility locators

Playwright пропонує getByRole, getByLabel, getByText, getByPlaceholder та інші user-facing locator-и. getByRole спирається на accessibility semantics і допомагає перевіряти, чи інтерфейс коректно описує кнопки, поля та таблиці для screen reader; особливо зручним такий пошук може бути для рядків і колонок таблиці.

Автор водночас застерігає, що role-based locator-и іноді складніше читати й діагностувати команді. Для більшості проєктів він радить обирати найпростіший стабільний CSS selector або узгоджений data attribute, а accessibility locator використовувати там, де він справді дає читабельний і надійний контракт.

API портів Playwright загалом однаковий у Java, Python, C# і TypeScript. Практична перевага TypeScript-версії в тому, що власний Playwright Test runner автоматично надає готовий Page; у Java lifecycle потрібно організувати через JUnit або власну обгортку.

31:44

JUnit 5 extension і lifecycle браузера

Щоб не створювати чотири Playwright instances у кожному тесті, демонструється JUnit 5 extension із BeforeAllCallback і AfterAllCallback. Він запускає Playwright і браузер перед тестами класу, надає Page, а після виконання закриває ресурси у зворотному порядку.

Перша спроба взяти Page зі static field у тесті дає порожнє значення, бо static initialization відбувається раніше за callback extension. Виправлення — зберігати Page всередині extension і отримувати його методом уже після запуску lifecycle.

На локальному headed-запуску Playwright контролює браузер так, що звичайний рух курсора не перехоплює тестові дії. Це протиставляється Selenium, де взаємодія користувача з тим самим браузером може змінити focus і зламати сценарій.

40:28

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

Замість довгого locator.waitFor для очікуваного стану використовується динамічний Playwright assertion на Locator, наприклад перевірка видимості або тексту. Так очікування і причина падіння залишаються частиною перевірки, а не окремим технічним кроком.

Для HomePage, SignInPage, ProjectsPage і сторінки окремого проєкту створюються Page Object-и. Кожен отримує спільний Page через constructor, зберігає дії на своїй сторінці та повертає наступний Page Object там, де сценарій переходить далі.

Початковий лінійний тест рефакториться у послідовність доменних дій: відкрити home page, увійти, знайти проєкт, відкрити його й перевірити title. Це прибирає locator-и з тесту та залишає у ньому читабельний користувацький сценарій.

51:04

Debugger, recorder і внутрішній transport

page.pause() зупиняє виконання й відкриває Playwright Inspector. У ньому можна покроково продовжувати тест, бачити підсвічений цільовий елемент, записувати дії та отримувати згенерований код для Java/JUnit або інших підтримуваних мов.

Pick locator допомагає знайти елемент і пропонує locator на основі placeholder, role, label чи іншого доступного сигналу. Результат recorder-а є стартовою точкою: згенерований locator потрібно перевірити на унікальність, читабельність і стабільність перед перенесенням у Page Object.

Під час переходу в реалізацію Java API показано, що Playwright формує protocol message, передає його transport-ом через WebSocket, отримує результат і перетворює помилку або timeout на Playwright exception. Це пояснює, як Java-обгортка пов'язана з командами, які фактично виконує браузер.

1:00:02

Уточнення locator-ів і складні CSS-можливості

Для assertions слід використовувати API, що повертає Locator: locator(...), getByRole(...), getByText(...) та споріднені методи. У документації Playwright пріоритет надається user-facing locator-ам, але відео рекомендує не перетворювати це на механічне правило й підбирати locator за реальним DOM та потребами команди.

Playwright розширює CSS-пошук перевірками тексту, видимості й відносного розташування, однак надто складні конструкції та XPath ускладнюють підтримку. Якщо стабільного сигналу немає, краще домовитися з розробниками про data attribute; getByTestId фактично є зручною обгорткою над таким контрактом.

1:05:26

Tracing і готовий JUnit integration

Tracing записує кроки тесту, screenshots, console logs, network requests і додатковий контекст виконання. Ручна реалізація потребує browser context, запуску tracing перед тестом і збереження archive після нього.

Замість власного extension демонструється експериментальна на момент відео JUnit integration з @UsePlaywright, яка інжектить Page. Для параметризації створюється клас, що реалізує OptionsFactory: через нього задаються headed/headless mode, base URL, tracing policy, browser launch options та інші параметри.

За замовчуванням запускається Chromium build Playwright. Через browser channel можна обрати встановлений Google Chrome, а slowMo додає паузу між операціями, що корисно для демонстрації або візуального аналізу швидкого тесту.

1:13:18

Аналіз прогону у Trace Viewer

Після прогону tracing створює ZIP archive. Автор не радить завантажувати внутрішні дані застосунку в online Trace Viewer; локально archive відкривається командою npx playwright show-trace <path>, для чого на машині має бути встановлений Node.js Playwright package.

Trace Viewer показує стан before/after для кожної дії, screenshots, snapshot сторінки та network requests. Завдяки цьому trace може бути основним діагностичним артефактом CI-прогону й давати значно більше контексту, ніж звичайний screenshot після падіння.

1:16:02

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 додатково враховує завершення, падіння або скасування тесту.

1:25:30

Очікування network events і API mocking

Playwright може чекати завершення request або появи response під час конкретної дії. У власній обгортці автора це оформлено як clickWithWaitForRequestFinished: всередині викликається Playwright network wait, а дія click передається callback-ом.

У документації також показані перехоплення request/response, route і fulfill, тобто можливість змінити або підмінити API response. У відео ці приклади не реалізуються повністю: головна мета — показати доступний механізм і запропонувати дослідити його в домашній роботі.

Network wait корисний не лише для синхронізації UI, а й для перевірки analytics чи інших events, що мають бути відправлені після кліку. Автор радить зберігати однаковий читабельний порядок у тестах — дія, а потім очікуваний результат — навіть якщо базовий API описує wait до callback-дії.

1:30:38

Межі низькорівневого API й options окремих дій

Playwright має API для keyboard shortcuts через page.keyboard().press(...), WebSocket events і mocking. Водночас автору бракує ланцюжків на кшталт «динамічно дочекайся тексту, а потім клікни цей самий елемент», тому у власній бібліотеці він додає коротші chainable operations.

Окремі actions та assertions приймають options objects. Для конкретної перевірки можна змінити timeout; FillOptions і подібні об'єкти дозволяють задати власний timeout або force. force обходить частину actionability checks і потрібен лише як виняток для проблемного frontend, а не як стандартний спосіб виправляти тести.

1:35:21

Практичні висновки й домашня робота

Playwright рекомендується як швидша й зручніша основа для UI automation, особливо на remote execution. У Java повторювану ініціалізацію можна прибрати через JUnit integration, Page Object-и та невелику application facade, а стабільність дій забезпечують auto-waiting і динамічні assertions.

Для домашньої роботи потрібно переписати на Playwright наявний Selenium-сценарій, налаштувати browser options, увімкнути tracing, відкрити trace локально та використати page.pause() або recorder для налагодження. Згенеровані recorder-ом кроки слід переносити вибірково й узгоджувати locator strategy в межах команди.

getByRole додатково перевіряє accessibility semantics сторінки: сучасні Angular і React components мають формувати ролі та ARIA attributes, які screen reader розпізнає як кнопку, поле введення чи інший control. Для колекцій strict locator semantics складніша, тому в більшості дій варто будувати locator, що знаходить один конкретний елемент.