playwright.config.ts задаёт таймаут теста, количество повторов, число параллельных воркеров, поведение трейсинга и base URL для всего сьюта. Дефолты от npm init playwright@latest работают локально, но у них два CI-подводных камня: workers: undefined вызывает конкуренцию за ресурсы на общих раннерах, а отсутствие forbidOnly: !!process.env.CI позволяет случайно закоммиченному test.only() тихо пропустить весь сьют. Эта статья разбирает каждую опцию которую используешь в реальном проекте и заканчивается готовым к продакшну конфигом с настройкой аутентификации, URL под разные окружения и отдельными репортерами для локальной разработки и CI.
Минимальный конфиг
После npm init playwright@latest получишь что-то вроде:
import { defineConfig, devices } from '@playwright/test';
export default defineConfig({
testDir: './tests',
fullyParallel: true,
forbidOnly: !!process.env.CI,
retries: process.env.CI ? 2 : 0,
workers: process.env.CI ? 1 : undefined,
reporter: 'html',
use: {
baseURL: 'http://localhost:3000',
trace: 'on-first-retry',
},
projects: [
{ name: 'chromium', use: { ...devices['Desktop Chrome'] } },
{ name: 'firefox', use: { ...devices['Desktop Firefox'] } },
{ name: 'webkit', use: { ...devices['Desktop Safari'] } },
],
});Разберём каждую секцию.
Верхнеуровневые опции
testDir
Где Playwright ищет тест-файлы.
testDir: './tests',Относительный или абсолютный путь. Файлы по маскам /.spec.ts и /.test.ts внутри этой папки подхватываются автоматически.
fullyParallel
fullyParallel: true,При true: все тесты запускаются параллельно на воркерах, даже тесты в одном файле. При false (прежний дефолт): тесты внутри файла запускаются последовательно, но разные файлы в параллели.
Для большинства проектов ставь true. Тесты должны быть достаточно независимы, чтобы работать в любом порядке.
forbidOnly
forbidOnly: !!process.env.CI,Если тест помечен test.only(), весь прогон завершится с ошибкой. Паттерн !!process.env.CI применяет это правило только в CI: локально можно использовать test.only() при отладке, но случайно его закоммитить не получится.
Всегда добавляй в продакшн-конфиги.
retries
retries: process.env.CI ? 2 : 0,Сколько раз повторять упавший тест перед тем как признать его провальным. В CI: 2 повтора (помогает с флакующими тестами). Локально: 0 (чтобы сразу видеть падения).
Если тест падает с первого раза но проходит при повторе, Playwright помечает его как "flaky" в отчёте.
workers
workers: process.env.CI ? 1 : undefined,Количество параллельных воркеров (экземпляров браузера): undefined (дефолт) использует 50% ядер CPU, 1 запускает все тесты последовательно (полезно в CI чтобы избежать конкуренции за ресурсы), 4 означает 4 параллельных воркера.
Для локальной разработки на мощной машине undefined подходит. В CI безопаснее 1, если только раннер не особо производительный.
timeout
timeout: 30_000, // 30 секунд на тестМаксимальное время выполнения одного теста. Дефолт: 30 секунд. Для медленных тестов или медленных CI-машин увеличивай до 60 секунд.
expect.timeout
expect: {
timeout: 5_000, // 5 секунд на каждый expect()
},Ассёрты в Playwright повторяются автоматически: до выполнения условия или до истечения таймаута. Дефолт: 5 секунд.
Блок use (общие настройки тестов)
use содержит опции которые применяются ко всем тестам (если не переопределены проектом).
use: {
baseURL: 'http://localhost:3000',
// Настройки браузера
headless: true,
viewport: { width: 1280, height: 720 },
// Запись
trace: 'on-first-retry', // 'on-first-retry' | 'retain-on-failure' | 'always' | 'off'
video: 'retain-on-failure', // 'retain-on-failure' | 'always' | 'off'
screenshot: 'only-on-failure',
// Таймауты
actionTimeout: 10_000, // таймаут для каждого действия (click, fill и т.д.)
navigationTimeout: 30_000, // таймаут для page.goto() и page.waitForURL()
// HTTP
ignoreHTTPSErrors: true, // полезно для staging с самоподписанными сертификатами
// Локаль
locale: 'en-US',
timezoneId: 'America/New_York',
},baseURL
Когда задан, page.goto('/login') разрешается в http://localhost:3000/login. Делает тесты переносимыми между окружениями.
Используй переменную окружения:
baseURL: process.env.BASE_URL || 'http://localhost:3000',trace
Трейсы Playwright записывают полную историю каждого действия: снимки DOM, скриншоты, сетевые запросы. Опции:
'on-first-retry': записывает при первом повторе упавшего теста. Рекомендуется.'retain-on-failure': записывает при любом провале (больше места на диске)'always': записывает всё (много места, медленнее)'off': без трейсов
Просмотр: npx playwright show-trace trace.zip.
video
'retain-on-failure' сохраняет видео только для упавших тестов (рекомендуется), 'always' сохраняет всё, 'off' отключает запись.
projects: несколько конфигураций браузеров
Проекты позволяют запускать одни и те же тесты в разных браузерах, с разными вьюпортами или конфигурациями.
projects: [
// Десктопные браузеры
{
name: 'chromium',
use: { ...devices['Desktop Chrome'] },
},
{
name: 'firefox',
use: { ...devices['Desktop Firefox'] },
},
{
name: 'webkit',
use: { ...devices['Desktop Safari'] },
},
// Мобильные
{
name: 'mobile-chrome',
use: { ...devices['Pixel 7'] },
},
{
name: 'mobile-safari',
use: { ...devices['iPhone 14'] },
},
],devices['Desktop Chrome']: пресет с заданным вьюпортом, user agent и другими браузерными дефолтами. Полный список смотри через npx playwright show-report или в документации Playwright.
Проекты для разных окружений
projects: [
{
name: 'staging',
use: {
...devices['Desktop Chrome'],
baseURL: 'https://staging.myapp.com',
},
testMatch: '**/*.spec.ts',
},
{
name: 'production',
use: {
...devices['Desktop Chrome'],
baseURL: 'https://myapp.com',
},
testMatch: '**/smoke/*.spec.ts', // только smoke-тесты в продакшне
},
],Setup-проекты (глобальная подготовка)
projects: [
{
name: 'setup',
testMatch: /.*\.setup\.ts/, // файлы вроде auth.setup.ts
},
{
name: 'chromium',
use: { ...devices['Desktop Chrome'] },
dependencies: ['setup'], // сначала запускает setup
},
],Используется для однократного выполнения аутентификации перед всеми тестами с сохранением auth-состояния.
reporter
Формат вывода результатов тестов:
reporter: [
['html'], // HTML-отчёт в playwright-report/
['junit', { outputFile: 'results.xml' }], // JUnit XML для CI
['list'], // вывод в консоль в реальном времени
],Для локальной разработки 'html' отлично подходит: открываешь playwright-report/index.html и получаешь полный визуальный отчёт. В CI добавляй 'junit': GitHub Actions, GitLab CI и Jenkins умеют его парсить.
globalSetup и globalTeardown
Для подготовки которая выполняется один раз перед всем сьютом:
globalSetup: './global-setup.ts',
globalTeardown: './global-teardown.ts',// global-setup.ts
import { chromium } from '@playwright/test';
export default async function globalSetup() {
const browser = await chromium.launch();
const page = await browser.newPage();
// логинимся и сохраняем auth-состояние
await page.goto('http://localhost:3000/login');
await page.fill('[data-testid="email"]', 'admin@test.com');
await page.fill('[data-testid="password"]', 'AdminPass1');
await page.click('[data-testid="submit"]');
await page.context().storageState({ path: 'auth.json' });
await browser.close();
}Тесты используют сохранённое auth-состояние без повторного входа:
use: {
storageState: 'auth.json',
},Готовый конфиг для продакшна
import { defineConfig, devices } from '@playwright/test';
import dotenv from 'dotenv';
dotenv.config();
export default defineConfig({
testDir: './tests',
fullyParallel: true,
forbidOnly: !!process.env.CI,
retries: process.env.CI ? 2 : 0,
workers: process.env.CI ? 2 : undefined,
timeout: 45_000,
expect: { timeout: 8_000 },
reporter: [
['html'],
...(process.env.CI ? [['junit', { outputFile: 'test-results/results.xml' }] as const] : []),
],
use: {
baseURL: process.env.BASE_URL || 'http://localhost:3000',
trace: 'on-first-retry',
video: 'retain-on-failure',
screenshot: 'only-on-failure',
actionTimeout: 10_000,
navigationTimeout: 30_000,
},
projects: [
{
name: 'setup',
testMatch: /auth\.setup\.ts/,
},
{
name: 'chromium',
use: {
...devices['Desktop Chrome'],
storageState: 'playwright/.auth/user.json',
},
dependencies: ['setup'],
},
{
name: 'api',
testMatch: '**/api/**/*.spec.ts',
use: { storageState: undefined }, // API-тестам не нужна браузерная авторизация
},
],
});Запуск конкретных проектов
# все тесты в chromium
npx playwright test --project=chromium
# только setup-проект
npx playwright test --project=setup
# несколько проектов
npx playwright test --project=chromium --project=firefoxГлавные опции: шпаргалка
| Опция | Рекомендация |
|-------|--------------|
| testDir | './tests' |
| fullyParallel | true |
| forbidOnly | !!process.env.CI |
| retries | CI ? 2 : 0 |
| timeout | 30_000–60_000 |
| trace | 'on-first-retry' |
| video | 'retain-on-failure' |
| baseURL | из переменной окружения |
| reporter | HTML локально, + JUnit в CI |