If you’re starting with Playwright for end-to-end testing, you’ll quickly encounter the playwright.config.ts file. This file is the backbone of your Playwright test setup, controlling how tests run, which browsers are used, and much more.
In this article, I’ll walk you through a typical Playwright configuration file, explaining every line—including the commented ones—so you’ll know exactly what’s happening and how to customize it for your own projects.
import { defineConfig, devices } from '@playwright/test';
import dotenv from 'dotenv';
import path from 'path';
dotenv.config({ path: path.resolve(__dirname, '.env') });
/**
* See https://playwright.dev/docs/test-configuration.
*/
export default defineConfig({
testDir: './tests',
/* Run tests in files in parallel */
fullyParallel: true,
/* Fail the build on CI if you accidentally left test.only in the source code. */
forbidOnly: !!process.env.CI,
/* Retry on CI only */
retries: process.env.CI ? 2 : 0,
/* Opt out of parallel tests on CI. */
workers: process.env.CI ? 1 : undefined,
/* Reporter to use. See https://playwright.dev/docs/test-reporters */
reporter: 'html',
/* Shared settings for all the projects below. See https://playwright.dev/docs/api/class-testoptions. */
use: {
/* Base URL to use in actions like `await page.goto('/')`. */
// baseURL: 'http://localhost:3000',
/* Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer */
trace: 'on-first-retry',
},
/* Configure projects for major browsers */
projects: [
{
name: 'chromium',
use: { ...devices['Desktop Chrome'] },
},
{
name: 'firefox',
use: { ...devices['Desktop Firefox'] },
},
{
name: 'webkit',
use: { ...devices['Desktop Safari'] },
},
/* Test against mobile viewports. */
// {
// name: 'Mobile Chrome',
// use: { ...devices['Pixel 5'] },
// },
// {
// name: 'Mobile Safari',
// use: { ...devices['iPhone 12'] },
// },
/* Test against branded browsers. */
// {
// name: 'Microsoft Edge',
// use: { ...devices['Desktop Edge'], channel: 'msedge' },
// },
// {
// name: 'Google Chrome',
// use: { ...devices['Desktop Chrome'], channel: 'chrome' },
// },
],
/* Run your local dev server before starting the tests */
// webServer: {
// command: 'npm run start',
// url: 'http://localhost:3000',
// reuseExistingServer: !process.env.CI,
// },
});
Breaking Down the Configuration
Let’s go through the file, section by section.
- Imports and Environment Variables
import { defineConfig, devices } from '@playwright/test';
import dotenv from 'dotenv';
import path from 'path';
dotenv.config({ path: path.resolve(__dirname, '.env') });
- defineConfig, devices: These come from Playwright. defineConfig helps with type safety and autocompletion. devices provides pre-configured settings for various browsers and devices.
- dotenv, path: These are Node.js packages. dotenv loads environment variables from a .env file, and path helps resolve the file path.
- dotenv.config(...): Loads environment variables from .env so you can use them in your tests or config.
- DefineConfig
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',
});
What do these options mean?
- testDir: Where your test files live. Change this if your tests are in a different folder.
- fullyParallel: Run tests in different files at the same time for speed.
- forbidOnly: If you accidentally leave a test.only in your code, this will fail the build on CI to prevent running only a subset of tests.
- retries: How many times to retry a failing test. Retries twice on CI, never locally.
- workers: Number of parallel workers. On CI, runs tests serially (1 worker) for stability; locally, uses the default (parallel).
- reporter: Generates an HTML report of your test results.
- use: Shared settings for all tests.
use: {
// baseURL: 'http://localhost:3000',
trace: 'on-first-retry',
}
What does this do?
- baseURL: (commented) If you have a local server, set this so you can use relative URLs in your tests.
- trace: Collects a trace (detailed log) only when a test fails and is retried.
- projects: Lets you run the same tests in different browsers and devices.
projects: [
{
name: 'chromium',
use: { ...devices['Desktop Chrome'] },
},
{
name: 'firefox',
use: { ...devices['Desktop Firefox'] },
},
{
name: 'webkit',
use: { ...devices['Desktop Safari'] },
},
// Mobile and branded browsers (commented out)
]
- chromium: Runs tests in Google Chrome.
- firefox: Runs tests in Mozilla Firefox.
- webkit: Runs tests in Safari.
- Mobile and branded browsers: You can uncomment these to test on mobile devices (like Pixel 5 or iPhone 12) or branded browsers (like Edge or Chrome with specific channels).
- Running a Local Dev Server (Optional)
If you have a local server running, you can uncomment this to start it before running tests.
webServer: {
command: 'npm run start',
url: 'http://localhost:3000',
reuseExistingServer: !process.env.CI,
}
- command: The command to start your server.
- url: The URL Playwright should wait for before running tests.
- reuseExistingServer: Reuse the server if it’s already running (locally), but always start fresh on CI.
Customizing for Your Project
- Change testDir if your tests are in a different folder.
- Uncomment and set baseURL if you want to use relative URLs in your tests.
- Add or remove projects to test on different browsers or devices.
- Enable webServer if your app needs to be running for tests.
Conclusion
- The Playwright configuration file is powerful but approachable. By understanding each line, you can tailor your test setup to your project’s needs, run tests across browsers and devices, and ensure your app works everywhere.
- If you’re new to Playwright, start with the defaults, then experiment with the options as your project grows. Happy testing!
Further Reading:
Top comments (0)