Skip to main content

TestProject

Playwright Test supports running multiple test projects at the same time. This is useful for running tests in multiple configurations. For example, consider running tests against multiple browsers.

TestProject encapsulates configuration specific to a single project. Projects are configured in testConfig.projects specified in the configuration file. Note that all properties of TestProject are available in the top-level TestConfig, in which case they are shared between all projects.

Here is an example configuration that runs every test in Chromium, Firefox and WebKit, both Desktop and Mobile versions.

// playwright.config.ts
import { type PlaywrightTestConfig, devices } from '@playwright/test';

const config: PlaywrightTestConfig = {
// Options shared for all projects.
timeout: 30000,
use: {
ignoreHTTPSErrors: true,
},

// Options specific to each project.
projects: [
{
name: 'Desktop Chromium',
use: {
browserName: 'chromium',
viewport: { width: 1280, height: 720 },
},
},
{
name: 'Desktop Safari',
use: {
browserName: 'webkit',
viewport: { width: 1280, height: 720 },
}
},
{
name: 'Desktop Firefox',
use: {
browserName: 'firefox',
viewport: { width: 1280, height: 720 },
}
},
{
name: 'Mobile Chrome',
use: devices['Pixel 5'],
},
{
name: 'Mobile Safari',
use: devices['iPhone 12'],
},
],
};
export default config;

testProject.expect

Added in: v1.10
  • type: <Object>
    • timeout? <number> Default timeout for async expect matchers in milliseconds, defaults to 5000ms.
    • toHaveScreenshot? <Object> Configuration for the expect(page).toHaveScreenshot(name[, options]) method.
      • threshold? <number> an acceptable perceived color difference in the YIQ color space between the same pixel in compared images, between zero (strict) and one (lax). Defaults to 0.2.
      • maxDiffPixels? <number> an acceptable amount of pixels that could be different, unset by default.
      • maxDiffPixelRatio? <number> an acceptable ratio of pixels that are different to the total amount of pixels, between 0 and 1 , unset by default.
      • animations? <"allow"|"disabled"> See animations in page.screenshot([options]). Defaults to "disabled".
      • caret? <"hide"|"initial"> See caret in page.screenshot([options]). Defaults to "hide".
      • scale? <"css"|"device"> See scale in page.screenshot([options]). Defaults to "css".
    • toMatchSnapshot? <Object> Configuration for the expect(screenshot).toMatchSnapshot(name[, options]) method.
      • threshold? <number> an acceptable perceived color difference in the YIQ color space between the same pixel in compared images, between zero (strict) and one (lax). Defaults to 0.2.
      • maxDiffPixels? <number> an acceptable amount of pixels that could be different, unset by default.
      • maxDiffPixelRatio? <number> an acceptable ratio of pixels that are different to the total amount of pixels, between 0 and 1 , unset by default.

Configuration for the expect assertion library.

Use testConfig.expect to change this option for all projects.

testProject.fullyParallel

Added in: v1.10

Playwright Test runs tests in parallel. In order to achieve that, it runs several worker processes that run at the same time. By default, test files are run in parallel. Tests in a single file are run in order, in the same worker process.

You can configure entire test project to concurrently run all tests in all files using this option.

testProject.grep

Added in: v1.10

Filter to only run tests with a title matching one of the patterns. For example, passing grep: /cart/ should only run tests with "cart" in the title. Also available globally and in the command line with the -g option.

grep option is also useful for tagging tests.

testProject.grepInvert

Added in: v1.10

Filter to only run tests with a title not matching one of the patterns. This is the opposite of testProject.grep. Also available globally and in the command line with the --grep-invert option.

grepInvert option is also useful for tagging tests.

testProject.metadata

Added in: v1.10
  • type: <[Metadata]>

Metadata that will be put directly to the test report serialized as JSON.

testProject.name

Added in: v1.10

Project name is visible in the report and during test execution.

testProject.outputDir

Added in: v1.10

The output directory for files created during test execution. Defaults to <package.json-directory>/test-results.

This directory is cleaned at the start. When running a test, a unique subdirectory inside the testProject.outputDir is created, guaranteeing that test running in parallel do not conflict. This directory can be accessed by testInfo.outputDir and testInfo.outputPath(...pathSegments).

Here is an example that uses testInfo.outputPath(...pathSegments) to create a temporary file.

import { test, expect } from '@playwright/test';
import fs from 'fs';

test('example test', async ({}, testInfo) => {
const file = testInfo.outputPath('temporary-file.txt');
await fs.promises.writeFile(file, 'Put some data to the file', 'utf8');
});

Use testConfig.outputDir to change this option for all projects.

testProject.repeatEach

Added in: v1.10

The number of times to repeat each test, useful for debugging flaky tests.

Use testConfig.repeatEach to change this option for all projects.

testProject.retries

Added in: v1.10

The maximum number of retry attempts given to failed tests. Learn more about test retries.

Use test.describe.configure([options]) to change the number of retries for a specific file or a group of tests.

Use testConfig.retries to change this option for all projects.

testProject.snapshotDir

Added in: v1.10

The base directory, relative to the config file, for snapshot files created with toMatchSnapshot. Defaults to testProject.testDir.

The directory for each test can be accessed by testInfo.snapshotDir and testInfo.snapshotPath(...pathSegments).

This path will serve as the base directory for each test file snapshot directory. Setting snapshotDir to 'snapshots', the testInfo.snapshotDir would resolve to snapshots/a.spec.js-snapshots.

testProject.snapshotPathTemplate

Added in: v1.28

This option configures a template controlling location of snapshots generated by expect(page).toHaveScreenshot(name[, options]) and expect(screenshot).toMatchSnapshot(name[, options]).

// playwright.config.ts
import type { PlaywrightTestConfig } from '@playwright/test';

const config: PlaywrightTestConfig = {
testDir: './tests',
snapshotPathTemplate: '{testDir}/__screenshots__/{testFilePath}/{arg}{ext}',
};

export default config;

The value might include some "tokens" that will be replaced with actual values during test execution.

Consider the following file structure:

playwright.config.ts
tests/
└── page/
└── page-click.spec.ts

And the following page-click.spec.ts that uses toHaveScreenshot() call:

// page-click.spec.ts
import { test, expect } from '@playwright/test';

test.describe('suite', () => {
test('test should work', async ({ page }) => {
await expect(page).toHaveScreenshot(['foo', 'bar', 'baz.png']);
});
});

The list of supported tokens:

  • {testDir} - Project's testConfig.testDir.
    • Value: /home/playwright/tests (absolute path is since testDir is resolved relative to directory with config)
  • {snapshotDir} - Project's testConfig.snapshotDir.
    • Value: /home/playwright/tests (since snapshotDir is not provided in config, it defaults to testDir)
  • {platform} - The value of process.platform.
  • {projectName} - Project's file-system-sanitized name, if any.
    • Value: '' (empty string).
  • {testFileDir} - Directories in relative path from testDir to test file.
    • Value: page
  • {testFileName} - Test file name with extension.
    • Value: page-click.spec.ts
  • {testFilePath} - Relative path from testDir to test file
    • Value: page/page-click.spec.ts
  • {testName} - File-system-sanitized test title, including parent describes but excluding file name.
    • Value: suite-test-should-work
  • {arg} - Relative snapshot path without extension. These come from the arguments passed to the toHaveScreenshot() and toMatchSnapshot() calls; if called without arguments, this will be an auto-generated snapshot name.
    • Value: foo/bar/baz
  • {ext} - snapshot extension (with dots)
    • Value: .png

Each token can be preceded with a single character that will be used only if this token has non-empty value.

Consider the following config:

// playwright.config.ts
import type { PlaywrightTestConfig } from '@playwright/test';

const config: PlaywrightTestConfig = {
snapshotPathTemplate: '__screenshots__{/projectName}/{testFilePath}/{arg}{ext}',
testMatch: 'example.spec.ts',
projects: [
{ use: { browserName: 'firefox' } },
{ name: 'chromium', use: { browserName: 'chromium' } },
],
};
export default config;

In this config:

  1. First project does not have a name, so its snapshots will be stored in <configDir>/__screenshots__/example.spec.ts/....
  2. Second project does have a name, so its snapshots will be stored in <configDir>/__screenshots__/chromium/example.spec.ts/...
  3. Since snapshotPathTemplate resolves to relative path, it will be resolved relative to configDir.
  4. Forward slashes "/" can be used as path separators on any platform.

testProject.testDir

Added in: v1.10

Directory that will be recursively scanned for test files. Defaults to the directory of the configuration file.

Each project can use a different directory. Here is an example that runs smoke tests in three browsers and all other tests in stable Chrome browser.

// playwright.config.ts
import type { PlaywrightTestConfig } from '@playwright/test';

const config: PlaywrightTestConfig = {
projects: [
{
name: 'Smoke Chromium',
testDir: './smoke-tests',
use: {
browserName: 'chromium',
}
},
{
name: 'Smoke WebKit',
testDir: './smoke-tests',
use: {
browserName: 'webkit',
}
},
{
name: 'Smoke Firefox',
testDir: './smoke-tests',
use: {
browserName: 'firefox',
}
},
{
name: 'Chrome Stable',
testDir: './',
use: {
browserName: 'chromium',
channel: 'chrome',
}
},
],
};
export default config;

Use testConfig.testDir to change this option for all projects.

testProject.testIgnore

Added in: v1.10

Files matching one of these patterns are not executed as test files. Matching is performed against the absolute file path. Strings are treated as glob patterns.

For example, '**/test-assets/**' will ignore any files in the test-assets directory.

Use testConfig.testIgnore to change this option for all projects.

testProject.testMatch

Added in: v1.10

Only the files matching one of these patterns are executed as test files. Matching is performed against the absolute file path. Strings are treated as glob patterns.

By default, Playwright Test looks for files matching .*(test|spec)\.(js|ts|mjs).

Use testConfig.testMatch to change this option for all projects.

testProject.timeout

Added in: v1.10

Timeout for each test in milliseconds. Defaults to 30 seconds.

This is a base timeout for all tests. Each test can configure its own timeout with test.setTimeout(timeout). Each file or a group of tests can configure the timeout with test.describe.configure([options]).

Use testConfig.timeout to change this option for all projects.

testProject.use

Added in: v1.10

Options for all tests in this project, for example testOptions.browserName. Learn more about configuration and see available options.

// playwright.config.ts
import type { PlaywrightTestConfig } from '@playwright/test';

const config: PlaywrightTestConfig = {
projects: [
{
name: 'Chromium',
use: {
browserName: 'chromium',
},
},
],
};
export default config;

Use testConfig.use to change this option for all projects.