Автоматизація «Playwright + Python»

Що таке Playwright і для чого він потрібен?

Уявімо, що нам треба протестувати вебсайт:

  • Перевірити, чи працює форма логіну — чи можна ввести ім’я і пароль і увійти.

  • Перевірити, чи відкривається меню — наприклад, натиснути на кнопку “Меню” і побачити список розділів.

  • Перевірити, чи правильно відображаються товари — чи завантажуються картинки, назви і ціни.

Якщо робити це вручну, треба багато разів відкривати сайт, шукати кнопки, вводити дані, натискати — і щоразу повторювати ті самі дії. Це довго і нудно, та ще й можна помилитися.


Що таке Playwright?

Playwright — це спеціальний інструмент для автоматизації браузера. Він:

  • Відкриває браузер і сторінки.

  • Клікає кнопки, вводить текст у форми.

  • Чекає, поки сторінка завантажиться або з’явиться потрібний елемент.

  • Робить скріншоти, щоб перевірити, як виглядає сторінка.

  • Перевіряє, чи з’явилися правильні повідомлення або елементи.

Все це можна запрограмувати на мові Python. Тобто замість того, щоб вручну натискати мишкою, ми пишемо код, який все робить за нас — швидко, точно і багато разів.


Чому це круто?

  • Економія часу — тести запускаються автоматично, навіть кілька разів на день.

  • Повторюваність — тест завжди робить одне й те саме, без помилок.

  • Швидкість — ти не сидиш годинами за комп’ютером, а просто запускаєш тести.

  • Підвищення якості продукту — швидко знаходиш баги і виправляєш їх.

Як це виглядає у коді?

Приклад дуже простого тесту логіну на Python з Playwright:

from playwright.sync_api import sync_playwright

def test_login():
with sync_playwright() as p:
browser = p.chromium.launch(headless=False) # Запускаємо браузер
page = browser.new_page()
page.goto(«https://test.com/login») # Відкриваємо сторінку логіну

page.fill(«input[name=’username’]», «myusername») # Вводимо ім’я користувача
page.fill(«input[name=’password’]», «mypassword») # Вводимо пароль
page.click(«button[type=’submit’]») # Натискаємо кнопку «Увійти»

# Чекаємо, поки з’явиться елемент, що означає успішний вхід
page.wait_for_selector(«text=Welcome, myusername»)

browser.close()

test_login()

 

Що ще можна тестувати автоматично з Playwright?

  • Перевірка меню і навігації
    Наприклад, клікнути на різні розділи сайту і впевнитися, що відкриваються правильні сторінки.

  • Тестування форм
    Крім логіну, можна перевірити реєстрацію, пошук, зворотний зв’язок — чи правильно працюють поля, чи з’являються повідомлення про помилки.

  • Перевірка відображення елементів
    Чи правильно показуються картинки, чи завантажуються товари, чи відображаються ціни.

  • Тестування поведінки сайту при різних розмірах екрана
    Перевірка адаптивності — як сайт виглядає на телефоні, планшеті і ПК.

  • Перевірка роботи кнопок, посилань, випадаючих списків
    Чи всі елементи працюють як потрібно, чи не виникають помилки.

  • Тестування сценаріїв користувача
    Наприклад, додавання товару в корзину, оформлення замовлення, вихід з аккаунта.

  • Зняття скріншотів та відеозапис сеансів
    Щоб у разі помилки було легше відтворити проблему.


Чому обирають Playwright?

  • Працює з усіма популярними браузерами: Chromium (Chrome), Firefox, WebKit (Safari).

  • Має простий, зрозумілий API.

  • Добре підходить і для тестування, і для автоматизації рутинних задач.

  • Підтримує різні мови програмування, зокрема Python, JavaScript, C#.

  • Має вбудовані функції очікування (wait), що роблять тести стабільнішими.

  • Легко інтегрується в CI/CD процеси (безперервна інтеграція та доставка).

Підготовка робочого середовища

Перед тим, як почати писати тести, потрібно підготувати свій комп’ютер.

Встанови Python

  • Перейди на https://www.python.org/downloads/windows/

  • Завантаж останню версію

  • Під час встановлення обов’язково постав галочку  Add Python to PATH

  • Натисни Install Now

Встанови VS Code

  • Завантаж з https://code.visualstudio.com/Download

  • Встанови з дефолтними налаштуваннями

  • Додай розширення Python у VS Code (іконка кубика → пошук Python → Install)

Перевір версії

Відкрий Командний рядок (CMD) або PowerShell:

python --version
pip --version

Перевір Python

macOS зазвичай має вбудований Python, але часто він старий.
Відкрий Terminal і введи:

python3 --version

Якщо версія менше ніж 3.8, онови:

brew install python

Якщо у тебе немає Homebrew, встанови його: https://brew.sh/

Встанови VS Code

Перевір версії

python3 --version
pip3 --version

Встанови Python і pip

sudo apt update
sudo apt install python3 python3-pip -y

 

Встанови VS Code

sudo apt install ./code_*.deb
  • Додай розширення Python у VS Code

Перевір версії

python3 --version
pip3 --version

Додатково (для всіх ОС)

Після встановлення Python:
Переконайся, що pip працює
Встанови Playwright:
pip install
playwright pytest
Завантаж браузери для тестування:
playwright install

Настав час практики!

Теорія — це добре, але справжні навички приходять тільки під час реальної роботи з проєктом.
Сьогодні ми переходимо від слів до справи — ви отримаєте можливість протестувати живий вебзастосунок Finmore, який використовується для управління особистими фінансами.

Чому саме зараз

Ви вже знаєте базу Playwright + Python.
Маєте готове робоче середовище.
І найголовніше — перед вами продукт, який можна “помацати” та перевірити на помилки.

Що будемо робити

Розберемо інтерфейс і логіку форми реєстрації.
Створимо тест-кейси.
Напишемо автоматичні тести у Playwright Python.
Перевіримо, як проходить позитивний сценарій та як система реагує на помилки.

Результат

Ви отримаєте свій перший готовий автотест для реального вебзастосунку, який можна додати у портфоліо

Коротко про проєкт Finmore

Finmore — це вебзастосунок для особистих фінансів.
Його основна мета — допомогти користувачам:

  • вести облік доходів та витрат;

  • аналізувати фінансові звички;

  • планувати бюджет;

  • працювати з кількома валютами.

Функціонал:

  • Реєстрація та авторизація користувачів.

  • Додавання транзакцій (доходи, витрати).

  • Звіти та графіки по фінансових операціях.

  • Підтримка кількох валют.

  • Захист даних через систему акаунтів.

Давай створимо тест-кейси для реєстрації, щоб можна було одразу реалізувати їх у Playwright + Python.

Тест-кейс: Реєстрація

Успішна реєстрація з валідними даними

Передумови: Користувач не має акаунта.
Кроки:

  1. Відкрити сторінку реєстрації.

  2. Ввести повне ім’я: Іван Петренко.

  3. Ввести email: ivan.petrenko@example.com.

  4. Ввести пароль: Qwerty123.

  5. Повторити пароль: Qwerty123.

  6. Обрати валюту: Гривня (UAH).

  7. Натиснути кнопку «Зареєструватися».
    Очікуваний результат: Користувач успішно зареєстрований і перенаправлений на сторінку Панель управління.

Створення структури проєкту

В твоїй папці створити файл, наприклад, test_registration.py

Написати тест у файлі test_registration.py

				
					from playwright.sync_api import sync_playwright

def test_registration():
    with sync_playwright() as p:
        browser = p.chromium.launch(headless=True)  # Запускаємо браузер у фоновому режимі
        context = browser.new_context()
        page = context.new_page()

        # Відкриваємо сторінку логіну
        page.goto("https://finmore.netlify.app")

        # Клікаємо на кнопку "Зареєструватися" щоб перейти до форми реєстрації
        page.click('button[data-testid="switch-to-register-button"]')

        # Заповнюємо форму реєстрації
        page.fill('input[data-testid="register-name-input"]', "Іван Петренко")
        page.fill('input[data-testid="register-email-input"]', "ivan.petrenko@example.com")
        page.fill('input[data-testid="register-password-input"]', "Qwerty123")
        page.fill('input[data-testid="register-confirm-password-input"]', "Qwerty123")
        page.select_option('select[data-testid="register-currency-select"]', "UAH")

        # Натискаємо кнопку "Зареєструватися"
        page.click('button[data-testid="register-submit-button"]')

        # Очікуємо появу сайдбару, що означає успішну авторизацію
        sidebar = page.locator('[data-testid="sidebar"]')
        sidebar.wait_for(state="visible", timeout=5000)  # Чекаємо до 5 секунд
        assert sidebar.is_visible(), "Сайдбар не відображається, ймовірно користувач не авторизований"

        browser.close()

if __name__ == "__main__":
    test_registration()

				
			

Пояснення

from playwright.sync_api import sync_playwright

  • Імпортуємо необхідну функцію sync_playwright з бібліотеки Playwright.

  • Це дозволяє керувати браузером у синхронному режимі (код буде виконуватися послідовно).

def test_registration():

  • Оголошуємо функцію test_registration, яка міститиме весь тестовий сценарій реєстрації.

  • Функція допомагає організувати код і запускати тест як окрему одиницю.

with sync_playwright() as p:

  • Відкриваємо контекст Playwright.

  • with — це конструкція, яка автоматично запускає Playwright і закриває його після виконання коду всередині блоку.

  • p — змінна, через яку ми звертаємося до браузерів (Chromium, Firefox, WebKit).

browser = p.chromium.launch(headless=True) # Запускаємо браузер у фоновому режимі

  • Запускаємо браузер Chromium.

  • headless=True означає, що браузер запуститься без графічного інтерфейсу — тобто не буде видно вікна браузера.

  • Це корисно для автоматичних тестів, щоб не відволікати користувача.

context = browser.new_context()

  • Створюємо новий контекст браузера.

  • Контекст — це «окрема вкладка» або «сесія» браузера із власними куками, кешем тощо.

  • Це дозволяє запускати тести незалежно один від одного.

page = context.new_page()

  • Відкриваємо нову сторінку (вкладку) в браузері.

  • У цю сторінку ми будемо завантажувати сайт і взаємодіяти з ним.

page.goto(«https://finmore.netlify.app»)

  • Переходимо за URL сайту, який тестуємо.

  • Метод goto завантажує сторінку за вказаною адресою.

page.click(‘button[data-testid=»switch-to-register-button»]’)

  • Клікаємо на кнопку «Зареєструватися».

  • Вибираємо елемент за атрибутом data-testid, який допомагає точно знайти потрібний елемент на сторінці.

  • Це відкриває форму реєстрації.

page.fill(‘input[data-testid=»register-name-input»]’, «Іван Петренко»)

  • Заповнюємо поле для імені текстом «Іван Петренко».

  • Метод fill очищає поле і вводить текст.

page.select_option(‘select[data-testid=»register-currency-select»]’, «UAH»)

  • Вибираємо опцію «Гривня (UAH)» у випадаючому списку валют.

  • Метод select_option задає потрібне значення у <select>.

sidebar = page.locator(‘[data-testid=»sidebar»]’)

  • Знаходимо елемент сайдбару, який з’являється тільки після успішної реєстрації та авторизації.

  • locator дозволяє працювати з елементом (перевіряти видимість, текст і т.д.).

sidebar.wait_for(state=»visible», timeout=5000) # Чекаємо до 5 секунд

  • Чекаємо, доки сайдбар стане видимим.

  • Максимальний час очікування — 5 секунд.

  • Це допомагає уникнути помилок, якщо елемент з’являється не миттєво.

assert sidebar.is_visible(), «Сайдбар не відображається, ймовірно користувач не авторизований»

  • Перевіряємо, що сайдбар справді видимий.

  • Якщо ні — тест зупиниться з повідомленням про помилку.

browser.close()

Закриваємо браузер і звільняємо ресурси.

if __name__ == «__main__»:
test_registration()

  • Це стандартний спосіб запустити тест, якщо скрипт запущений напряму (а не імпортований як модуль).

  • Викликає функцію test_registration().

Запусти тест

python test_registration.py

Написання асинхронного варіанту реєстрації з Playwright на Python.

Тут використовується async/await синтаксис, який дозволяє виконувати операції асинхронно, не блокуючи виконання коду.

				
					import asyncio
from playwright.async_api import async_playwright

async def test_registration():
    async with async_playwright() as p:
        browser = await p.chromium.launch(headless=True)  # Запускаємо браузер у фоновому режимі
        context = await browser.new_context()
        page = await context.new_page()

        # Відкриваємо сторінку логіну
        await page.goto("https://finmore.netlify.app")

        # Клікаємо на кнопку "Зареєструватися" щоб перейти до форми реєстрації
        await page.click('button[data-testid="switch-to-register-button"]')

        # Заповнюємо форму реєстрації
        await page.fill('input[data-testid="register-name-input"]', "Іван Петренко")
        await page.fill('input[data-testid="register-email-input"]', "ivan.petrenko@example.com")
        await page.fill('input[data-testid="register-password-input"]', "Qwerty123")
        await page.fill('input[data-testid="register-confirm-password-input"]', "Qwerty123")
        await page.select_option('select[data-testid="register-currency-select"]', "UAH")

        # Натискаємо кнопку "Зареєструватися"
        await page.click('button[data-testid="register-submit-button"]')

        # Очікуємо появу сайдбару, що означає успішну авторизацію
        sidebar = page.locator('[data-testid="sidebar"]')
        await sidebar.wait_for(state="visible", timeout=5000)  # Чекаємо до 5 секунд
        assert await sidebar.is_visible(), "Сайдбар не відображається, ймовірно користувач не авторизований"

        await browser.close()

if __name__ == "__main__":
    asyncio.run(test_registration())

				
			

Ключові відмінності в асинхронній версії:

  • Імпортуємо asyncio і async_playwright.

  • Вся функція оголошена як async def.

  • Для асинхронних дій (відкриття браузера, кліки, заповнення форм, очікування) використовується await.

  • Запуск функції — через asyncio.run().

Розпишу детальніше про асинхронний vs синхронний код у Playwright на Python і пораджу, що краще використовувати.

 

Що таке синхронний і асинхронний код?

Синхронний код (sync)

  • Виконується послідовно: одна команда чекає, поки завершиться попередня.

  • Проста логіка, легко читати і дебажити.

  • У Playwright є синхронний API (playwright.sync_api).

page.goto(«url»)
page.click(«button»)

тут друга команда виконується лише після закінчення першої.

 

Асинхронний код (async)

  • Виконується з можливістю паралельного опрацювання.

  • Використовує async/await, щоб «не блокувати» програму, коли чекає на довгі операції (наприклад, завантаження сторінки).

  • Playwright має асинхронний API (playwright.async_api).

await page.goto(«url»)
await page.click(«button»)

Відповідь не блокує інші операції, поки браузер виконує завдання.

Плюси і мінуси

ХарактеристикаСинхронний APIАсинхронний API
Простота кодуЛегко писати і читатиТрохи складніше, треба розуміти async/await
Дебаг і логікаПростий послідовний потікПотрібно враховувати асинхронність
ВиконанняМенше паралельності (один крок за раз)Можна запускати паралельно декілька задач, швидше в масштабі
ПідтримкаІдеально для простих тестівКращий для складних проектів з багатьма паралельними тестами
СумісністьЧасто легше інтегрувати з іншими синхронними інструментамиПотрібно використовувати asyncio або інші async-інструменти

Що краще вибрати для початківця?

  • Якщо тільки починаєш — рекомендую синхронний API:

    • Простий і зрозумілий.

    • Легше читати, менше складних конструкцій.

    • Хороша база, щоб зрозуміти, як працює Playwright.

  • Коли освоїш основи — переходь на асинхронний:

    • Асинхронність допомагає запускати кілька тестів паралельно, що значно економить час.

    • Більше контролю над продуктивністю.

    • Потрібно для великих, складних проектів.

Тест-кейс: Валідація обов’язкових полів

Передумови: Користувач на сторінці реєстрації.
Кроки:

  1. Не заповнювати жодне поле.

  2. Натиснути «Зареєструватися».
    Очікуваний результат: Для кожного поля з’являється повідомлення про помилку (наприклад, «Поле обов’язкове»).

Короткий огляд елементів для перевірки

  • Поле Ім’я: input[data-testid="register-name-input"]

  • Повідомлення помилки імені: [data-testid="name-error"]

  • Поле Email: input[data-testid="register-email-input"]

  • Повідомлення помилки Email: [data-testid="email-error"]

  • Поле Пароль: input[data-testid="register-password-input"]

  • Повідомлення помилки пароля: [data-testid="password-error"]

  • Поле Підтвердження пароля: input[data-testid="register-confirm-password-input"]

  • Повідомлення помилки підтвердження: [data-testid="confirm-password-error"]

  • Кнопка «Зареєструватися»: button[data-testid="register-submit-button"]

Тест на перевірку обов’язкових полів (синхронний)

 

				
					from playwright.sync_api import sync_playwright

def test_required_fields_validation():
    with sync_playwright() as p:
        browser = p.chromium.launch(headless=True)
        context = browser.new_context()
        page = context.new_page()

        # Відкриваємо головну і клікаємо на кнопку "Зареєструватися"
        page.goto("https://finmore.netlify.app")
        page.click('button[data-testid="switch-to-register-button"]')

        # Нічого не вводимо, просто натискаємо кнопку реєстрації
        page.click('button[data-testid="register-submit-button"]')

        # Перевіряємо появу повідомлень про помилки

        # Ім'я
        name_error = page.locator('[data-testid="name-error"]')
        assert name_error.is_visible(), "Повідомлення про помилку імені не відображається"
        assert "обов'язкове" in name_error.text_content(), "Текст помилки імені некоректний"

        # Email
        email_error = page.locator('[data-testid="email-error"]')
        assert email_error.is_visible(), "Повідомлення про помилку email не відображається"
        assert "обов'язковий" in email_error.text_content(), "Текст помилки email некоректний"

        # Пароль
        password_error = page.locator('[data-testid="password-error"]')
        assert password_error.is_visible(), "Повідомлення про помилку паролю не відображається"
        assert "обов'язковий" in password_error.text_content(), "Текст помилки паролю некоректний"

        # Підтвердження паролю
        confirm_password_error = page.locator('[data-testid="confirm-password-error"]')
        assert confirm_password_error.is_visible(), "Повідомлення про помилку підтвердження паролю не відображається"
        assert "обов'язкове" in confirm_password_error.text_content(), "Текст помилки підтвердження паролю некоректний"

        browser.close()

if __name__ == "__main__":
    test_required_fields_validation()

				
			

Тест на перевірку обов’язкових полів (асинхронний)

				
					import asyncio
from playwright.async_api import async_playwright

async def test_required_fields_validation():
    async with async_playwright() as p:
        browser = await p.chromium.launch(headless=True)
        context = await browser.new_context()
        page = await context.new_page()

        # 1. Відкриваємо головну сторінку
        await page.goto("https://finmore.netlify.app")

        # 2. Переходимо на форму реєстрації
        await page.click('button[data-testid="switch-to-register-button"]')

        # 3. Натискаємо кнопку "Зареєструватися" без заповнення
        await page.click('button[data-testid="register-submit-button"]')

        # 4. Перевірка кожного повідомлення про помилку

        # Ім'я
        name_error = page.locator('[data-testid="name-error"]')
        assert await name_error.is_visible(), "Помилка для поля Ім'я не відображається"
        assert "обов'язков" in (await name_error.text_content()), "Текст помилки Ім'я некоректний"

        # Email
        email_error = page.locator('[data-testid="email-error"]')
        assert await email_error.is_visible(), "Помилка для поля Email не відображається"
        assert "обов'язков" in (await email_error.text_content()), "Текст помилки Email некоректний"

        # Пароль
        password_error = page.locator('[data-testid="password-error"]')
        assert await password_error.is_visible(), "Помилка для поля Пароль не відображається"
        assert "обов'язков" in (await password_error.text_content()), "Текст помилки Пароль некоректний"

        # Підтвердження паролю
        confirm_password_error = page.locator('[data-testid="confirm-password-error"]')
        assert await confirm_password_error.is_visible(), "Помилка для поля Підтвердження паролю не відображається"
        assert "обов'язков" in (await confirm_password_error.text_content()), "Текст помилки Підтвердження паролю некоректний"

        await browser.close()

if __name__ == "__main__":
    asyncio.run(test_required_fields_validation())

				
			

Що таке Page Object Model (POM)

Page Object Model — це підхід у автоматизації тестування, коли:

  1. Кожна сторінка сайту описується окремим класом/файлом.

  2. У цьому класі ми зберігаємо локатори елементів і методи для роботи з ними.

  3. Тести стають чистими та читабельними, бо вся логіка взаємодії з елементами винесена в окремі файли.

Без POM тест може виглядати як “суцільна каша” з локаторів і дій.
З POM тести виглядають як інструкція: «відкрий сторінку», «заповни форму», «натисни кнопку».

Структура проєкту

tests/
    test_registration.py
    test_required_fields_validation.py
pages/
   registration_page.py

pages/registration_page.py

				
					from playwright.sync_api import Page

class RegistrationPage:
    def __init__(self, page: Page):
        self.page = page
        self.switch_to_register_button = 'button[data-testid="switch-to-register-button"]'
        self.name_input = 'input[data-testid="register-name-input"]'
        self.email_input = 'input[data-testid="register-email-input"]'
        self.password_input = 'input[data-testid="register-password-input"]'
        self.confirm_password_input = 'input[data-testid="register-confirm-password-input"]'
        self.currency_select = 'select[data-testid="register-currency-select"]'
        self.submit_button = 'button[data-testid="register-submit-button"]'
        self.sidebar = '[data-testid="sidebar"]'

        # Errors
        self.name_error = '[data-testid="name-error"]'
        self.email_error = '[data-testid="email-error"]'
        self.password_error = '[data-testid="password-error"]'
        self.confirm_password_error = '[data-testid="confirm-password-error"]'

    def open(self):
        self.page.goto("https://finmore.netlify.app")
        self.page.click(self.switch_to_register_button)

    def register(self, name, email, password, confirm_password, currency):
        self.page.fill(self.name_input, name)
        self.page.fill(self.email_input, email)
        self.page.fill(self.password_input, password)
        self.page.fill(self.confirm_password_input, confirm_password)
        self.page.select_option(self.currency_select, currency)
        self.page.click(self.submit_button)

    def submit_empty_form(self):
        self.page.click(self.submit_button)

    def wait_for_sidebar(self):
        sidebar_locator = self.page.locator(self.sidebar)
        sidebar_locator.wait_for(state="visible", timeout=5000)
        return sidebar_locator.is_visible()

    def get_error_text(self, locator):
        return self.page.locator(locator).text_content()

    def is_error_visible(self, locator):
        return self.page.locator(locator).is_visible()

				
			

tests/test_registration.py

				
					from playwright.sync_api import sync_playwright
from pages.registration_page import RegistrationPage

def test_registration():
    with sync_playwright() as p:
        browser = p.chromium.launch(headless=True)
        context = browser.new_context()
        page = context.new_page()

        registration_page = RegistrationPage(page)

        # Відкриваємо сторінку та форму
        registration_page.open()

        # Заповнюємо форму
        registration_page.register(
            name="Іван Петренко",
            email="ivan.petrenko@example.com",
            password="Qwerty123",
            confirm_password="Qwerty123",
            currency="UAH"
        )

        # Перевіряємо успішну реєстрацію
        assert registration_page.wait_for_sidebar(), "Сайдбар не відображається, користувач не авторизований"

        browser.close()

				
			

tests/test_required_fields_validation.py

				
					from playwright.sync_api import sync_playwright
from pages.registration_page import RegistrationPage

def test_required_fields_validation():
    with sync_playwright() as p:
        browser = p.chromium.launch(headless=True)
        context = browser.new_context()
        page = context.new_page()

        registration_page = RegistrationPage(page)

        # Відкриваємо форму
        registration_page.open()

        # Відправляємо порожню форму
        registration_page.submit_empty_form()

        # Перевірка помилок
        assert registration_page.is_error_visible(registration_page.name_error), "Помилка імені не відображається"
        assert "обов'язкове" in registration_page.get_error_text(registration_page.name_error), "Текст помилки імені некоректний"

        assert registration_page.is_error_visible(registration_page.email_error), "Помилка email не відображається"
        assert "обов'язковий" in registration_page.get_error_text(registration_page.email_error), "Текст помилки email некоректний"

        assert registration_page.is_error_visible(registration_page.password_error), "Помилка паролю не відображається"
        assert "обов'язковий" in registration_page.get_error_text(registration_page.password_error), "Текст помилки паролю некоректний"

        assert registration_page.is_error_visible(registration_page.confirm_password_error), "Помилка підтвердження паролю не відображається"
        assert "обов'язкове" in registration_page.get_error_text(registration_page.confirm_password_error), "Текст помилки підтвердження паролю некоректний"

        browser.close()

				
			

Що ми виграли завдяки Page Object:

  • Всі селектори зібрані в одному місці (registration_page.py).

  • Якщо зміниться верстка — редагуємо лише один файл.

  • Тести стали короткі та зрозумілі.

  • Легко додавати нові методи для роботи з формою.

Давай розберемо  registration_page.py

Імпорт модуля Page

from playwright.sync_api import Page

Ми імпортуємо клас Page із Playwright.
Page — це об’єкт, який представляє вкладку браузера.
Через нього ми відкриваємо сторінки, клікаємо, вводимо текст, читаємо елементи.

Оголошення класу

def __init__(self, page: Page):
self.page = page

  • Конструктор (__init__) викликається, коли ми створюємо об’єкт класу.

  • Ми передаємо об’єкт page (вкладка браузера) з тесту у цей клас і зберігаємо його в self.page.

  • Тепер всі методи цього класу можуть керувати браузером через self.page.

class RegistrationPage:

  • Створюємо Page Object для сторінки реєстрації.

  • Page Object — це як «модель» сторінки: тут описані всі селектори та методи, які з нею працюють.

Локатори елементів
 
self.switch_to_register_button = ‘button[data-testid=»switch-to-register-button»]’
self.name_input = ‘input[data-testid=»register-name-input»]’
 

Тут ми зберігаємо CSS-селектори для елементів сторінки.

Краще виносити селектори сюди, щоб:

    • не дублювати їх у тестах;

    • якщо зміниться HTML — треба виправити тільки тут.

  • data-testid — це атрибут, який зазвичай додають розробники спеціально для автотестів.

Метод відкриття сторінки

def open(self):
self.page.goto(«https://finmore.netlify.app»)
self.page.click(self.switch_to_register_button)

  • goto() — відкриває потрібну URL-сторінку.

  • Потім клікаємо по кнопці «Зареєструватися», щоб відкрити форму.

  • Таким чином, тестам не треба повторювати цей код, вони просто викличуть registration_page.open().

Метод реєстрації

def register(self, name, email, password, confirm_password, currency):
self.page.fill(self.name_input, name)
self.page.fill(self.email_input, email)
self.page.fill(self.password_input, password)
self.page.fill(self.confirm_password_input, confirm_password)
self.page.select_option(self.currency_select, currency)
self.page.click(self.submit_button)

Приймає всі потрібні дані як аргументи.

  • fill() — вводить текст у поле.

  • select_option() — вибирає значення в <select>.

  • click() — натискає на кнопку.

  • Весь процес реєстрації тепер можна виконати одним викликом:

registration_page.register(«Іван», «ivan@example.com», «Qwerty123», «Qwerty123», «UAH»)

Відправка пустої форми

def submit_empty_form(self):
self.page.click(self.submit_button)

Використовується для тестів валідації (щоб перевірити помилки при пустих полях).

Очікування появи сайдбару

def wait_for_sidebar(self):
sidebar_locator = self.page.locator(self.sidebar)
sidebar_locator.wait_for(state=»visible», timeout=5000)
return sidebar_locator.is_visible()

  • locator() — знаходить елемент на сторінці.

  • wait_for() — чекає, поки елемент стане видимим (максимум 5 секунд).

  • Повертає True або False залежно від того, чи з’явився сайдбар.

  • Використовується в перевірках успішної авторизації.

Отримання тексту помилки

def get_error_text(self, locator):
return self.page.locator(locator).text_content()

Повертає текст із помилки (наприклад, «Поле обов’язкове»).

Перевірка видимості помилки

def is_error_visible(self, locator):
return self.page.locator(locator).is_visible()

Повертає True, якщо помилка видима на сторінці.

registration_page.py — це карта сторінки + набір дій, які можна виконати з її елементами.
В тестах тепер не потрібно думати про локатори — вони просто викликають методи класу.

Давай розберемо

test_registration.py

Імпорти

from playwright.sync_api import sync_playwright
from pages.registration_page import RegistrationPage

  • sync_playwright — синхронний API Playwright, щоб можна було писати код у звичайному послідовному стилі.

  • RegistrationPage — це ваш власний Page Object клас, який інкапсулює всі дії та локатори, пов’язані зі сторінкою реєстрації.

Основна функція тесту

def test_registration():

Це функція, яка буде виконуватись тестовим раннером (наприклад, pytest).

Запуск браузера

with sync_playwright() as p:
browser = p.chromium.launch(headless=True)
context = browser.new_context()
page = context.new_page()

  • p.chromium.launch(headless=True) — відкриває Chromium у безголовому режимі (без графічного інтерфейсу).

  • new_context() — створює новий браузерний контекст (аналог окремого користувацького сеансу).

  • new_page() — відкриває нову вкладку в цьому контексті.

Ініціалізація Page Object

registration_page = RegistrationPage(page)

Тут створюється екземпляр сторінки реєстрації, якому передається page з Playwright.
Тепер можна викликати методи, описані в RegistrationPage.

Відкриття сторінки та форми

registration_page.open()

Цей метод у Page Object відкриває потрібну URL сторінки реєстрації та, ймовірно, чекає завантаження форми.

Заповнення форми

registration_page.register(
name=»Іван Петренко»,
email=»ivan.petrenko@example.com»,
password=»Qwerty123″,
confirm_password=»Qwerty123″,
currency=»UAH»
)

Метод register():

  • Вводить ім’я

  • Вводить email

  • Встановлює пароль і підтвердження пароля

  • Обирає валюту (UAH)

  • Надсилає форму (натискає кнопку реєстрації)

Перевірка успішної реєстрації

assert registration_page.wait_for_sidebar(), «Сайдбар не відображається, користувач не авторизований»

  • Метод wait_for_sidebar() чекає появи елемента сайдбара, що свідчить про успішний логін після реєстрації.

  • Якщо сайдбар не з’явився — тест падає з повідомленням.

Закриття браузера

browser.close()

Закриває браузер і завершує роботу Playwright.

Сенс тесту — автоматично перевірити, що новий користувач може зареєструватись і після цього потрапляє в систему (відображається сайдбар).
Цей підхід з POM робить тест чистим, читабельним і легко підтримуваним — усі локатори та логіка роботи зі сторінкою зберігаються окремо від тесту.

 

Завдання для самостійного опрацювання

Page Object Model (POM) у Playwright / Python

Теорія

Своїми словами пояснити:
Що таке Page Object Model.
Які є переваги POM.
Які є ризики та недоліки POM.
Коли не варто використовувати POM.

Перевірка мінімальної довжини пароля

Кроки:
Заповнити ім’я та email валідними даними.У полі "Пароль" ввести 12345.Повторити пароль: 12345.Натиснути "Зареєструватися". Очікуваний результат: З’являється повідомлення про помилку ("Мінімум 6 символів").

Перевірка збігу паролів

Кроки:
Заповнити всі поля валідно.
У полі "Пароль" ввести Qwerty123.
У полі "Підтвердження паролю" ввести Qwerty124.
Натиснути "Зареєструватися".
Очікуваний результат: Повідомлення про помилку ("Паролі не збігаються").

Перевірка формату email

Заповнити ім’я і пароль валідними даними.
У полі "Email" ввести ivan.petrenko.com (без @).
Натиснути "Зареєструватися".
Очікуваний результат: Повідомлення про помилку ("Некоректний email").

Підтримка та питання

Якщо вам потрібна будь-яка підтримка або у вас виникли додаткові питання, не соромтеся зв'язатися з нами, ми готові швидко надати вам допомогу.

Через чат-бот