Skip to content

Katarzyna Kmiotek

Playwright config

Playwright6 min read

logo When you start building your project and run

1npm init playwright@latest

playwright.config.js file is already created for you with example usage and basic configuration. In this post, I would like to explain what and why can be defined in the Playwright config file.
The content of the file can be split into a few sections:

  • general config
  • use
  • projects

General config

Test Config properties in this section:

  • timeout - max time limit for each test (for me it serves the purpose of a best practice reminder - If I think about extending it means that I should rethink the test scenario.
  • globalTimeout - max time limit for the run of the whole test suite. Infinite loop, resource drainage in CI run? not anymore; this feature will exit execution if the given time is exceeded. ( Can also be set in your CI pipeline as job timeout).
  • globalSetup defines the file that will be executed before the test suite, globalTeardown points to the file that will be executed once all tests are finished.
    Playwright documentation shows how those files can be used for example to reuse authentication state in test context
  • name so title of your test suite
  • testDir property allows setting a directory that will be scanned for test files.
  • snapshotDir path to the location where snapshots (used for visual regression tests) are stored
  • outputDir path to the location where test results (trace, videos, screenshots) are stored. By default test result are stored but you can change it to be stored only failures-only or never. In the projects section this value can be overridden for each project's requirements
1testDir: './tests',
3 timeout: 30 * 1000,
5 globalTimeout: process.env.CI ? 60 * 60 * 1000: 30 * 60 * 1000,
7 globalSetup: './global-setup.js',
8 globalTeardown: './global-teardown.js',
  • retries in case of test failure Playwright will retry to get the successful result as many times as specified in retries properties. The default value is 0.
    In the test summary test that had to be rerun to get a pass result will be marked as flaky instead of failed. This in my opinion shows room for improvement to better understand the feature.
  • you can also specify that you want to repeatEach test given number of times
  • forbidOnly - to run a single test you can add an .only tag
1test.only('homepage has Playwright

which is great when working on a single test, usually you don't want to execute only one test in the pipeline and don't want the only tag to be merged to a higher environment.
The forbidOnly property when resolved to true will throw an error and exit tests with code 1

  • workers - are OS processes that run independently in separate browsers. It is really up to your machine's memory limit how many of those resources will be created to execute the test suite. The test runner will reuse them so multiple test files are usually run in a single worker one after another.
    But you may want to limit their number let's say in a CI environment
  • fullyParallel - with this property set to true tests within test files will be executed in parallel so will override default worker behavior to execute file by file.
  • shard property allows to split tests for multiple machines, let's say 1/2 and 2/2 to run them in parallel so speed up test execution. More about implementation in docs
  • testMatch Defines a pattern used by test files like: testMatch: "**/?(*.)@(spec|test).*"
    Tests are executed in alphabetical order of the file names. By providing a testMatch: test.list.js file with a list of tests you can specify your order of execution.
  • in the same way as testMatch you can use testIgnore so files name pattern that will be ignored from test execution
  • maxFailures you can also specify the max number of failures before tests will exit with 1 code.
    This is handy in CI jobs to avoid wasting resources once we know the pipeline won't pass
1retries: process.env.CI ? 2 : 0,
3 forbidOnly: !!process.env.CI,
5 workers: process.env.CI ? 1 : undefined,
7 fullyParallel: true,
9 testMatch: 'test.list.js',
11 maxFailures: process.env.CI ? 10 : undefined,
  • grep and grepInvert Do your tests use tags like @develop , @visual to run only certain tests? You can also set it in the config. Personally prefer to pass it dynamically in the command let's say depending on the environment and specific tests you want to run there
  • reporter takes a single string or array of arrays and accepts the object of the reporter's options.
    Builtin reporters to choose from: dot, github, html, json, junit, line, list, null. Or you can provide your own. It is a great idea to experiment with all of them and see which one suits you best.
  • reportSlowTests default number is 5 and at the end of your test run up to 5 tests will be listed as slowest. You can change this number here and also specify what is threshold for a slow test
  • metadata this is an object that can be logged in the report.
    This can help debug tests in the pipeline job as part of metadata operating system information can be logged.
1reporter: [
2 ['html', { outputFolder: 'test-results' }],
3 ['json', { outputFolder: 'test-results', outputFile: 'report.json' }],
4 ],
5 metadata: {
6 hostFreeMemory: os.freemem()
7 },
  • Playwright can actually start a webServer for you! And will wait until the service is responding with a 2xx HTTP status code. Just provide all required values like: command to start it, port or URL, timeout etc
  • expect - this section relates to assertions within tests.
    This is the right place to override the default timeout (which is 5000 milliseconds) because in your case tests need a little bit longer most of the time and it safe is to set it to 6000 milliseconds.
    In this part, you can also add global settings for visual regression tests by defining toHaveScreenshot and toMatchSnapshot methods that will apply to all your visual test - let's say you want to allow maxDiffPixelRatio to be 0.01
1expect: {
2 timeout: 6000,
3 toHaveScreenshot: {
4 animations: 'disabled'
5 },
6 toMatchSnapshot: {
7 maxDiffPixelRatio: 0.01
8 },
9 },


This section contains properties shared within projects and values that define tests Context (TestOptions):

  • acceptDownloads accepts boolean and it is really useful for testing the file downloads functionality of the app.
  • actionTimeout value if not set defaults to 0. Adds timeout value on page actions like click(), type() etc.
  • navigationTimeout happens that page.goto() in the app takes a little bit longer, allowing the page to load. You can either specify timeout here or in the method itself.
    Without need of specifying it on individual actions ({ timeout: 1000 })).
  • baseURL base URL of the tested application. Can be a hardcoded string or provided by environment variables (process.env.BASE_URL).
  • colorScheme Are you testing the dark mode functionality of the app, maybe checking accessibility on it? This property will allow you to set colour schema for dark, light or no-preference.
  • serviceWorkers here you can allow or block registration of service workers. Defaults to allow value.
  • geolocation let's say you want to check how your app looks and works when used by the user from a different part of the world, does locale change and does the user sees their language version of the app? You can provide desired geolocation here.
  • locale and timezoneId - testing i18n (internationalization) or l10n (localization) feature of the app? locale and geolocation properties will help you to automate those tests.
  • when you use geolocation remember to also give a browser context permission to use it by defining it in the permissions property.
    You can also allow here for notifications, clipboard-write, clipboard-read (for copy/paste interactions with clipboard API) etc.
  • headless execute tests in headless or headful browser mode; true or false? Usually true (default) as can run tests in the background but when working on tests and debugging false. I prefer to pass this value in the command rather than set it in the config.
  • ignoreHTTPSErrors with this value set to true you can ignore HTTPS-related errors in your local environment.
    Testing API response and getting an error? Make sure you have this value set.
  • screenshot , video and trace here you can specify if you want to retain them in the test results directory after tests finish. Options available (and self-explanatory) : 'on', 'off', 'retain-on-failure'. It is a great help with debugging failing tests so would recommend having it set.
  • viewport property specifies the viewport of the browser (makes sense :) ). I find it really helpful in visual regression tests
  • offline this TestOption becomes handy if you test Progressive Web Application and want to check how the app behaves in an offline state or if you simply want to verify what user sees when the network is not available
  • storageState you can use this option to let's say set cookies for all your tests or maybe your tests require the test-user to be logged in. You can just set it here instead of repeating it in all tests.
  • userAgent value can be specified here too.
  • hasTouch , isMobile both options default to false. Can be overwritten in individual test, extremely helpful for emulation tests on mobile devices.
  • you can connect with remote browsers and override fixtures (browser, context and page) with connectOptions an Option object that takes wsEndpoint and optional headers as parameters
  • you can provide here as well browserName (defaults to chromium) and browser distribution channel (chrome-canary)
  • if you test API and calls require authentication you can provide it in extraHTTPHeaders
    so APIRequestContext can use it.
  • network proxy settings can be also specified in the Playwright config if required by your tests. This option accepts an object with HTTP or SOCKS server and authentication username and password
1use: {
2 acceptDownloads: true,
3 actionTimeout: 0,
4 baseURL: '',
5 colorScheme: 'dark',
6 viewport: { width: 1280, height: 720 },
7 geolocation: { longitude: 19.944544, latitude: 50.049683 },
8 headless: false,
9 ignoreHTTPSErrors: true,
10 locale: 'en-GB',
11 permissions: ['notifications', 'geolocation', 'clipboard-read'],
12 screenshot: 'only-on-failure',
13 trace: 'retain-on-failure',
14 video: 'on-first-retry',
15 }


The example config file provided shows how you can use it to test on different browsers and different devices. For each project object, you can provide its own properties from the use section:

1projects: [
2 {
3 name: 'project one',
4 use: {
5 ...devices['Desktop Chrome'],
6 baseURL: process.env.POST_ONE_URL || '',
7 colorScheme: 'light',
8 storageState: 'storage/user1.json'
9 },
10 },
11 {
12 name: 'project two',
13 use: {
14 ...devices['Desktop Chrome'],
15 baseURL: process.env.POST_TWO_URL || '',
16 colorScheme: 'dark',
17 storageState: 'storage/user2.json'
18 },
19 },

That's all but also probably not enough. All you will find at Playwright website

The above is taken mostly from my own experience and the projects I worked on.
Hope it helped you to understand Playwright config a little bit better!

© 2024 by Katarzyna Kmiotek. All rights reserved.
Theme by LekoArts