top of page

Welcome
to NumpyNinja Blogs

NumpyNinja: Blogs. Demystifying Tech,

One Blog at a Time.
Millions of views. 

Mastering playwright.config.js — The Brain Behind Your Test Suite

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: {

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.

+1 (302) 200-8320

NumPy_Ninja_Logo (1).png

Numpy Ninja Inc. 8 The Grn Ste A Dover, DE 19901

© Copyright 2025 by Numpy Ninja Inc.

  • Twitter
  • LinkedIn
bottom of page