Mastering playwright.config.js — The Brain Behind Your Test Suite
- uthikagajbhiye
- Feb 21
- 4 min read
When you're building a serious test automation framework, configuration isn't an afterthought — it's the
foundation. The playwright.config.js file is where you tell Playwright how to run your tests: which browsers to
use, how many tests to run in parallel, where to send reports, and much more. Get this file right, and everything
else falls into place.
Let me walk you through what this file does, why each setting matters, and how I've configured it in a real-
world project — the DSAlgo Portal Test Automation Framework.
What Is playwright.config.js ?
playwright.config.js is the central configuration file for any Playwright project. It lives at the root of your project
and is automatically picked up when you run npx playwright test . Think of it as the control panel for your entire
test execution lifecycle.
It controls:
Test discovery — where Playwright looks for your test files
Browser setup — which browsers and devices to run against
Parallelism — how many tests run simultaneously
Timeouts — how long a test or action can take before it fails
Reporters — how results are displayed and saved
Base URL — the root URL of the application under test
Global setup/teardown — hooks that run before or after the entire suite
Key Configuration Options Explained
Here's a breakdown of the most important properties you'll use day to day.
testDir points to the folder where your test files live. In BDD setups, this typically points to your .feature files or step definitions.
fullyParallel when set to true , runs tests across files in parallel. Setting it to false gives you sequential execution — critical when tests have dependencies on each other.
workers controls how many parallel worker processes Playwright spins up More workers = faster runs but they consume more memory and can cause flakiness if tests share state.
retries is your safety net. Setting retries to 2 in CI means a flaky test gets two more attempts before being marked as failed — reducing false negatives in pipelines.
use is where you define browser-level defaults: headless mode, viewport size, screenshot behaviour, trace collection, and baseURL.
reporter accepts a list of reporters. You can combine multiple — for example, a human-readable html report alongside a machine-readable json or the rich Allure report format.
projects is arguably the most powerful feature. It lets you define multiple named configurations — different
browsers, different environments, or even different test phases — all within a single config file.
Real-World Example: DSAlgo Portal Framework
In my DSAlgo Portal framework, I needed to solve a specific challenge: 130+ tests spanning multiple data
structure modules (Arrays, Linked Lists, Stacks, Queues, Trees, Graphs) had to run in a controlled
sequence, with authentication happening before anything else. Here's how playwright.config.js made that
possible.
javascript
import { defineConfig, devices } from '@playwright/test';
export default defineConfig({
testDir: './tests',
fullyParallel: false, forbidOnly: !!process.env.CI, retries: process.env.CI ? 2 : 0,
workers: process.env.CI ? 2 : 1,
timeout: 60000, // Sequential execution between phases
// Prevent .only() from sneaking into CI
// 60s per test — accounts for heavy DOM operations
reporter: [
['list'],
['html', { outputFolder: 'playwright-report', open: 'never' }],
['allure-playwright', { outputFolder: 'allure-results' }],
['json', { outputFile: 'test-results/results.json' }]
],
use: {
baseURL: 'http://localhost:3000',
headless: true,
screenshot: 'only-on-failure',
video: 'retain-on-failure',
trace: 'on-first-retry',
storageState: 'auth/storageState.json', // Reuse auth session across tests
},
projects: [
{
// Phase 1: Authentication — must complete before data tests
name: 'setup',
testMatch: '**/auth.setup.spec.js',
},
// Phase 2: Data Structure modules run after auth
{
name: 'arrays',
testMatch: '**/arrays/**/*.spec.js',
dependencies: ['setup'],
},
{
name: 'linked-lists',
testMatch: '**/linkedlists/**/*.spec.js',
dependencies: ['setup'],
},
{
name: 'stacks-queues',
testMatch: '**/stacks/**/*.spec.js',
dependencies: ['setup'],
},
{
name: 'trees-graphs',
testMatch: '**/trees/**/*.spec.js',
dependencies: ['setup'],
},
],
});
Why This Setup Works
The dependencies key on each project ensures the setup project (which handles login and saves
storageState.json ) always runs first. Every subsequent module then loads that saved auth session — no repeated
login flows, no race conditions, no flaky auth failures at scale.
Combining fullyParallel: false with workers: 2 gives us controlled parallelism: two modules can run side by
side, but we don't open the floodgates and cause resource contention on the test environment.
The four-reporter combination means our team gets immediate console feedback ( list ), a shareable HTML
report, rich Allure dashboards published to GitHub Pages via CI, and raw JSON for any downstream
automation.
Pro Tips for Your Own Config
Use environment variables for flexibility. Switching baseURL between local and staging is as simple as reading process.env.BASE_URL || 'http://localhost:3000'.
Keep storageState in .gitignore. Auth tokens shouldn't be committed. Generate them fresh in CI using a globalSetup script.
Set forbidOnly: !!process.env.CI. This prevents a developer accidentally leaving a .only() in their code from silently skipping all other tests in your pipeline.
Use trace: 'on-first-retry' not 'on' . Full trace on every run bloats your storage and slows things down. On-
first-retry catches the useful diagnostic data without the overhead.
Wrapping Up
The playwright.config.js file is far more than a settings file — it's the architectural backbone of your test suite.
Investing time to understand and configure it well pays dividends in test reliability, CI speed, and
maintainability. In the DSAlgo framework, this config is what transformed 130+ scattered tests into an
orchestrated, phase-based, reporting-rich automation pipeline.
Whether you're just starting out or scaling an enterprise suite, mastering this file is one of the highest-leverage
things you can do as an SDET.


