Skip to main content

Configuration File

Playwright Test uses a configuration file named playwright.config.ts at the project root:
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'] },
    },
  ],
});

Configuration Options

The configuration is defined in src/common/config.ts:42-149. Here are the key options:

Test Discovery

testDir
string
default:"'.'"
Directory where test files are located
testDir: './e2e'
testMatch
string | RegExp | Array
default:"'**/*.@(spec|test).?(c|m)[jt]s?(x)'"
Pattern to match test files
testMatch: '**/*.spec.ts'
testIgnore
string | RegExp | Array
default:"[]"
Pattern to ignore test files
testIgnore: '**/node_modules/**'

Execution Control

workers
number | string
default:"'50%'"
Number of concurrent worker processesFrom src/common/config.ts:121:
workers: 4,           // Fixed number
workers: '50%',       // Percentage of CPU cores
workers: undefined,   // Auto-detect based on CPU
fullyParallel
boolean
default:"false"
Run all tests in parallelFrom src/common/config.ts:102:
fullyParallel: true
forbidOnly
boolean
default:"false"
Fail if test.only is encountered
forbidOnly: !!process.env.CI
maxFailures
number
default:"0"
Maximum number of test failures before stoppingFrom src/common/config.ts:108:
maxFailures: 10  // Stop after 10 failures

Timeouts

timeout
number
default:"30000"
Timeout for each test in millisecondsFrom src/common/config.ts:40,199:
export const defaultTimeout = 30000;  // 30 seconds

timeout: 60000  // 60 seconds
globalTimeout
number
default:"0"
Maximum time for the entire test runFrom src/common/config.ts:105:
globalTimeout: 60 * 60 * 1000  // 1 hour
expect.timeout
number
default:"5000"
Timeout for expect assertions
use: {
  expect: {
    timeout: 10000  // 10 seconds for assertions
  }
}

Retries

retries
number
default:"0"
Number of retry attempts for failed testsFrom src/common/config.ts:192:
retries: 2  // Retry failed tests twice
repeatEach
number
default:"1"
Number of times to repeat each testFrom src/common/config.ts:191:
repeatEach: 3  // Run each test 3 times

Filtering

grep
RegExp | Array<RegExp>
default:"/.*/"
Filter tests by titleFrom src/common/config.ts:106-107:
grep: /login/,              // Run tests matching "login"
grep: [/@smoke/, /@fast/],  // Multiple patterns
grepInvert
RegExp | Array<RegExp>
default:"null"
Exclude tests by title
grepInvert: /@slow/  // Skip tests with @slow tag

Output and Artifacts

outputDir
string
default:"'test-results'"
Directory for test artifactsFrom src/common/config.ts:188:
outputDir: './test-results'
snapshotDir
string
Directory for snapshotsFrom src/common/config.ts:196:
snapshotDir: './snapshots'
preserveOutput
'always' | 'never' | 'failures-only'
default:"'always'"
When to preserve output directoryFrom src/common/config.ts:110:
preserveOutput: 'failures-only'

Reporters

reporter
string | Array
default:"'list'"
Test reporters to useFrom src/common/config.ts:113,296:
// Built-in reporters: 'list', 'line', 'dot', 'json', 'junit', 
// 'null', 'github', 'html', 'blob'

reporter: 'html',
reporter: [['html', { open: 'never' }], ['json', { outputFile: 'results.json' }]]
reportSlowTests
object
default:"{ max: 5, threshold: 300000 }"
Report slow testsFrom src/common/config.ts:114:
reportSlowTests: {
  max: 10,           // Report top 10 slow tests
  threshold: 15000   // Tests slower than 15s
}

Global Setup/Teardown

globalSetup
string
Path to global setup fileFrom src/common/config.ts:85-86,103:
globalSetup: './global-setup.ts'
globalTeardown
string
Path to global teardown fileFrom src/common/config.ts:85-86,104:
globalTeardown: './global-teardown.ts'

Projects

projects
Array<Project>
Configure multiple test projectsFrom src/common/config.ts:144-149,168-216:
projects: [
  {
    name: 'chromium',
    use: { browserName: 'chromium' },
  },
  {
    name: 'firefox',
    use: { browserName: 'firefox' },
    testDir: './firefox-tests',
    timeout: 45000,
  },
  {
    name: 'api',
    testDir: './api-tests',
    dependencies: ['setup-db'],
  },
  {
    name: 'cleanup',
    teardown: 'api',
  },
]

Project Dependencies

From src/common/config.ts:254-286:
projects: [
  {
    name: 'setup',
    testMatch: /.*\.setup\.ts/,
  },
  {
    name: 'chromium',
    use: { ...devices['Desktop Chrome'] },
    dependencies: ['setup'],  // Run setup first
  },
  {
    name: 'teardown',
    testMatch: /.*\.teardown\.ts/,
    teardown: 'chromium',     // Run after chromium
  },
]
Teardown projects must not have dependencies. Projects cannot depend on teardown projects.

Sharding

shard
object
Distribute tests across multiple machinesFrom src/common/config.ts:116:
shard: { total: 4, current: 1 }
CLI usage:
npx playwright test --shard=1/4

Web Server

webServer
object | Array
Start a local development server before testsFrom src/common/config.ts:131-141:
webServer: {
  command: 'npm run start',
  port: 3000,
  timeout: 120 * 1000,
  reuseExistingServer: !process.env.CI,
}

// Multiple servers
webServer: [
  {
    command: 'npm run api',
    port: 8080,
  },
  {
    command: 'npm run ui',
    port: 3000,
  },
]

Browser Options

use: {
  // Browser context options
  viewport: { width: 1280, height: 720 },
  ignoreHTTPSErrors: true,
  locale: 'en-US',
  timezoneId: 'America/New_York',
  permissions: ['geolocation'],
  geolocation: { latitude: 37.7749, longitude: -122.4194 },
  colorScheme: 'dark',
  
  // Network
  baseURL: 'http://localhost:3000',
  extraHTTPHeaders: {
    'X-Custom-Header': 'value',
  },
  httpCredentials: {
    username: 'user',
    password: 'pass',
  },
  
  // Behavior
  actionTimeout: 10000,
  navigationTimeout: 30000,
  screenshot: 'only-on-failure',
  video: 'retain-on-failure',
  trace: 'on-first-retry',
}

Configuration Merging

Project configurations merge with global configuration: From src/common/config.ts:200:
use: mergeObjects(config.use, projectConfig.use, configCLIOverrides.use)
Priority (lowest to highest):
  1. Global config use object
  2. Project config use object
  3. CLI overrides

Environment Variables

export default defineConfig({
  workers: process.env.CI ? 1 : undefined,
  retries: process.env.CI ? 2 : 0,
  use: {
    baseURL: process.env.BASE_URL || 'http://localhost:3000',
  },
});

TypeScript Configuration

tsconfig
string
Path to TypeScript configurationFrom src/common/config.ts:81:
tsconfig: './tsconfig.test.json'

Example: Complete Configuration

import { defineConfig, devices } from '@playwright/test';

export default defineConfig({
  testDir: './tests',
  testMatch: '**/*.spec.ts',
  testIgnore: '**/*.skip.ts',
  
  fullyParallel: true,
  forbidOnly: !!process.env.CI,
  workers: process.env.CI ? 2 : undefined,
  retries: process.env.CI ? 2 : 0,
  
  timeout: 30000,
  globalTimeout: 60 * 60 * 1000,
  
  expect: {
    timeout: 5000,
  },
  
  outputDir: './test-results',
  preserveOutput: 'failures-only',
  
  reporter: [
    ['html', { open: 'never' }],
    ['json', { outputFile: 'results.json' }],
    ['junit', { outputFile: 'junit.xml' }],
  ],
  
  use: {
    baseURL: 'http://localhost:3000',
    trace: 'on-first-retry',
    screenshot: 'only-on-failure',
    video: 'retain-on-failure',
    actionTimeout: 10000,
  },
  
  projects: [
    {
      name: 'setup',
      testMatch: /.*\.setup\.ts/,
    },
    {
      name: 'chromium',
      use: { ...devices['Desktop Chrome'] },
      dependencies: ['setup'],
    },
    {
      name: 'firefox',
      use: { ...devices['Desktop Firefox'] },
      dependencies: ['setup'],
    },
    {
      name: 'mobile',
      use: { ...devices['iPhone 12'] },
      dependencies: ['setup'],
    },
  ],
  
  webServer: {
    command: 'npm run start',
    port: 3000,
    reuseExistingServer: !process.env.CI,
  },
});

Next Steps

Test Fixtures

Learn about fixture configuration

Parallelization

Optimize test execution

Build docs developers (and LLMs) love