Налаштовуємо PyCharm під щоденну роботу з Python і Playwright: використовуємо безпечні рефакторинги, навігацію, власні скорочення, postfix templates, live templates і file templates. Мета — прибрати повторюваний ручний набір коду та отримати швидкий, передбачуваний процес, який не залежить від якості відповіді ШІ.
Після цього уроку ви зможете
Застосовувати Introduce Variable, Rename та Extract Method через рефакторинги PyCharm.
Розрізняти postfix template, live template і file template та вибирати найменший механізм для повторюваної дії.
Створювати власні шаблони для Playwright locators, assertions, Page Object і тестових файлів.
Налаштовувати keymap під свою ОС, не прив’язуючи процес до комбінацій клавіш викладача.
Перевіряти згенерований шаблоном код на реальному тестовому сценарії.
Можливості IDE варто сприймати як частину інженерної практики, а не як набір необов’язкових трюків. Скорочення й шаблони допомагають стандартизувати повторювані дії так само, як KISS, DRY, YAGNI, патерни та SOLID стандартизують роботу з кодом.
На відміну від генерації коду за допомогою ШІ, налаштована команда IDE виконує наперед визначене перетворення. Вона не вигадує API й щоразу дає той самий результат. Перш ніж додавати автоматизацію, корисно певний час писати конструкції вручну: це формує розуміння функцій, викликів, контексту й оператора ..
На прикладі повторюваних рядків показано Refactor → Introduce Variable: PyCharm створює змінну з виділеного виразу й може замінити всі його входження. У демонстрації на macOS використовується ⌘⌥V; на Windows або Linux слід дивитися актуальне скорочення безпосередньо в меню IDE. Так само винесено повторювані значення classical і BDD у зрозуміло названі змінні.
IDE підсвічує невикористаний код сірим, тому зайві параметри й імпорти можна швидко знаходити та видаляти. Окрема команда оптимізує імпорти після змін.
Для навігації показано:
- ⌘B — перейти до оголошення або реалізації символу під курсором; - ⌘⌥← і ⌘⌥→ — повернутися до попереднього місця редагування або перейти вперед; - перехід на початок чи кінець рядка замість ручного руху курсора.
Головна звичка: спочатку шукати дію в контекстному меню й дивитися її назву та скорочення, а вже потім за потреби змінювати keymap.
Увага
Shortcuts залежать від keymap
Комбінації клавіш у відео показані на macOS і частково налаштовані автором. Знаходьте дію за назвою в меню або Settings → Keymap і перевіряйте локальну комбінацію та конфлікти.
У браузерних DevTools вмикається режим вибору елемента на сторінці. Після кліку потрібний вузол одразу знаходиться в HTML, де можна перевірити унікальність майбутнього селектора. У прикладі селектор має знаходити рівно один елемент.
Ручний процес — скопіювати значення, повернутися в PyCharm і загорнути його в page.locator(...) — повторюється багато разів. Це хороший кандидат для локального шаблону: структура виклику стабільна, а змінюється лише селектор.
Postfix Completion налаштовується через Settings (⌘, на macOS). Postfix template застосовується до виразу ліворуч від крапки. Спеціальна змінна $EXPR$ означає цей вираз, а $END$ визначає, де залишиться курсор після розгортання.
Створено кілька Python-шаблонів:
- "selector".locator перетворює селектор на page.locator("selector"); - вираз із postfix expect обгортається в expect(...); - скорочений варіант на кшталт expvis одразу створює expect(...).to_be_visible().
Під час першого налаштування locator вираз помилково був додатково взятий у лапки, через що PyCharm формував неправильний код. Після виправлення $EXPR$ підставляється як готовий вираз. Це важливе правило: шаблон має додавати лише відсутню структуру, а не повторно форматувати вже валідний фрагмент.
Такий ланцюжок скорочує типовий шлях до перевірки: знайти селектор, вставити його як рядок, застосувати .locator, а потім .expvis. Результат детермінований і не потребує повторної перевірки припущень генеративної моделі.
Термін
Postfix template
Шаблон PyCharm, який за ключем після крапки перетворює вже введений вираз з урахуванням його типу та контексту.
Термін
$EXPR$ і $END$
$EXPR$ підставляє вираз, до якого застосовано custom postfix template; $END$ задає позицію курсора після завершення перетворення.
Приклад коду
Target expression для postfix locator
page.locator($EXPR$)$END$
Мінімальна target expression для custom postfix template: готовий вираз підставляється через $EXPR$, а курсор після розгортання переходить у $END$.
Очікуваний результат: Вираз ліворуч від postfix перетворюється на аргумент page.locator(...).
Потрібно: PyCharm with Python support
Практика
Створити два postfix templates
Створіть Python postfix template locator, який обгортає вираз у page.locator(...).
Створіть postfix template expvis для expect(...).to_be_visible().
Перевірте обидва шаблони на трьох різних селекторах і переконайтеся, що лапки не дублюються.
Результат: Кожен шаблон стабільно створює синтаксично валідний Python-код, а курсор залишається в очікуваному місці.
Окремий postfix template експериментально перетворює вираз на присвоєння змінній. Він корисний лише тоді, коли справді економить дії; якщо шаблон незручно визначає позицію курсора або працює не для всіх виразів, його краще спростити чи не використовувати.
⌥Enter відкриває intention actions для поточного контексту. У меню можна рухатися клавішами й вибирати, наприклад, перейменування елемента. Перейменування через IDE змінює всі пов’язані входження, тому безпечніше за ручний пошук і заміну.
Refactor → Extract Method (⌘⌥M у показаному keymap) переносить виділений фрагмент у новий метод. PyCharm визначає потрібні аргументи й можливі значення, що повертаються. У прикладі перевірки кнопки винесено в check_manage_button, після чого до викликів усередині методу додано self. Це спосіб прибрати дублювання на рівні поведінки, не переписуючи код вручну.
Практичне зауваження з демонстрації: to_have_text() не варто вважати повною заміною перевірки видимості. Якщо видимість є окремою вимогою сценарію, її треба перевіряти явно.
Створення Page Object постійно починається з нового Python-файлу. У Project view командою ⌘N відкривається меню New, яке можна фільтрувати простим набором Python і вибрати Python File або Python Package без мишки.
Щоб скоротити шлях ще більше, у Settings → Keymap знайдено відповідні дії й призначено власні комбінації: одну для Python-файлу, іншу для Python-пакета. Конкретні клавіші не є універсальним стандартом — їх слід обирати під власну ОС і перевіряти на конфлікти в keymap.
У меню створення також видно вбудовані шаблони на кшталт Python unit test. Вони демонструють наступний рівень автоматизації: IDE може створювати не порожній файл, а одразу потрібну початкову структуру.
Page Object і Page Component мають повторювану основу: імпорти Playwright, клас, __init__, збереження page, базову перевірку завантаження та часто return self. Замість копіювання цієї «шапки» створено власний шаблон у Settings → Editor → File and Code Templates.
У file template змінна ${NAME} підставляє назву, яку вводять під час створення файлу. Після збереження в меню New з’являється окремий тип Page Object; вибір цього пункту створює клас з підготовленими імпортами й методами.
Під час live coding шаблон кілька разів виправляється: додаються пропущені self, закривається дужка, коригуються відступи. Це нормальний цикл налаштування: створити пробний файл, дочекатися синтаксичних та інспекційних підказок IDE, виправити шаблон і повторити генерацію. Перевіряти потрібно саме згенерований файл, а не лише текст у вікні налаштувань.
Оскільки поточні Page Object і Page Component мають однакову основу, одного file template достатньо. Окремі шаблони варто додавати лише тоді, коли їхня структура реально розійдеться.
Термін
File template
Шаблон PyCharm для створення нового файла з визначеними назвою, розширенням і початковим вмістом. Project-scoped templates зберігаються в .idea/fileTemplates і можуть бути спільними для команди.
Практика
Створити file template для Page Object
Створіть custom file template з імпортом Page, класом, __init__, self.page і return self.
Використайте ${NAME} для назви створюваного класу або файла.
Створіть пробний Page Object і виправте всі syntax та inspection errors у самому шаблоні.
Результат: Новий Page Object створюється одним пунктом меню та не містить syntax або unresolved reference errors.
Під час пошуку елементів для наступного тесту видно, наскільки якість HTML впливає на автоматизацію. У модальному вікні частина елементів не має зручних семантичних ознак, стабільних назв або доступних ролей. Через це доводиться розглядати id, текст, структуру div і Accessibility Tree.
Кращий локатор спирається на доступну роль, ім’я або іншу стабільну продуктову ознаку. CSS-класи оформлення, випадкові вкладені контейнери й пробіли в тексті — крихка основа. Якщо елемент важко однозначно знайти, це може бути не лише проблемою тесту, а й сигналом недостатньої доступності чи тестованості інтерфейсу.
Після дослідження обирається невеликий реальний сценарій: створити сутність через кнопку, заповнити назву й перевірити наступний стан. Саме повторювані частини цього сценарію далі перетворюються на live templates.
Термін
Role locator
Playwright locator, який знаходить елемент за доступною роллю та зазвичай accessible name. Офіційна документація радить пріоритезувати user-facing attributes і explicit contracts на кшталт get_by_role().
Приклад коду
Role locator і видимість діалогу
from playwright.sync_api import Page, expect
def test_create_suite_dialog(page: Page) -> None:
page.get_by_role("button", name="Create suite").click()
expect(page.get_by_text("Select suite for test")).to_be_visible()
Мінімальний приклад Codex на основі актуального Playwright contract: інтерактивна кнопка знаходиться за role та accessible name, а неінтерактивний текст перевіряється через get_by_text().
Очікуваний результат: Після кліку на Create suite текст Select suite for test стає видимим.
Потрібно: pytest, pytest-playwright, playwright
Практика
Замінити крихкий локатор на user-facing locator
Знайдіть у власному тесті інтерактивний елемент, який зараз шукається за CSS-класом або вкладеною структурою.
Перевірте його role та accessible name у Accessibility Tree.
Замініть локатор на get_by_role(..., name=...) і запустіть цільовий тест.
Результат: Локатор однозначно знаходить потрібний елемент, а тест проходить без nth(), first або прив’язки до CSS оформлення.
На відміну від postfix template, Live Template розгортається в місці курсора з короткої абревіатури. У Settings створюється окрема група шаблонів для проєкту або Playwright, а контекст обмежується Python-файлами. Це не дає шаблону випадково з’являтися в нерелевантних типах файлів.
У шаблоні методу використовуються змінні для назви функції, аргументів або локатора та $END$ для фінальної позиції курсора. Після розгортання Tab переходить між редагованими полями. Якщо автоматичне перетворення назви в snake_case не працює передбачувано, простіше залишити явне введення назви, ніж ускладнювати шаблон.
На основі реального сценарію створено заготовку методу, який приймає дані, знаходить елемент через self.page.locator(...), виконує дію й повертає self. Потім метод перейменовується рефакторингом IDE, щоб назва оновилась і в оголошенні, і у виклику.
Термін
Live template
Шаблон коду, який вставляє наперед визначену конструкцію в позиції курсора; на відміну від postfix completion, він не потребує наявного виразу для перетворення.
Для частих операцій створюються малі шаблони, кожен з яких прибирає конкретний повторюваний фрагмент:
- page.pause() для зупинки тесту й дослідження стану; - заготовка методу Page Object із параметром і локатором; - self.page.get_by_role(...) з курсором на ролі та подальших аргументах; - виклик потрібного локатора з .click(); - очікування expect(button).to_be_hidden() після відправлення форми.
Шаблон get_by_role дає виграш не кількістю згенерованого коду, а тим, що не треба щоразу набирати self.page, назву методу й дужки. Після розгортання залишається вибрати роль, наприклад button, і вказати доступне ім’я.
Також показано запуск поточного тесту зі скорочення та переміщення цілого statement вгору або вниз (⌘⇧↑ / ⌘⇧↓ у демонстрації). Якщо комбінації в локальному keymap інші, дію слід знайти за назвами Move Statement Up і Move Statement Down.
Після кліку тест очікує зникнення кнопки. Це робить перехід до наступної сторінки явним: подальші дії починаються лише після підтвердженої зміни стану.
Для унікальної назви використовується Faker. Вираз із назвою компанії перетворюється на змінну через створений postfix template, змінна перейменовується на змістовну target_suite_name і передається в метод створення.
Непотрібні вбудовані postfix templates можна вимикати, щоб список підказок не заважав. Водночас експеримент із власним .var показує межу автоматизації: якщо шаблон не залишає курсор у корисному місці, його треба виправити, а не пристосовувати робочий процес до невдалого шаблону.
Сценарій запускається й проходить послідовно: авторизація, створення проєкту, закриття README, відкриття діалогу створення тесту. У режимі паузи перевіряється DOM і вибирається текст Select suite for test; для нього додається шаблон get_by_text(...), після чого expect(...).to_be_visible() підтверджує появу модального вікна.
Якщо попередній debug-процес ще приєднаний, повторний запуск може чекати на його завершення. Після коректного продовження або зупинки процесу тест проходить. Наприкінці тест перейменовується відповідно до перевірюваної поведінки, а не до проміжних технічних кроків.
Після успішного запуску тест перейменовується відповідно до перевірюваної поведінки. Для ще одного повторюваного фрагмента створюється простий live template, який розгортається в return self. Це підтримує ланцюжкові виклики Page Object без повторного ручного набору.
Плагіни не є основою цього процесу. У викладача встановлений Junie, але частіше для окремих задач використовується Claude Code. Головний приріст швидкості в уроці дають штатні засоби PyCharm: пошук у Settings, keymap, рефакторинги та шаблони. Параметри сторонніх плагінів варто змінювати лише під реальну потребу.
Підсумкова модель трьох механізмів:
- **postfix template** застосовується після виразу через крапку та обгортає або перетворює цей вираз; - **live template** розгортає за абревіатурою блок коду в позиції курсора; - **file template** створює новий файл із готовою структурою.
На практиці postfix зручний для locator або expect, live template — для page.pause(), get_by_role() і повторюваних методів, а file template — для Page Object. Ці механізми доповнюють один одного й не потребують зовнішнього генератора.
Останній приклад — file template для нового Playwright-тесту. У ньому заздалегідь зберігається типова шапка: імпорти, базова структура тесту, потрібні фікстури та місце, де після створення файла має залишитися курсор. Назву тестової функції зрештою залишено для явного введення: автоматичне формування з назви файла не дало достатньо зручного результату.
Після вибору нового типу файла в меню PyCharm створює готовий каркас, у якому можна відразу ініціалізувати потрібний Page Object і продовжити сценарій. Це завершує повний шлях автоматизації: file template створює структуру, live templates додають типові блоки, postfix templates перетворюють окремі вирази, а штатні рефакторинги безпечно змінюють уже написаний код.
Практичний порядок впровадження:
1. Виписати дії та конструкції, які повторюються щодня. 2. Для кожної обрати найменший механізм: shortcut, postfix, live або file template. 3. Обмежити шаблон потрібною мовою чи контекстом. 4. Перевірити згенерований код на реальному сценарії. 5. Вимкнути невикористовувані шаблони й залишити лише ті, що справді прискорюють роботу.
Налаштування IDE має зменшувати кількість механічних дій, але не приховувати зміст коду. Експериментувати варто поступово: додавати один шаблон під реальне повторення, користуватися ним у роботі й лише тоді переходити до наступного.