← Python мануфактура

Після цього уроку ви зможете

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

0:00

Навіщо розуміти селектори та DOM

Надійні локатори спрощують не лише написання нового тесту, а й пошук дублювань та рефакторинг наявного набору. Без розуміння HTML одна й та сама кнопка швидко отримує кілька різних локаторів у різних тестах.

DOM розглядається як дерево. Кореневий <html> містить <head> і <body>, а вкладені елементи утворюють гілки на різних рівнях. DevTools дає змогу розгортати й згортати ці гілки та бачити, до якого блоку належить потрібний елемент.

2:55

Елементи, атрибути, `id` і класи

HTML-вузол має тег, атрибути та вкладений вміст. Атрибут class може містити кілька класів, розділених пробілами. CSS надає короткий синтаксис:

```css
#search /* елемент з id="search" */
.demo /* елемент із класом demo */
input#search /* input з id="search" */
```

Текстові локатори краще будувати засобами Playwright, а не намагатися кодувати складний пошук тексту в CSS.

5:45

Динамічні значення та пошук за частиною атрибута

За стандартом id має бути унікальним, але деякі frontend-фреймворки генерують до стабільної частини випадковий суфікс. Повне значення такого id може змінитися після нового deployment або навіть між сесіями.

CSS дозволяє шукати за точним значенням або за стабільним фрагментом:

```css
[id="sort-block-123"]
[id*="sort-block"]
[class*="text-area"]
```

Оператор *= означає «атрибут містить цей текст». Частковий збіг має бути достатньо специфічним, інакше локатор знайде кілька елементів.

Термін

attribute selector

CSS selector, який відбирає elements за наявністю або значенням attribute, включно з exact і substring matching operators.

10:03

Контрольовані `data-testid` та інші атрибути

Найстабільніший для команди варіант — атрибут, значення якого тестувальники та розробники свідомо контролюють, наприклад data-testid. Його можна додати у frontend-компонент і зберігати як частину контракту тестованості.

Так само можуть використовуватися стабільні id, name, aria-label чи інші атрибути. Головний критерій автора — не назва механізму сама по собі, а можливість команди контролювати його та домовитися, коли він змінюється.

12:20

Пріоритети локаторів і читабельність

Поле Search Project можна знайти за id або placeholder. placeholder є зрозумілим, але може змінюватися через локалізацію. Класи зазвичай менш стабільні за спеціальний тестовий атрибут.

XPath має широкі можливості навігації вгору й вниз по DOM, але часто читається гірше за короткий CSS-локатор. Результати тестів мають швидко розуміти розробники, тому читабельність і спільна командна домовленість важливіші за демонстрацію максимально складного виразу.

Приклад коду

CSS attribute matching

#search
[id*="sort-block"]
a.common-btn.primary[href*="new"]

Порівнює id shorthand, substring match і комбінування tag, classes та attribute.

Очікуваний результат: Кожен selector знаходить лише intended element у відповідному DOM fixture.

16:15

Побудова читабельних CSS-селекторів

Один елемент можна знайти різними еквівалентними способами:

```css
#search
[id="search"]
input#search
```

Якщо простого атрибута недостатньо, умови комбінуються:

```css
a.common-btn.primary[href*="new"]
```

href часто стабільний, бо відповідає маршруту застосунку. Водночас найкоротший селектор не завжди найкращий: трохи довший вираз може краще пояснювати на code review, яку саме кнопку він описує. Пріоритет — однозначність і читабельність, а не мінімальна кількість символів.

Що змінилося після запису

Чинний locator guidance Playwright

АктуальноПоточна документація радить пріоритезувати user-facing attributes, особливо role locators, або explicit testing contracts через test ids. CSS/XPath залишаються fallback, коли ці варіанти непридатні.

Перевірено 2026-07-31

Термін

Locator

Playwright abstraction, яка повторно знаходить актуальний DOM element перед кожною action та підтримує auto-waiting і retry-ability.

Практика

Скласти locator inventory

  1. Вибрати три interactive elements на тестовій сторінці.
  2. Для кожного записати role/text/test-id/CSS candidates.
  3. У DevTools перевірити count і видимість.
  4. Обрати один locator та пояснити компроміс.

Результат: Кожен selected locator однозначний і пояснюваний на code review.

23:35

Accessibility tree та role-локатори

Accessibility tree показує інтерфейс так, як його сприймають assistive technologies: ролі link, button, textbox, searchbox, list та їхні доступні імена. У DevTools потрібно ввімкнути повне accessibility tree й перезавантажити сторінку.

Playwright підтримує локатори на основі цієї семантики, наприклад get_by_role. Вони часто добре читаються та водночас перевіряють, що елемент має зрозумілу роль. Але на проєкті все одно потрібна єдина домовленість про основну стратегію та допустимі винятки.

Термін

accessible name

Ім’я, за яким element сприймається assistive technologies і знаходиться role locator; воно формується семантикою HTML та ARIA.

26:30

`get_by_role` і проблемна семантика форми

У Python role-локатор може виглядати так:

```python
page.get_by_role("button", name="Sign in")
page.get_by_role("textbox", name="Email")
```

Допустимі ролі й додаткові параметри можна подивитися через перехід до визначення методу в PyCharm. На розглянутій login-формі доступні імена полів сформовані невдало, а type="text" використано там, де доречніший type="email". Через це семантичний локатор стає незручним.

Це приклад того, що рекомендацію Playwright не можна застосовувати механічно: спочатку слід перевірити реальну accessibility-структуру, а якщо вона неякісна — або виправити frontend, або обрати зрозумілий контрольований локатор.

Що змінилося після запису

Дубльований `id` — невалідний HTML, а scope лише workaround

АктуальноHTML Standard вимагає, щоб id був унікальним у межах element tree. Scope до desktop container може стабілізувати test, але root fix належить frontend markup.

Перевірено 2026-07-31

Уточнення

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

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

Термін

strictness

Правило Playwright: operation, що очікує один target element, падає, якщо locator відповідає кільком elements.

Практика

Відтворити mobile/desktop collision

  1. Створити DOM fixture з двома forms і однаковими field identifiers.
  2. Підтвердити strictness failure для global locator.
  3. Звузити пошук до visible container.

Результат: Scoped locator проходить без .first і .nth().

32:20

Дублікати mobile/desktop і область пошуку

На сторінці одночасно присутні mobile- і desktop-версії форми. Тому навіть нібито унікальний id може знайти два вузли, один з яких прихований. Щоб не покладатися на порядок, пошук звужується до видимого контейнера:

```css
#content-desktop #user_email
```

Пробіл означає нащадка на будь-якому рівні вкладеності, а > — лише безпосередню дочірню ланку. Перед автоматизацією сценарій потрібно повністю пройти вручну й у DevTools перевірити кожен локатор, кількість збігів, видимість елемента та мережеві запити, які запускає введення даних.

36:10

Сценарій login і навігація в PyCharm

Поля заповнюються через locator(...).fill(...), а кнопка може шукатися за роллю та доступним ім’ям. Приклад структури сценарію:

```python
page.locator("#content-desktop #user_email").fill("user@example.com")
page.locator("#content-desktop #user_password").fill("invalid-password")
page.get_by_role("button", name="Sign in").click()
```

Для швидкої роботи з кодом автор налаштовує розширення й звуження виділення (Extend Selection, Shrink Selection) та перехід між словами через Option+Left/Right. Гарячі клавіші мають прискорювати точні дії, а не приховувати нерозуміння поточного контексту.

40:30

Запуск і налагодження повного сценарію

Після запуску прибирається зайвий код, що залишився від попередніх експериментів, і додається відсутній клік Sign in. Для кожної дії Playwright має додаткові аргументи на кшталт timeout або force, але їх не слід додавати без конкретної потреби.

Падіння на локаторі треба розбирати з фактичної сторінки: відкрити DOM, повторити пошук і перевірити, чи тест узагалі перейшов у потрібний стан.

44:40

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

Для невалідних облікових даних тест очікує повідомлення Invalid email or password. Є два близькі підходи:

```python
expect(page.get_by_text("Invalid email or password")).to_be_visible()

expect(page.locator("#content-desktop .common-flash-info")).to_have_text(
"Invalid email or password"
)
```

У першому випадку елемент знаходиться за текстом і перевіряється його видимість. У другому — спочатку знаходиться стабільний контейнер, а потім перевіряється його текст. Обидва варіанти потребують правильної області пошуку через дубльовану розмітку.

Приклад коду

User-facing locator зі scope

from playwright.sync_api import Page, expect


def test_invalid_login(page: Page):
    page.goto("https://example.test/login")
    desktop = page.locator("#content-desktop")
    desktop.get_by_label("Email").fill("invalid@example.test")
    desktop.get_by_label("Password").fill("invalid-password")
    desktop.get_by_role("button", name="Sign in").click()
    expect(desktop.get_by_text("Invalid email or password")).to_be_visible()

Демонструє narrowing до desktop container, user-facing locators і explicit assertion; URL та labels є навчальними placeholders.

Очікуваний результат: Test знаходить лише desktop form і перевіряє повідомлення про невалідний login.

Потрібно: pytest, pytest-playwright, test application with matching accessible labels

48:35

AI як помічник для локаторів

HTML потрібного елемента можна передати AI-помічнику з проханням запропонувати Playwright-локатор. Це корисно на початку, коли синтаксис CSS, XPath і role-локаторів ще незнайомий.

Згенерований код не можна приймати без запуску. AI може запропонувати статичну перевірку або локатор, що знаходить не той вузол. Для UI-тесту зазвичай кращий expect, який очікує потрібного стану й дає змістовну помилку. Кожну пропозицію треба перевіряти в DevTools та реальним тестовим прогоном.

53:05

Налаштування редактора та `requirements.txt`

У PyCharm можна ввімкнути CamelHumps/Camel Words, щоб навігація й виділення працювали за частинами snake_case та інших складених імен.

Для відтворення середовища на іншому комп’ютері або CI версії залежностей фіксуються у requirements.txt:

```bash
pip freeze > requirements.txt
pip install -r requirements.txt
```

pip freeze записує також транзитивні бібліотеки. Автор показує, що список можна звести до прямих залежностей із зафіксованими версіями, якщо команда свідомо підтримує такий формат.

57:20

Підготовка файлів до коміту

Віртуальне середовище .venv не потрібно комітити. Налаштування .idea в уроці також додаються до .gitignore, хоча частина спільних JetBrains-конфігурацій може бути корисною для команди — це слід вирішити явно.

Кольори в Project view показують стан файлів відносно Git. Якщо файл уже потрапив до індексу, просте додавання правила в .gitignore не прибере його автоматично: спочатку його потрібно вилучити з індексу, не видаляючи потрібний локальний вміст.

Що змінилося після запису

`.gitignore` не діє на tracked files

АктуальноЧинна Git documentation прямо зазначає: files already tracked by Git are not affected; їх потрібно окремо вилучити з index, перш ніж ignore pattern запобігатиме повторному додаванню.

Перевірено 2026-07-31

Термін

.gitignore

Versioned список patterns для intentionally untracked files; він не впливає на files, які Git уже відстежує.

1:02:30

Коміт і публікація на GitHub

Перед першим комітом Git запитує ім’я та email автора. Автор радить не встановлювати ці значення глобально, якщо для особистих і робочих репозиторіїв використовуються різні облікові дані.

Після локального коміту проєкт можна опублікувати через Share Project on GitHub, авторизувати PyCharm і створити remote-репозиторій. Коміт і публікація — різні дії: зелений статус файлів показує локальну індексацію/зміни, а наявність remote і push потрібно перевіряти окремо.

Підсумкова стратегія локаторів: обирати читабельні атрибути, які команда може контролювати; домовлятися про них з розробниками; accessibility-, CSS- та XPath-підходи використовувати відповідно до реальної розмітки, а не як догму.

Джерела та додаткові матеріали

  • Locators — Playwright Python ↗Microsoft Playwright · перевірено 2026-07-31

    Описує recommended locators, test ids, CSS/XPath fallback, chaining і strictness.

  • Selectors Level 4 ↗W3C · перевірено 2026-07-31

    Є нормативним джерелом синтаксису CSS selectors та attribute matching.

  • gitignore Documentation ↗Git · перевірено 2026-07-31

    Уточнює, чому tracked file не стає ignored лише після додавання pattern.