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

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

Нюанс · 26:30

Дубльований responsive DOM — окрема причина неоднозначності

Прихований mobile block може залишатися в DOM разом із desktop block. Visibility не робить global locator унікальним; scope до правильного container має бути явним.

3. Селектори та пошук елементів →

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

Стабілізувати Selenium-сценарій

Створіть pytest fixture з webdriver.Chrome() і гарантованим quit() після тесту.
Відтворіть вхід і пошук проєкту через By.CSS_SELECTOR.
Замініть перевірки після переходів на WebDriverWait з visibility_of_element_located.
Навмисно зламайте один locator і переконайтеся, що падіння вказує на очікувану умову.
Тест проходить без sleep і падає з діагностичним TimeoutException, якщо цільовий locator неправильний.

1. Selenium початок, основи, фікстури →

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

Actionability і правильна область кліку

[Дивитися з 14:20](https://www.youtube.com/watch?v=6QdvE9DHOIY&t=860s). Перед дією Playwright перевіряє її передумови. Для `locator.click()` це, зокрема, strict resolution до одного елемента, visibility, stability, здатність отримувати pointer events і enabled state. Якщо умови не виконуються до завершення timeout, action завершується помилкою замість випадкового кліку. Візуальний текст усередині button не завжди є правильним click target: event listener може бути на батьківському element, а вкладений `span` — лише оформленням. Через це семантичний locator на кшталт `getByRole('button', { name: ... })` часто стабільніший за пошук найглибшого text node. Велика активна область також краща для користувача й доступності. Вибір між `click()` і touch-oriented `tap()` має залежати від реального input mode та context configuration, а не лише від розміру viewport.

Як Playwright взаємодіє з браузером через протокол →

Python мануфактура · Сесії: AMA та PMP · 0:00–4:40

Від публічного API до реалізації Locator

[Дивитися з 00:00](https://www.youtube.com/watch?v=6QdvE9DHOIY&t=0s). Playwright складається з багатьох частин: browser lifecycle, locators, actions, assertions, downloads, reporting і tracing. Щоб відповісти на питання «що відбувається під капотом», автор відкриває реалізацію `Locator`, а не обмежується документацією верхнього рівня. `Locator` зберігає frame і спосіб пошуку елемента, а додаткові умови на кшталт `has`, `hasText` чи visibility-related filters добудовують запит. У Python named arguments роблять таку композицію схожою на Builder без окремого builder class. Практичний висновок: перед створенням власного selector DSL варто перевірити вже наявні аргументи конструктора й методи locator API.

Як Playwright взаємодіє з браузером через протокол →

Java: архівні доповнення · 2:10–4:15

Публікація локального проєкту

Для локального проєкту використовується IDE action `Share Project on GitHub`: вказується назва repository та його visibility. Перед першим commit треба переглянути список файлів. `.idea`, логи та інші локальні артефакти не мають випадково потрапити до repository.

Публікація Java-проєкту на GitHub →

Python мануфактура · Сесії: AMA та PMP · 4:12–5:35

Перевіряємо готовність, а не ідеальність анімації

Не потрібно перевіряти кожен кадр анімації. Достатньо спостережуваного переходу: loader зник, skeleton замінився карткою, назва продукту видима, критична дія доступна. Уповільнення мережі в DevTools допомагає знайти реальні проміжні стани й вибрати правильний сигнал. Підсумкове правило: `isLoaded` описує те, що користувач очікує побачити перед продовженням роботи, і те, без чого тест не може виконувати наступну дію стабільно.

Що має описувати isLoaded →

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

Selenium WebDriver, explicit waits і ширша matrix

Selenium 4 використовує стандартизований W3C WebDriver protocol. Client binding надсилає HTTP-команди WebDriver endpoint, а browser-specific driver виконує їх у Chrome, Firefox, Edge, Safari чи іншому підтримуваному браузері. У старішому Selenium 3 застосовувався JSON Wire Protocol. У класичному Selenium flow перед click або input часто використовується explicit wait: client повторно перевіряє умову на кшталт visibility або clickability, а після її виконання надсилає окрему action command. Це створює більше round trips, особливо коли browser session віддалена. Сильна сторона Selenium — широка екосистема vendor drivers і remote providers. Якщо навіть невелика частка користувачів певного браузера означає сотні тисяч людей або браузер входить у договірну support matrix, таке покриття не можна відкидати лише через повільніший test run. У Python-проєкті технічно можна мати і Playwright, і Selenium tests під pytest: Playwright для основного functional suite, Selenium — для вузької cross-browser перевірки. Це виправдано лише реальною вимогою, бо два automation stacks подвоюють dependency, fixture та maintenance surface.

3. Selenium vs Playwright - яка різниця →

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

Wait-aware дії в `BasePage`

У `BasePage` демонструються helpers для `open`, `refresh`, `find`, `find_all`, `click` і введення тексту. Перед дією helper чекає потрібний стан: visibility для введення або clickability для кліку. Так exception вказує на невиконану передумову, а не на випадковий наступний Selenium command. `send_keys()` вводить символи та може передавати спеціальні клавіші на кшталт Enter або Tab. На відміну від високорівневого fill у Playwright, він не гарантує очищення поля, тому `clear()` додається лише там, де сценарій справді починає з порожнього input. Не варто приховувати `clear()` у кожному введенні «про запас». Тест має явно задавати стартовий стан: іноді потрібен refresh, бо попередня невдала авторизація залишила validation message або інший стан, який просте очищення полів не скидає.

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

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

Application object і поступова міграція

`send_keys()` використовується не лише для тексту: file input можна передати шлях до локального файлу, після чого браузер виконає upload. У такому спеціальному сценарії взаємодія з невидимим input може бути виправдана, тому generic helper не повинен безумовно вимагати visibility для кожної операції. Application object може один раз ініціалізувати всі Page Objects і дати тестам єдину точку доступу. Це прибирає повторну ініціалізацію з кожного тесту; обсяг статичних селекторів у пам’яті тут не є практичною проблемою. Той самий контейнер дозволяє поступово переводити Python-suite із Selenium на Playwright: старі Page Objects продовжують працювати, нові сценарії отримують Playwright implementation. Переписувати весь набір одразу не потрібно, особливо коли корисні API/database fixtures уже живуть у цьому pytest-проєкті.

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

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

Чому implicit wait недостатньо

Перед аналізом очікувань виправляється ще одна причина падіння: регістр символів і точне значення атрибута мають збігатися з DOM. Це нагадування не списувати кожен `NoSuchElementException` на повільну сторінку — спочатку слід перевірити сам локатор. `driver.implicitly_wait(10)` задає загальний час очікування для пошуку елементів. Такий механізм може дочекатися присутності вузла в DOM, але не виражає конкретний стан: елемент може існувати, залишаючись невидимим або недоступним для кліку. Для сучасних динамічних сторінок урок рекомендує не покладатися на implicit wait. Тесту потрібна конкретна умова — visibility, clickability, selected state або зникнення — у конкретному місці сценарію.

1. Selenium початок, основи, фікстури →

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

`WebDriverWait` та `expected_conditions`

Явне очікування створюється як `WebDriverWait(driver, timeout, poll_frequency=...)`. Timeout задає верхню межу, а `poll_frequency` — інтервал повторної перевірки. Значення треба підбирати без надмірного polling: частіші запити не лікують повільний продукт і можуть додати зайве навантаження браузеру. Метод `until()` приймає конкретну умову з `selenium.webdriver.support.expected_conditions`, яку часто імпортують як `EC`. Серед типових умов: `visibility_of_element_located`, `element_to_be_clickable`, presence, invisibility і selected state. До `WebDriverWait` можна передати ignored exceptions, наприклад `NoSuchElementException` або `StaleElementReferenceException`. Проте це працює лише тоді, коли пошук виконується всередині condition; якщо `find_element()` викликати раніше під час формування аргументу, exception виникне ще до старту polling.

1. Selenium початок, основи, фікстури →

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

Locator замість завчасно знайденого `WebElement`

`find_element()` є eager operation: команда одразу йде до WebDriver. Тому конструкція на кшталт `EC.visibility_of(driver.find_element(...))` не захищає від раннього `NoSuchElementException` — елемент уже намагалися знайти. Для елемента, який ще має з’явитися, використовується `EC.visibility_of_element_located((By.CSS_SELECTOR, selector))`. Condition отримує locator tuple і сам повторює пошук до успіху або timeout. Збереження `By.CSS_SELECTOR` у tuple також зменшує ризик переплутати тип локатора зі звичайним рядком. Різниця принципова: `is_displayed()` робить одне звернення до стану вже знайденого element ID, тоді як explicit wait повторює перевірку. Саме тому очікування треба прив’язувати до спостережуваного стану, а не просто додавати після будь-якого пошуку.

1. Selenium початок, основи, фікстури →
Запитати в чаті про «visibility» →