2.1. Storage state: практична реалізація, фікстури для ролей
Додатковий урок перетворює `storage state` на практичну систему fixtures для різних ролей або тарифів. На прикладі Enterprise і Free проєктів показано, як дослідити фактичну ознаку активного проєкту, створити окремі states, передати їх у `BrowserContext`, забезпечити fallback для чистого запуску й не відкривати зайві сторінки.
Примітка: конспект укладено за автоматичними українськими субтитрами; терміни Playwright, pytest, JSON і browser storage нормалізовано за контекстом відео.
Після цього уроку ви зможете
Створювати окремі Playwright states для ролей, тарифів або tenants.
Будувати незалежну pytest fixture з fallback для чистого запуску.
Повертати вже підготовлену page без зайвого browser context або вкладки.
Якщо функціональність залежить від ролі, тарифу або tenant, тести доцільно групувати за відповідним станом користувача. У прикладі один акаунт має доступ до Enterprise і Free проєктів, але в реальній системі це можуть бути окремі користувачі.
Перед реалізацією досліджується UI, Network, cookies та local storage. Перемикання проєкту змінює Company ID; додатковими спостережуваними ознаками є тексти Enterprise subscription і Free subscription.
Що змінилося після запису
State не замінює ізоляцію server-side даних
У відеоУрок оптимізує login через повторне використання стану одного користувача для кількох тестів.
АктуальноPlaywright гарантує ізоляцію browser contexts, але спільний акаунт і його backend data залишаються спільними; незалежність та regeneration простроченого state треба забезпечувати на рівні проєкту.
Перевірено 2026-07-31
Термін
role-specific state
Окремий auth state для конкретної ролі або tenant, який передається під час створення нового browser context.
Tooltip із назвою тарифу з’являється після hover, тому тест спочатку знаходить стабільний label, виконує hover і лише потім перевіряє текст підписки. DOM/attribute breakpoints допомагають зрозуміти, який компонент створює анімацію.
Повторювані елементи Enterprise і Free додаються в page object, а тест перевіряє стан до та після select_company. Це формує observable contract, на який можна спертися під час оптимізації авторизації.
Самого запису state недостатньо: шлях треба передати в browser.new_context(storage_state=...). Browser options збираються у dictionary, який доповнюється лише тоді, коли шлях передано і файл існує.
Урок порівнює два JSON states після перемикання проєкту. Окрім Company ID, можуть змінюватися timestamps, analytics cookies і backend session, тому ручне припущення про «єдину різницю» треба перевіряти, а не приймати наперед.
Перший варіант дублює Enterprise state й через стандартний модуль json очищає cookie Company ID. Пошук проходить масив cookies, змінює лише елемент із потрібним name і записує окремий файл.
Цей підхід є оптимізацією для конкретного застосунку, а не універсальним правилом Playwright. Якщо backend session або інший state також прив’язаний до tenant, безпечніше реально перемкнути проєкт у браузері й зберегти отриманий context.
free_project_context відкриває context із Free state, а тест одразу перевіряє Free UI без login та ручного switch. Перший запуск виявляє проблему: fixture залежить від того, що інший тест уже створив файл авторизації.
Тести не повинні залежати від порядку. Якщо state існує — він завантажується; якщо ні — fixture виконує login, перемикає проєкт, перевіряє Free plan і зберігає state сама.
Увага
Тест не повинен залежати від порядку
Free fixture мусить сама створити state, якщо файл відсутній; запуск окремого тесту після очищення локальних state-файлів є обов’язковою перевіркою.
Термін
test isolation
Playwright ізолює cookies, local storage і session storage між browser contexts; повторне використання state є явним винятком, який тест має контролювати.
Практика
Доказ незалежності Free fixture
Видаліть локальні state-файли.
Запустіть лише один Free test і перевірте створення state через fallback.
Запустіть той самий тест вдруге й перевірте повторне використання state без другої page.
Результат: Обидва запуски проходять окремо; перший створює state, другий його використовує, одночасно відкрита одна page.
Fallback будує context, створює page, авторизується, переходить до Free проєкту й записує storage_state. Після цього та сама page передається тесту через yield, щоб сценарій продовжився без повторного відкриття вкладки.
Під час демонстрації код кілька разів дублюється для швидкої перевірки, а потім уточнюється. Ключовий критерій — окремий Free test має проходити самостійно після видалення всіх локальних state-файлів.
Термін
yield fixture
pytest fixture виконує setup до yield, передає значення тесту, а cleanup після yield виконує під час teardown.
Зайва сторінка з’явилася через те, що fixture створювала context.new_page() вдруге замість повернення вже авторизованої page. Після виправлення один context і одна page проходять увесь setup та test lifecycle.
Друга помилка — інвертована умова not exists, через яку готовий state не використовувався. Перевірка маленьких умов, точного path і фактичного returned object часто швидше знаходить root cause, ніж повторний великий рефакторинг.
Загальні сценарії, наприклад login, залишаються спільними. Перевірки, залежні від тарифу, розкладаються в окремі packages для Free та Enterprise, кожен зі своєю fixture.
Підсумкова схема: на першому чистому запуску state створюється; надалі він перевикористовується; page не перестворюється; кожен тест може запускатися окремо. Зміни комітяться з номером задачі та коротким описом storage, page initialization і структури suites.