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

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

Практика · 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 та Очікувань →

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

Явне очікування видимого елемента

Locator передається всередину expected condition, тому кожна спроба polling може повторно знайти актуальний DOM-вузол.

Повертається видимий WebElement або після 10 секунд виникає TimeoutException.

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

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

Locator, `WebElement` або рядок

На Python-проєктах можна зустріти три підходи: зберігати locator tuple, лише CSS/XPath-рядок або вже знайдений `WebElement`. Рядок коротший, але не містить тип пошуку; `WebElement` зручний лише поки DOM-вузол не перерендерився; locator дає змогу безпечно виконувати повторний пошук. Якщо helper має приймати і locator, і `WebElement`, це можна відобразити union type та всередині визначити потрібну expected condition. Така гнучкість виправдана лише коли обидва представлення реально використовуються; для нового коду один locator-based контракт простіший. Wait helper отримує default timeout, але дозволяє локально передати довший для справді повільної операції. Page Object може застосовувати Loadable Component approach: сторінка вважається готовою лише після появи її ключових елементів, наприклад email і password inputs.

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

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

Lazy `WebElement` через `@property`

Другий поширений варіант Page Object — оголошувати element getter як метод із `@property`. З тесту він виглядає як поле, але `find_element()` виконується лише під час звернення. Це відкладає пошук і зменшує ризик зберегти element reference надто рано. Через property можна викликати `clear()`, `send_keys()`, `click()` або читати `is_selected()`. Для дії, яка потребує очікування, все одно краще мати окремий метод: property не перетворює Selenium на lazy locator і сама по собі не додає retry. Якщо агент або IDE має працювати з незнайомою бібліотекою, урок радить дати йому локальний source code як контекст. Це допомагає звірити реальні методи та актуальну реалізацію замість вигадування API за пам’яттю.

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

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 початок, основи, фікстури →

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

Вартість polling і `StaleElementReferenceException`

WebDriver перевіряє стани елементів через браузер і JavaScript. Надто частий polling може впливати на сторінку, яку тест вимірює, особливо якщо UI одночасно виконує важку клієнтську логіку. Тому частоту й timeout варто тримати розумними, а кількість UI-тестів — достатньою для критичних journeys, не максимальною. Іноді короткий `sleep` може бути прагматичним, якщо саме polling блокує потрібний browser work, але це виняток із виміряною причиною. За замовчуванням очікується конкретний спостережуваний стан через explicit wait. `StaleElementReferenceException` виникає, коли WebDriver зберіг internal ID елемента, а компонент перерендерився й старий DOM-вузол зник. Повторний виклик дії на старому `WebElement` уже не може спрацювати; потрібен повторний пошук за locator.

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

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

Не змішувати implicit та explicit waits

Locator-based explicit wait вирішує stale reference тим, що на кожній спробі знаходить актуальний DOM-вузол. Це ще одна причина зберігати локатор, а не довгоживучий `WebElement`. Implicit wait радять залишити нульовим і не змішувати з explicit waits: інакше внутрішнє очікування кожного `find_element()` додається до зовнішнього polling, через що реальний timeout стає непередбачуваним. Практичне завдання — зробити `BasePage`, окремий wait helper і Page Object у вибраному locator-based стилі.

2. Selenium організація PageObject's та Очікувань →
Запитати в чаті про «WebElement» →