Playwright это фреймворк Microsoft для браузерной автоматизации: Chromium, Firefox и WebKit одним API. Есть версии для TypeScript/JavaScript, Python, Java и .NET, но полный тестовый раннер @playwright/test (фикстуры, параллельность, отчёты, трейсы) есть именно в Node. В Python обычно берут pytest с плагином pytest-playwright.
Минимальный тест
import { test, expect } from '@playwright/test';
test('поиск товара', async ({ page }) => {
await page.goto('/');
await page.getByRole('searchbox', { name: 'Поиск' }).fill('чайник');
await page.getByRole('button', { name: 'Найти' }).click();
await expect(page.getByTestId('product-card')).toHaveCount(12);
});
page это фикстура: раннер сам создаёт браузер, изолированный контекст и вкладку, а после теста всё закрывает.
Браузер, контекст, страница
- Browser: запущенный процесс браузера, дорогой ресурс, переиспользуется воркером.
- BrowserContext: изолированная сессия, как профиль в режиме инкогнито: свои куки, localStorage, кеш. Создаётся за миллисекунды. Каждый тест получает новый контекст, поэтому тесты не делят состояние.
- Page: вкладка внутри контекста.
Автоожидание и web-first assertions
Перед действием Playwright ждёт, что элемент видим, стабилен, получает события и включён. Проверки expect(locator) повторяются до таймаута:
await expect(page.getByText('Заказ оформлен')).toBeVisible(); // ждёт до 5 с по умолчанию
expect(await page.getByText('Заказ оформлен').isVisible()).toBe(true); // снимок, без ожидания
Вторая строка частая ошибка: isVisible() возвращает состояние в момент вызова, и тест флакает. Таймауты по умолчанию: 30 секунд на тест, 5 секунд на expect.
Ещё полезно: expect.soft (проверка не прерывает тест), expect.poll (опрос произвольной функции, например API), expect(page).toHaveScreenshot() (скриншотное сравнение).
Фикстуры
Свои фикстуры объявляются через test.extend:
export const test = base.extend<{ cartPage: CartPage }>({
cartPage: async ({ page }, use) => {
const cart = new CartPage(page);
await cart.open();
await use(cart); // здесь выполняется тест
await cart.clear(); // teardown
},
});
Фикстура создаётся только если тест её запросил. Бывают фикстуры уровня теста и уровня воркера ({ scope: 'worker' }).
Авторизация один раз
Логин через UI в каждом тесте дорог. Типовой рецепт: setup-проект логинится и сохраняет storageState (куки и localStorage) в файл, остальные проекты зависят от него (dependencies) и стартуют уже авторизованными.
Сеть
page.route('**/api/products', route => route.fulfill({ json: [...] }))подменяет ответ.- Фикстура
requestделает API-запросы без браузера: удобно готовить данные. page.waitForResponse(...)ждёт конкретный ответ.
Параллельность и конфиг
playwright.config.ts: projects (браузеры, устройства), workers, fullyParallel, retries, use: { baseURL, trace, screenshot, video }. По умолчанию файлы распределяются по воркерам, тесты внутри файла идут последовательно; fullyParallel: true распараллеливает и их. Для CI есть --shard=1/4.
Отладка
npx playwright codegenзаписывает действия в код.--uiрежим и--debugс инспектором.- Трейс (
trace: 'on-first-retry'): шаги, снимки DOM, сеть, консоль. Открываетсяnpx playwright show-trace.
Частые ошибки
page.waitForTimeout(3000)вместо ожидания состояния.isVisible(),textContent()иcount()вexpect(...)вместо web-first assertions.- Логин через UI в каждом тесте.
- Общие данные между тестами при
fullyParallel.
Что спросят на собесе
- Чем Playwright отличается от Selenium?
- Что такое BrowserContext и зачем он нужен?
- Как работает автоожидание и чем
toBeVisibleлучшеisVisible? - Как сделать авторизацию один раз на весь прогон?
- Как мокать сеть и как отлаживать упавший в CI тест?