MENU

Saturday, 28 June 2025


When you embark on a Playwright test automation journey, you quickly encounter playwright.config.js. This seemingly humble JavaScript file is, in fact, the central control panel for your entire test suite. It's where you configure browsers, define parallel execution, set timeouts, integrate reporters, and manage various test environments.

Understanding playwright.config.js is crucial because it dictates the behavior of your tests without needing to modify individual test files. This makes your framework incredibly flexible, scalable, and adaptable to different testing needs.

Let's unravel the key sections of this powerful configuration file.

What is playwright.config.js?

At its core, playwright.config.js is a Node.js module that exports a configuration object. Playwright's test runner reads this file to understand:

  • Where to find your tests.

  • Which browsers to run tests on.

  • How many tests to run in parallel.

  • How to report test results.

  • Various timeouts and debugging options.

  • And much more!

Basic Structure

When you initialize a Playwright project (e.g., npm init playwright@latest), a playwright.config.js file is generated for you. It typically looks something like this:

JavaScript
// playwright.config.js
import { defineConfig } from '@playwright/test';

export default defineConfig({
  testDir: './tests', // Where your test files are located
  fullyParallel: true, // Run tests in files in parallel
  forbidOnly: process.env.CI ? true : false, // Disallow .only on CI
  retries: process.env.CI ? 2 : 0, // Number of retries on CI
  workers: process.env.CI ? 1 : undefined, // Number of parallel workers on CI
  reporter: 'html', // Reporter to use

  use: {
    // Base URL to use in tests like `await page.goto('/')`.
    baseURL: 'http://127.0.0.1:3000',
    trace: 'on-first-retry', // Collect trace when retrying a failed test
  },

  /* Configure projects for browsers */
  projects: [
    {
      name: 'chromium',
      use: { ...devices['Desktop Chrome'] },
    },
    {
      name: 'firefox',
      use: { ...devices['Desktop Firefox'] },
    },
    {
      name: 'webkit',
      use: { ...devices['Desktop Safari'] },
    },
  ],

  /* Run your local dev server before starting the tests */
  // webServer: {
  //   command: 'npm run start',
  //   url: 'http://127.0.0.1:3000',
  //   reuseExistingServer: !process.env.CI,
  // },
});

Let's break down the most important configuration options.

Key Configuration Options Explained

1. testDir

  • Purpose: Specifies the directory where Playwright should look for your test files.

  • Example: testDir: './tests', (looks for tests in a folder named tests at the root).

2. Execution Control & Parallelization

  • fullyParallel: boolean

    • Purpose: If true, tests in different test files will run in parallel.

    • Default: false

  • forbidOnly: boolean

    • Purpose: If true, fails the test run if any test uses .only(). Essential for CI to prevent accidentally committed focused tests.

    • Example: forbidOnly: process.env.CI ? true : false, (only forbid on CI).

  • retries: number

    • Purpose: The number of times to retry a failed test. Highly recommended for CI environments to mitigate flakiness.

    • Example: retries: 2, (retry twice if a test fails).

  • workers: number

    • Purpose: Defines the maximum number of worker processes that Playwright can use to run tests in parallel.

    • Default: About 1/2 of your CPU cores.

    • Example: workers: 4, or workers: process.env.CI ? 1 : undefined, (run sequentially on CI for specific reasons, like database contention).

3. reporter

  • Purpose: Configures how test results are reported. You can specify single or multiple reporters.

  • Common Built-in Reporters:

    • 'list': Prints a list of tests and their status (default).

    • 'dot': Prints a dot for each test (pass/fail).

    • 'line': A more verbose list reporter.

    • 'html': Generates a rich, interactive HTML report (highly recommended for local viewing).

    • 'json': Exports results as a JSON file.

    • 'junit': Exports results in JUnit XML format (common for CI/CD tools).

  • Example (multiple reporters):

    JavaScript
    reporter: [
      ['list'],
      ['html', { open: 'never' }], // Don't open automatically after run
      ['json', { outputFile: 'test-results.json' }],
    ],
    

4. use

This is a global configuration object applied to all tests unless overridden by projects. It contains browser-specific settings and test runtime options.

  • baseURL: string

    • Purpose: The base URL for your application. Allows you to use relative paths like await page.goto('/') in your tests.

    • Example: baseURL: 'http://localhost:8080',

  • headless: boolean

    • Purpose: If true, browsers run in headless mode (without a UI). Ideal for CI. If false, browsers launch with a visible UI.

    • Default: true in CI, false otherwise.

    • Example: headless: true,

  • viewport: { width: number, height: number }

    • Purpose: Sets the browser viewport size.

    • Example: viewport: { width: 1280, height: 720 },

  • Timeouts (actionTimeout, navigationTimeout, expect.timeout)

    • actionTimeout: number: Maximum time for any action (click, fill, etc.) to complete. Includes auto-waiting.

    • navigationTimeout: number: Maximum time for a navigation to occur.

    • expect.timeout: number: Default timeout for expect() assertions (Web-First Assertions).

    • Example:

      JavaScript
      actionTimeout: 10000, // 10 seconds
      navigationTimeout: 30000, // 30 seconds
      expect: { timeout: 5000 }, // 5 seconds for assertions
      
  • Artifacts on Failure (screenshot, video, trace)

    • Purpose: Configure what artifacts Playwright saves when a test fails. Crucial for debugging.

    • screenshot: 'off', 'on', 'only-on-failure'.

    • video: 'off', 'on', 'retain-on-failure'.

    • trace: 'off', 'on', 'retain-on-failure', 'on-first-retry'. on-first-retry is a good balance.

    • Example:

      JavaScript
      screenshot: 'only-on-failure',
      video: 'retain-on-failure',
      trace: 'on-first-retry',
      
  • testIdAttribute: string

    • Purpose: Defines the data-* attribute that Playwright's getByTestId() locator should look for. Connects directly to our previous discussion on robust locators!

    • Default: 'data-testid'

    • Example: testIdAttribute: 'data-qa-id', (if your developers use data-qa-id).

5. projects

  • Purpose: Defines different test configurations (projects). This is how you run tests across multiple browsers, device emulations, or even different environments (e.g., staging vs. production API tests). Each project can override global use settings.

  • Key usage: Often combined with devices (Playwright's predefined device presets).

  • Example (Desktop & Mobile):

    JavaScript
    projects: [
      {
        name: 'desktop_chromium',
        use: { ...devices['Desktop Chrome'] },
      },
      {
        name: 'mobile_safari',
        use: { ...devices['iPhone 12'] }, // Emulate iPhone 12
      },
      // You can also define projects for different environments:
      // {
      //   name: 'api_staging',
      //   testMatch: /.*\.api\.spec\.js/, // Run only API tests
      //   use: { baseURL: 'https://staging.api.example.com' },
      // },
    ],
    

    To run specific projects: npx playwright test --project=desktop_chromium

6. webServer

  • Purpose: Automatically starts a local development server before tests run and stops it afterwards. Ideal for testing front-end applications that need to be served.

  • Example:

    JavaScript
    webServer: {
      command: 'npm run start', // Command to start your dev server
      url: 'http://localhost:3000', // URL the server should be available at
      reuseExistingServer: !process.env.CI, // Don't start if already running (useful locally)
      timeout: 120 * 1000, // Timeout for the server to start (2 minutes)
    },
    

7. defineConfig

  • Purpose: (Used implicitly in the default template) A helper function that provides type safety and better IntelliSense/autocompletion for your configuration object, especially useful in TypeScript. While not strictly required for JavaScript, it's good practice.

  • Example: export default defineConfig({ ... });

Tips and Best Practices

  1. Start Simple: Don't over-configure initially. Add options as your needs evolve.

  2. Leverage projects: Use projects extensively for managing different test dimensions (browsers, devices, environments).

  3. Use Environment Variables: Parameterize sensitive data or environment-specific values using process.env.

  4. Manage Timeouts Wisely: Adjust timeouts based on your application's typical responsiveness, but avoid excessively long timeouts which can hide performance issues.

  5. Artifacts for Debugging: Always configure screenshot, video, and trace on failure, especially for CI runs. They are invaluable for debugging.

  6. testIdAttribute: Collaborate with developers to implement a consistent data-testid strategy in your application and configure it here.

Conclusion

playwright.config.js is much more than just a settings file; it's a powerful tool that enables you to precisely control your test execution, improve debugging, and build a highly adaptable test automation framework. By understanding and effectively utilizing its myriad options, you can tailor Playwright to fit the exact needs of your project, ensuring robust, efficient, and reliable test automation.

0 comments:

Post a Comment

Popular Posts