Фікстура — це готовий ресурс який Playwright сам підготував і передав у тест. Ти просто називаєш що тобі потрібно — і отримуєш це готовим. Після тесту Playwright сам прибирає.
Аналогія з рестораном: ти не ходиш на кухню щоб взяти тарілку — офіціант приносить її сам. Ти просто замовляєш “мені потрібна тарілка” і отримуєш готову. Fixture — це той офіціант.
У коді це виглядає так: коли пишеш async ({ page }) — ти не створюєш page сам. Playwright читає ключ деструктуризації page, розуміє що тобі потрібна вкладка, і підставляє готову. Важливо: Playwright дивиться на ключ об’єкта, а не на ім’я локальної змінної. Тому async ({ page: myPage }) працює так само — fixture key залишається page, просто локальна змінна перейменована на myPage.
Це схоже на Dependency Injection (DI) — патерн з бекенд-розробки. DI означає: “не створюй залежності сам — отримай їх ззовні”. Замість того щоб писати new Database() всередині класу — клас отримує вже готовий об’єкт бази даних через конструктор або параметр. Так само тест отримує готову page через параметр функції — не сам її створює.
TypeScript
// test() — функція з параметрами "за домовленістю", як DI
test('приклад', async ({ page }) => {
// "page" — ключ в об'єкті fixtures, Playwright розпізнає
// це ім'я і підставляє відповідний готовий ресурс
await page.goto('/login');
});
// Тобі НЕ треба робити це вручну:
// const browser = await chromium.launch();
// const context = await browser.newContext();
// const page = await context.newPage();
// ... тест ...
// await page.close();
// await context.close();
// Playwright робить усе це сам, і сам же прибирає після тесту
// Вбудовані фікстури з різним життєвим циклом:
// page → нова для КОЖНОГО тесту
// context → нова для КОЖНОГО тесту (page живе всередині неї)
// browser → одна на ВЕСЬ файл / прогін (дорого перестворювати)
💡 Простими словами: уяви, що фікстура — це офіціант, який сам приносить тобі чисту тарілку перед їжею і сам забирає брудну після, без твоєї участі. Ти просто кажеш “мені потрібна тарілка” (називаєш page у деструктуризації) — і не думаєш про те, звідки вона взялась і хто її помиє.
🔧 TypeScript / JS патерни в цьому прикладіasync ({}, use) => {} — стрілочна async функція з двома параметрами, перший — порожня деструктуризація (нам не потрібні інші fixtures); await use(value) — use це callback-функція яку ми викликаємо щоб “передати” ресурс в тест і “призупинити” fixture; все що до use() — setup, після — teardown.
🗣 Як читати вголосФікстура — це готовий ресурс, який Playwright сам готує і передає в тест перед його запуском, а потім сам прибирає після. Технічно, коли ми пишемо async ({ page }) => {...}, page — це не просто змінна, а ключ в об’єкті fixtures, який Playwright розпізнає по імені і підставляє відповідний ресурс. У Playwright є вбудовані фікстури: page, context, browser, request для API-тестів — кожна зі своїм життєвим циклом, наприклад page створюється заново для кожного тесту, а browser — worker-scoped: один браузерний процес на весь worker. При 4 workers — 4 браузерних процеси. Це той самий принцип, що dependency injection в бекенд-фреймворках: ми кажемо “мені потрібен page” просто назвавши його в деструктуризації — і Playwright за лаштунками вирішує, як саме його зібрати, коли створити і коли знищити. Нам не треба писати new Page() чи закривати її вручну. Сила фікстур ще й у тому, що можна створювати власні — наприклад, кастомна фікстура authenticatedPage бере базову page, логінить юзера через storageState, і вже залогінену сторінку віддає в тест; тест просто пише async ({ authenticatedPage }) => {...} і не думає про логін взагалі.