docs: Rework config (#21384)

This commit is contained in:
Debbie O'Brien 2023-03-06 17:17:34 +01:00 committed by GitHub
parent 948755226f
commit 9e47c450c7
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 315 additions and 1027 deletions

View file

@ -1,603 +1,154 @@
---
id: test-advanced
title: "Advanced: configuration"
title: "Test Configuration"
---
## Configuration object
Playwright has many options to configure how your tests are run. You can specify these options in the configuration file. Note that test runner options are **top-level**, do not put them into the `use` section.
Configuration file exports a single [TestConfig] object. See [TestConfig] properties for available configuration options.
## Basic Configuration
Note that each [test project](#projects) can provide its own [options][TestProject], for example two projects can run different tests by providing different `testDir`s.
Here are some of the most common configuration options.
Here is an example that defines a common timeout and two projects. The "Smoke" project runs a small subset of tests without retries, and "Default" project runs all other tests with retries.
```js tab=js-ts
// playwright.config.ts
```js
import { defineConfig } from '@playwright/test';
export default defineConfig({
timeout: 60000, // Timeout is shared between all tests.
projects: [
{
name: 'Smoke',
testMatch: /.*smoke.spec.ts/,
retries: 0,
},
{
name: 'Default',
testIgnore: /.*smoke.spec.ts/,
retries: 2,
},
],
});
```
// Look for test files in the "tests" directory, relative to this configuration file.
testDir: 'tests',
```js tab=js-js
// playwright.config.js
// @ts-check
const { defineConfig } = require('@playwright/test');
// Run all tests in parallel.
fullyParallel: true,
module.exports = defineConfig({
timeout: 60000, // Timeout is shared between all tests.
projects: [
{
name: 'Smoke',
testMatch: /.*smoke.spec.ts/,
retries: 0,
},
{
name: 'Default',
testIgnore: /.*smoke.spec.ts/,
retries: 2,
},
],
});
```
// Fail the build on CI if you accidentally left test.only in the source code.
forbidOnly: !!process.env.CI,
## TestInfo object
// Retry on CI only.
retries: process.env.CI ? 2 : 0,
Test functions, fixtures and hooks receive a [TestInfo] parameter that provides information about the currently running test as well as some useful utilities that include:
- Information about the test, for example `title`, `config` and `project`.
- Information about test execution, for example `expectedStatus` and `status`.
- Test artifact utilities, for example `outputPath()` and `attach()`.
// Opt out of parallel tests on CI.
workers: process.env.CI ? 1 : undefined,
See [TestInfo] methods and properties for all available information and utilities.
// Reporter to use
reporter: 'html',
Here is an example test that saves information to a file using [TestInfo].
```js tab=js-js
// example.spec.js
const { test } = require('@playwright/test');
test('my test needs a file', async ({ table }, testInfo) => {
// Do something with the table...
// ... and then save contents.
const filePath = testInfo.outputPath('table.dat');
await table.saveTo(filePath);
});
```
```js tab=js-ts
// example.spec.ts
import { test } from '@playwright/test';
test('my test needs a file', async ({ table }, testInfo) => {
// Do something with the table...
// ... and then save contents.
const filePath = testInfo.outputPath('table.dat');
await table.saveTo(filePath);
});
```
Here is an example fixture that automatically saves debug logs when the test fails.
```js tab=js-js
// my-test.js
const debug = require('debug');
const fs = require('fs');
const base = require('@playwright/test');
// Note how we mark the fixture as { auto: true }.
// This way it is always instantiated, even if the test does not use it explicitly.
exports.test = base.test.extend({
saveLogs: [ async ({}, use, testInfo) => {
const logs = [];
debug.log = (...args) => logs.push(args.map(String).join(''));
debug.enable('mycomponent');
await use();
if (testInfo.status !== testInfo.expectedStatus)
fs.writeFileSync(testInfo.outputPath('logs.txt'), logs.join('\n'), 'utf8');
}, { auto: true } ]
});
```
```js tab=js-ts
// my-test.ts
import * as debug from 'debug';
import * as fs from 'fs';
import { test as base } from '@playwright/test';
// Note how we mark the fixture as { auto: true }.
// This way it is always instantiated, even if the test does not use it explicitly.
export const test = base.extend<{ saveLogs: void }>({
saveLogs: [ async ({}, use, testInfo) => {
const logs = [];
debug.log = (...args) => logs.push(args.map(String).join(''));
debug.enable('mycomponent');
await use();
if (testInfo.status !== testInfo.expectedStatus)
fs.writeFileSync(testInfo.outputPath('logs.txt'), logs.join('\n'), 'utf8');
}, { auto: true } ]
});
```
## Launching a development web server during the tests
To launch a server during the tests, use the `webServer` option in the [configuration file](#configuration-object).
If `port` is specified in the config, test runner will wait for `127.0.0.1:port` or `::1:port` to be available before running the tests.
If `url` is specified in the config, test runner will wait for that `url` to return a 2xx, 3xx, 400, 401, 402, or 403 response before running the tests.
For continuous integration, you may want to use the `reuseExistingServer: !process.env.CI` option which does not use an existing server on the CI. To see the stdout, you can set the `DEBUG=pw:webserver` environment variable.
The `port` (but not the `url`) gets passed over to Playwright as a [`property: TestOptions.baseURL`]. For example port `8080` produces `baseURL` equal `http://localhost:8080`.
:::note
It is also recommended to specify [`property: TestOptions.baseURL`] in the config, so that tests could use relative urls.
:::
```js tab=js-ts
// playwright.config.ts
import { defineConfig } from '@playwright/test';
export default defineConfig({
webServer: {
command: 'npm run start',
url: 'http://localhost:3000/app/',
timeout: 120 * 1000,
reuseExistingServer: !process.env.CI,
},
use: {
baseURL: 'http://localhost:3000/app/',
// Base URL to use in actions like `await page.goto('/')`.
baseURL: 'http://127.0.0.1:3000',
// Collect trace when retrying the failed test.
trace: 'on-first-retry',
},
});
```
```js tab=js-js
// playwright.config.js
// @ts-check
const { defineConfig } = require('@playwright/test');
module.exports = defineConfig({
webServer: {
command: 'npm run start',
url: 'http://localhost:3000/app/',
timeout: 120 * 1000,
reuseExistingServer: !process.env.CI,
},
use: {
baseURL: 'http://localhost:3000/app/',
},
});
```
Now you can use a relative path when navigating the page:
```js tab=js-ts
// test.spec.ts
import { test } from '@playwright/test';
test('test', async ({ page }) => {
// baseURL is set in the config to http://localhost:3000/app/
// This will navigate to http://localhost:3000/app/login
await page.goto('./login');
});
```
```js tab=js-js
// test.spec.js
const { test } = require('@playwright/test');
test('test', async ({ page }) => {
// baseURL is set in the config to http://localhost:3000/app/
// This will navigate to http://localhost:3000/app/login
await page.goto('./login');
});
```
Multiple web servers (or background processes) can be launched simultaneously by providing an array of `webServer` configurations. See [`property: TestConfig.webServer`] for additional examples and documentation.
## Global setup and teardown
To set something up once before running all tests, use `globalSetup` option in the [configuration file](#configuration-object). Global setup file must export a single function that takes a config object. This function will be run once before all the tests.
Similarly, use `globalTeardown` to run something once after all the tests. Alternatively, let `globalSetup` return a function that will be used as a global teardown. You can pass data such as port number, authentication tokens, etc. from your global setup to your tests using environment variables.
Here is a global setup example that authenticates once and reuses authentication state in tests. It uses `baseURL` and `storageState` options from the configuration file.
```js tab=js-js
// global-setup.js
const { chromium } = require('@playwright/test');
module.exports = async config => {
const { baseURL, storageState } = config.projects[0].use;
const browser = await chromium.launch();
const page = await browser.newPage();
await page.goto(baseURL);
await page.getByLabel('User Name').fill('user');
await page.getByLabel('Password').fill('password');
await page.getByText('Sign in').click();
await page.context().storageState({ path: storageState });
await browser.close();
};
```
```js tab=js-ts
// global-setup.ts
import { chromium, FullConfig } from '@playwright/test';
async function globalSetup(config: FullConfig) {
const { baseURL, storageState } = config.projects[0].use;
const browser = await chromium.launch();
const page = await browser.newPage();
await page.goto(baseURL!);
await page.getByLabel('User Name').fill('user');
await page.getByLabel('Password').fill('password');
await page.getByText('Sign in').click();
await page.context().storageState({ path: storageState as string });
await browser.close();
}
export default globalSetup;
```
Specify `globalSetup`, `baseURL` and `storageState` in the configuration file.
```js tab=js-js
// playwright.config.js
// @ts-check
const { defineConfig } = require('@playwright/test');
module.exports = defineConfig({
globalSetup: require.resolve('./global-setup'),
use: {
baseURL: 'http://localhost:3000/',
storageState: 'state.json',
},
});
```
```js tab=js-ts
// playwright.config.ts
import { defineConfig } from '@playwright/test';
export default defineConfig({
globalSetup: require.resolve('./global-setup'),
use: {
baseURL: 'http://localhost:3000/',
storageState: 'state.json',
},
});
```
Tests start already authenticated because we specify `storageState` that was populated by global setup.
```js tab=js-ts
import { test } from '@playwright/test';
test('test', async ({ page }) => {
await page.goto('/');
// You are signed in!
});
```
```js tab=js-js
const { test } = require('@playwright/test');
test('test', async ({ page }) => {
await page.goto('/');
// You are signed in!
});
```
You can make arbitrary data available in your tests from your global setup file by setting them as environment variables via `process.env`.
```js tab=js-js
// global-setup.js
module.exports = async config => {
process.env.FOO = 'some data';
// Or a more complicated data structure as JSON:
process.env.BAR = JSON.stringify({ some: 'data' });
};
```
```js tab=js-ts
// global-setup.ts
import { FullConfig } from '@playwright/test';
async function globalSetup(config: FullConfig) {
process.env.FOO = 'some data';
// Or a more complicated data structure as JSON:
process.env.BAR = JSON.stringify({ some: 'data' });
}
export default globalSetup;
```
Tests have access to the `process.env` properties set in the global setup.
```js tab=js-ts
import { test } from '@playwright/test';
test('test', async ({ page }) => {
// environment variables which are set in globalSetup are only available inside test().
const { FOO, BAR } = process.env;
// FOO and BAR properties are populated.
expect(FOO).toEqual('some data');
const complexData = JSON.parse(BAR);
expect(BAR).toEqual({ some: 'data' });
});
```
```js tab=js-js
const { test } = require('@playwright/test');
test('test', async ({ page }) => {
// environment variables which are set in globalSetup are only available inside test().
const { FOO, BAR } = process.env;
// FOO and BAR properties are populated.
expect(FOO).toEqual('some data');
const complexData = JSON.parse(BAR);
expect(BAR).toEqual({ some: 'data' });
});
```
### Capturing trace of failures during global setup
In some instances, it may be useful to capture a trace of failures encountered during the global setup. In order to do this, you must [start tracing](./api/class-tracing.md#tracing-start) in your setup, and you must ensure that you [stop tracing](./api/class-tracing.md#tracing-stop) if an error occurs before that error is thrown. This can be achieved by wrapping your setup in a `try...catch` block. Here is an example that expands the global setup example to capture a trace.
```js tab=js-js
// global-setup.js
const { chromium } = require('@playwright/test');
module.exports = async config => {
const { baseURL, storageState } = config.projects[0].use;
const browser = await chromium.launch();
const context = await browser.newContext();
const page = await context.newPage();
try {
await context.tracing.start({ screenshots: true, snapshots: true });
await page.goto(baseURL);
await page.getByLabel('User Name').fill('user');
await page.getByLabel('Password').fill('password');
await page.getByText('Sign in').click();
await context.storageState({ path: storageState });
await context.tracing.stop({
path: './test-results/setup-trace.zip',
})
await browser.close();
} catch (error) {
await context.tracing.stop({
path: './test-results/failed-setup-trace.zip',
});
await browser.close();
throw error;
}
};
```
```js tab=js-ts
// global-setup.ts
import { chromium, FullConfig } from '@playwright/test';
async function globalSetup(config: FullConfig) {
const { baseURL, storageState } = config.projects[0].use;
const browser = await chromium.launch();
const context = await browser.newContext();
const page = await context.newPage();
try {
await context.tracing.start({ screenshots: true, snapshots: true });
await page.goto(baseURL!);
await page.getByLabel('User Name').fill('user');
await page.getByLabel('Password').fill('password');
await page.getByText('Sign in').click();
await context.storageState({ path: storageState as string });
await context.tracing.stop({
path: './test-results/setup-trace.zip',
})
await browser.close();
} catch (error) {
await context.tracing.stop({
path: './test-results/failed-setup-trace.zip',
});
await browser.close();
throw error;
}
}
export default globalSetup;
```
## Projects
Playwright Test supports running multiple test projects at the same time. This is useful for running the same or different tests in multiple configurations.
### Same tests, different configuration
Here is an example that runs the same tests in different browsers:
```js tab=js-js
// playwright.config.js
// @ts-check
const { devices } = require('@playwright/test');
const { defineConfig } = require('@playwright/test');
module.exports = defineConfig({
// Configure projects for major 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,
},
});
```
```js tab=js-ts
// playwright.config.ts
import { defineConfig, devices } from '@playwright/test';
| Option | Description |
| :- | :- |
| [`property: TestConfig.forbidOnly`] | Whether to exit with an error if any tests are marked as `test.only`. Useful on CI.|
| [`property: TestConfig.fullyParallel`] | have all tests in all files to run in parallel. See [/Parallelism and sharding](./test-parallel) for more details. |
| [`property: TestConfig.projects`] | Run tests in multiple configurations or on multiple browsers |
| [`property: TestConfig.reporter`] | Reporter to use. See [Test Reporters](/test-reporters.md) to learn more about which reporters are available. |
| [`property: TestConfig.retries`] | The maximum number of retry attempts per test. See [Test Retries](/test-retries.md) to learn more about retries.|
| [`property: TestConfig.testDir`] | Directory with the test files. |
| [`property: TestConfig.use`] | Options with `use{}` |
| [`property: TestConfig.webServer`] | To launch a server during the tests, use the `webServer` option |
| [`property: TestConfig.workers`] | The maximum number of concurrent worker processes to use for parallelizing tests. Can also be set as percentage of logical CPU cores, e.g. `'50%'.`. See [/Parallelism and sharding](./test-parallel) for more details. |
export default defineConfig({
projects: [
{
name: 'chromium',
use: { ...devices['Desktop Chrome'] },
},
{
name: 'firefox',
use: { ...devices['Desktop Firefox'] },
},
{
name: 'webkit',
use: { ...devices['Desktop Safari'] },
},
],
});
```
## Filtering Tests
You can run all projects or just a single one:
```bash
# Run both projects - each test will be run three times
npx playwright test
Filter tests by glob patterns or regular expressions.
# Run a single project - each test will be run once
npx playwright test --project=chromium
```
### Different tests, different configuration
Each project can be configured separately, and run different set of tests with different options. You can use [`property: TestProject.testDir`], [`property: TestProject.testMatch`] and [`property: TestProject.testIgnore`] to configure which tests should the project run.
Here is an example that runs projects with different tests and configurations. The "Smoke" project runs a small subset of tests without retries, and "Default" project runs all other tests with retries.
```js tab=js-ts
// playwright.config.ts
```js
import { defineConfig } from '@playwright/test';
export default defineConfig({
timeout: 60000, // Timeout is shared between all tests.
projects: [
{
name: 'Smoke',
testMatch: /.*smoke.spec.ts/,
retries: 0,
},
{
name: 'Default',
testIgnore: /.*smoke.spec.ts/,
retries: 2,
},
],
// Glob patterns or regular expressions to ignore test files.
testIgnore: '*test-assets',
// Glob patterns or regular expressions that match test files.
testMatch: '*todo-tests/*.spec.ts',
});
```
```js tab=js-js
// playwright.config.js
// @ts-check
const { defineConfig } = require('@playwright/test');
| Option | Description |
| :- | :- |
| [`property: TestConfig.testIgnore`] | Glob patterns or regular expressions that should be ignored when looking for the test files. For example, `'*test-assets'` |
| [`property: TestConfig.testMatch`] | Glob patterns or regular expressions that match test files. For example, `'*todo-tests/*.spec.ts'`. By default, Playwright runs `.*(test|spec)\.(js|ts|mjs)` files. |
module.exports = defineConfig({
timeout: 60000, // Timeout is shared between all tests.
projects: [
{
name: 'Smoke',
testMatch: /.*smoke.spec.ts/,
retries: 0,
## Advanced Configuration
```js
import { defineConfig } from '@playwright/test';
export default defineConfig({
// Folder for test artifacts such as screenshots, videos, traces, etc.
outputDir: 'test-results',
// path to the global setup files.
globalSetup: require.resolve('./global-setup'),
// path to the global teardown files.
globalTeardown: require.resolve('./global-teardown'),
// Each test is given 30 seconds.
timeout: 30000,
});
```
| Option | Description |
| :- | :- |
| [`property: TestConfig.globalSetup`] | Path to the global setup file. This file will be required and run before all the tests. It must export a single function. |
| [`property: TestConfig.globalTeardown`] |Path to the global teardown file. This file will be required and run after all the tests. It must export a single function. |
| [`property: TestConfig.outputDir`] | Folder for test artifacts such as screenshots, videos, traces, etc. |
| [`property: TestConfig.timeout`] | Playwright enforces a [timeout](./test-timeouts.md) for each test, 30 seconds by default. Time spent by the test function, fixtures, beforeEach and afterEach hooks is included in the test timeout. |
## Expect Options
Configuration for the expect assertion library.
```js
import { defineConfig } from '@playwright/test';
export default defineConfig({
expect: {
// Maximum time expect() should wait for the condition to be met.
timeout: 5000,
toHaveScreenshot: {
// An acceptable amount of pixels that could be different, unset by default.
maxDiffPixels: 10,
},
{
name: 'Default',
testIgnore: /.*smoke.spec.ts/,
retries: 2,
toMatchSnapshot: {
// An acceptable ratio of pixels that are different to the total amount of pixels, between 0 and 1.
maxDiffPixelRatio: 10,
},
],
},
});
```
You can run all projects or just a single one:
```bash
# Run both projects
npx playwright test
| Option | Description |
| :- | :- |
| [`property: TestConfig.expect`] | [Web first assertions](./test-assertions.md) like `expect(locator).toHaveText()` have a separate timeout of 5 seconds by default. This is the maximum time the `expect()` should wait for the condition to be met. Learn more about [test and expect timeouts](./test-timeouts.md) and how to set them for a single test. |
| [`method: PageAssertions.toHaveScreenshot#1`] | Configuration for the `expect(locator).toHaveScreeshot()` method. |
| [`method: SnapshotAssertions.toMatchSnapshot#1`]| Configuration for the `expect(locator).toMatchSnapshot()` method.|
# Run a single project
npx playwright test --project=Smoke
```
### Custom project parameters
Projects can be also used to parametrize tests with your custom configuration - take a look at [this separate guide](./test-parameterize.md#parameterized-projects).
## WorkerInfo object
Depending on the configuration and failures, Playwright Test might use different number of worker processes to run all the tests. For example, Playwright Test will always start a new worker process after a failing test.
Worker-scoped fixtures receive a [WorkerInfo] parameter that describes the current worker configuration. See [WorkerInfo] properties for available worker information.
Consider an example where we run a new http server per worker process, and use `workerIndex` to produce a unique port number:
```js tab=js-js
// my-test.js
const base = require('@playwright/test');
const http = require('http');
// Note how we mark the fixture as { scope: 'worker' }.
// Also note that we pass empty {} first, since we do not declare any test fixtures.
exports.test = base.test.extend({
server: [ async ({}, use, workerInfo) => {
// Start the server.
const server = http.createServer();
server.listen(9000 + workerInfo.workerIndex);
await new Promise(ready => server.once('listening', ready));
// Use the server in the tests.
await use(server);
// Cleanup.
await new Promise(done => server.close(done));
}, { scope: 'worker' } ]
});
```
```js tab=js-ts
// my-test.ts
import { test as base } from '@playwright/test';
import * as http from 'http';
// Note how we mark the fixture as { scope: 'worker' }.
// Also note that we pass empty {} first, since we do not declare any test fixtures.
export const test = base.extend<{}, { server: http.Server }>({
server: [ async ({}, use, workerInfo) => {
// Start the server.
const server = http.createServer();
server.listen(9000 + workerInfo.workerIndex);
await new Promise(ready => server.once('listening', ready));
// Use the server in the tests.
await use(server);
// Cleanup.
await new Promise(done => server.close(done));
}, { scope: 'worker' } ]
});
```
## Add custom matchers using expect.extend
### Add custom matchers using expect.extend
You can extend Playwright assertions by providing custom matchers. These matchers will be available on the `expect` object.

View file

@ -1,417 +1,200 @@
---
id: test-configuration
title: "Configuration"
title: "Test Options with use"
---
Playwright Test provides options to configure the default `browser`, `context` and `page` fixtures. For example there are options for `headless`, `viewport` and `ignoreHTTPSErrors`. You can also record a video or a trace for the test or capture a screenshot at the end.
In addition to configuring the test runner you can also configure [Emulation](#emulation-options), [Network](#network-options) and [Recording](#recording-options) for the [Browser] or [BrowserContext],. These options are passed to the `use: {}` object in the Playwright config.
There are plenty of testing options like `timeout` or `testDir` that configure how your tests are collected and executed.
### Basic Options
You can specify any options globally in the configuration file, and most of them locally in a test file.
Set the base URL and storage state for all tests:
See the full list of [test options][TestOptions] and all [configuration properties][TestConfig].
## Global configuration
Create a `playwright.config.js` (or `playwright.config.ts`) and specify options in the [`property: TestConfig.use`] section.
```js tab=js-js
// @ts-check
const { defineConfig } = require('@playwright/test');
module.exports = defineConfig({
use: {
headless: false,
viewport: { width: 1280, height: 720 },
ignoreHTTPSErrors: true,
video: 'on-first-retry',
},
});
```
```js tab=js-ts
```js
import { defineConfig } from '@playwright/test';
export default defineConfig({
use: {
headless: false,
viewport: { width: 1280, height: 720 },
ignoreHTTPSErrors: true,
video: 'on-first-retry',
// Base URL to use in actions like `await page.goto('/')`.
baseURL: 'http://127.0.0.1:3000'
// Populates context with given storage state.
storageState: 'state.json',
},
});
```
Now run tests as usual, Playwright Test will pick up the configuration file automatically.
```bash
npx playwright test
```
| Option | Description |
| :- | :- |
| [`property: TestOptions.baseURL`] | Base URL used for all pages in the context. Allows navigating by using just the path, for example `page.goto('/settings')`. |
| [`property: TestOptions.storageState`] | Populates context with given storage state. Useful for easy authentication, [learn more](./auth.md). |
If you put your configuration file in a different place, pass it with `--config` option.
### Emulation Options
```bash
npx playwright test --config=tests/my.config.js
```
With Playwright you can emulate a real device such as a mobile phone or tablet. See our [guide on projects](./test-projects.md) for more info on emulating devices. You can also emulate the `"geolocation"`, `"locale"` and `"timezone"` for all tests or for a specific test as well as set the `"permissions"` to show notifications or change the `"colorScheme"`. See our [Emulation](./emulation.md) guide to learn more.
## Local configuration
You can override some options for a file or describe block.
```js tab=js-js
// example.spec.js
const { test, expect } = require('@playwright/test');
// Run tests in this file with portrait-like viewport.
test.use({ viewport: { width: 600, height: 900 } });
test('my portrait test', async ({ page }) => {
// ...
});
```
```js tab=js-ts
// example.spec.ts
import { test, expect } from '@playwright/test';
// Run tests in this file with portrait-like viewport.
test.use({ viewport: { width: 600, height: 900 } });
test('my portrait test', async ({ page }) => {
// ...
});
```
The same works inside describe.
```js tab=js-js
// example.spec.js
const { test, expect } = require('@playwright/test');
test.describe('locale block', () => {
// Run tests in this describe block with portrait-like viewport.
test.use({ viewport: { width: 600, height: 900 } });
test('my portrait test', async ({ page }) => {
// ...
});
});
```
```js tab=js-ts
// example.spec.ts
import { test, expect } from '@playwright/test';
test.describe('locale block', () => {
// Run tests in this describe block with portrait-like viewport.
test.use({ viewport: { width: 600, height: 900 } });
test('my portrait test', async ({ page }) => {
// ...
});
});
```
## Basic options
Normally you would start with emulating a device, for example Desktop Chromium. See our [Emulation](./emulation.md) guide to learn more.
Here are some of the commonly used options for various scenarios. You usually set them globally in the [configuration file](#global-configuration).
- `actionTimeout` - Timeout for each Playwright action in milliseconds. Defaults to `0` (no timeout). Learn more about [various timeouts](./test-timeouts.md).
- `baseURL` - Base URL used for all pages in the context. Allows navigating by using just the path, for example `page.goto('/settings')`.
- `browserName` - Name of the browser that will run the tests, one of `chromium`, `firefox`, or `webkit`.
- `bypassCSP` - Toggles bypassing Content-Security-Policy. Useful when CSP includes the production origin.
- `channel` - Browser channel to use. [Learn more](./browsers.md) about different browsers and channels.
- `headless` - Whether to run the browser in headless mode.
- `viewport` - Viewport used for all pages in the context.
- `storageState` - Populates context with given storage state. Useful for easy authentication, [learn more](./auth.md).
- `colorScheme` - Emulates `'prefers-colors-scheme'` media feature, supported values are `'light'`, `'dark'`, `'no-preference'`.
- `geolocation` - Context geolocation.
- `locale` - [Emulates](./emulation.md) the user locale, for example `en-GB`, `de-DE`, etc.
- `permissions` - A list of permissions to grant to all pages in the context.
- `timezoneId` - Changes the timezone of the context.
```js tab=js-js
// @ts-check
const { defineConfig } = require('@playwright/test');
module.exports = defineConfig({
use: {
baseURL: 'http://localhost:3000',
browserName: 'firefox',
headless: true,
},
});
```
```js tab=js-ts
```js
import { defineConfig } from '@playwright/test';
export default defineConfig({
use: {
baseURL: 'http://localhost:3000',
browserName: 'firefox',
headless: true,
// Emulates `'prefers-colors-scheme'` media feature.
colorScheme: 'dark',
// Context geolocation.
geolocation: { longitude: 12.492507, latitude: 41.889938 },
// Emulates the user locale.
locale: 'en-GB',
// Grants specified permissions to the browser context.
permissions: 'geolocation',
// Emulates the user timezone.
timezoneId: 'Europe/Paris',
// Viewport used for all pages in the context.
viewport: { width: 1280, height: 720 },
},
});
```
## Multiple browsers
| Option | Description |
| :- | :- |
| [`property: TestOptions.colorScheme`] | [Emulates](./emulation.md#color-scheme-and-media) `'prefers-colors-scheme'` media feature, supported values are `'light'`, `'dark'`, `'no-preference'` |
| [`property: TestOptions.geolocation`] | Context [geolocation](./emulation.md#geolocation). |
| [`property: TestOptions.locale`] | [Emulates](./emulation.md#locale--timezone) the user locale, for example `en-GB`, `de-DE`, etc. |
| [`property: TestOptions.permissions`] | A list of [permissions](./emulation.md#permissions) to grant to all pages in the context. |
| [`property: TestOptions.timezoneId`] | Changes the [timezone](./emulation.md#locale--timezone) of the context. |
| [`property: TestOptions.viewport`] | [Viewport](./emulation.md#viewport) used for all pages in the context. |
Playwright Test supports multiple "projects" that can run your tests in multiple browsers and configurations. Here is an example that runs every test in Chromium, Firefox and WebKit, by creating a project for each.
```js tab=js-js
// playwright.config.js
// @ts-check
const { devices } = require('@playwright/test');
const { defineConfig } = require('@playwright/test');
module.exports = defineConfig({
projects: [
{
name: 'chromium',
use: { ...devices['Desktop Chrome'] },
},
{
name: 'firefox',
use: { ...devices['Desktop Firefox'] },
},
{
name: 'webkit',
use: { ...devices['Desktop Safari'] },
},
],
});
```
```js tab=js-ts
// playwright.config.ts
import { defineConfig, devices } from '@playwright/test';
export default defineConfig({
projects: [
{
name: 'chromium',
use: { ...devices['Desktop Chrome'] },
},
{
name: 'firefox',
use: { ...devices['Desktop Firefox'] },
},
{
name: 'webkit',
use: { ...devices['Desktop Safari'] },
},
],
});
```
You can specify [different options][TestProject] for each project, for example set specific command-line arguments for Chromium.
Playwright Test will run all projects by default.
```bash
npx playwright test
Running 5 tests using 5 workers
✓ [chromium] example.spec.ts:3:1 basic test (2s)
✓ [firefox] example.spec.ts:3:1 basic test (2s)
✓ [webkit] example.spec.ts:3:1 basic test (2s)
```
Use `--project` command line option to run a single project.
```bash
npx playwright test --project=firefox
Running 1 test using 1 worker
✓ [firefox] example.spec.ts:3:1 basic test (2s)
```
## Network
### Network Options
Available options to configure networking:
- `acceptDownloads` - Whether to automatically download all the attachments, defaults to `true`. [Learn more](./downloads.md) about working with downloads.
- `extraHTTPHeaders` - An object containing additional HTTP headers to be sent with every request. All header values must be strings.
- `httpCredentials` - Credentials for [HTTP authentication](./network.md#http-authentication).
- `ignoreHTTPSErrors` - Whether to ignore HTTPS errors during navigation.
- `offline` - Whether to emulate network being offline.
- `proxy` - [Proxy settings](./network.md#http-proxy) used for all pages in the test.
### Network mocking
You don't have to configure anything to mock network requests. Just define a custom [Route] that mocks network for a browser context.
```js tab=js-js
// example.spec.js
const { test, expect } = require('@playwright/test');
test.beforeEach(async ({ context }) => {
// Block any css requests for each test in this file.
await context.route(/.css/, route => route.abort());
});
test('loads page without css', async ({ page }) => {
await page.goto('https://playwright.dev');
// ... test goes here
});
```
```js tab=js-ts
// example.spec.ts
import { test, expect } from '@playwright/test';
test.beforeEach(async ({ context }) => {
// Block any css requests for each test in this file.
await context.route(/.css/, route => route.abort());
});
test('loads page without css', async ({ page }) => {
await page.goto('https://playwright.dev');
// ... test goes here
});
```
Alternatively, you can use [`method: Page.route`] to mock network in a single test.
```js tab=js-js
// example.spec.js
const { test, expect } = require('@playwright/test');
test('loads page without images', async ({ page }) => {
// Block png and jpeg images.
await page.route(/(png|jpeg)$/, route => route.abort());
await page.goto('https://playwright.dev');
// ... test goes here
});
```
```js tab=js-ts
// example.spec.ts
import { test, expect } from '@playwright/test';
test('loads page without images', async ({ page }) => {
// Block png and jpeg images.
await page.route(/(png|jpeg)$/, route => route.abort());
await page.goto('https://playwright.dev');
// ... test goes here
});
```
## Automatic screenshots
You can make Playwright Test capture screenshots for you - control it with the `screenshot` option. By default screenshots are off.
- `'off'` - Do not capture screenshots.
- `'on'` - Capture screenshot after each test.
- `'only-on-failure'` - Capture screenshot after each test failure.
Screenshots will appear in the test output directory, typically `test-results`.
```js tab=js-js
// @ts-check
const { defineConfig } = require('@playwright/test');
module.exports = defineConfig({
use: {
screenshot: 'only-on-failure',
},
});
```
```js tab=js-ts
```js
import { defineConfig } from '@playwright/test';
export default defineConfig({
use: {
screenshot: 'only-on-failure',
},
});
```
// Whether to automatically download all the attachments.
acceptDownloads: false,
## Record video
// An object containing additional HTTP headers to be sent with every request.
extraHTTPHeaders: {
'X-My-Header': 'value',
},
Playwright Test can record videos for your tests, controlled by the `video` option. By default videos are off.
// Credentials for HTTP authentication.
httpCredentials: {
username: 'user',
password: 'pass',
},
- `'off'` - Do not record video.
- `'on'` - Record video for each test.
- `'retain-on-failure'` - Record video for each test, but remove all videos from successful test runs.
- `'on-first-retry'` - Record video only when retrying a test for the first time.
// Whether to ignore HTTPS errors during navigation.
ignoreHTTPSErrors: true,
Video files will appear in the test output directory, typically `test-results`. See [`property: TestOptions.video`] for advanced video configuration.
// Whether to emulate network being offline.
offline: true,
```js tab=js-js
// @ts-check
const { defineConfig } = require('@playwright/test');
module.exports = defineConfig({
use: {
video: 'on-first-retry',
},
});
```
```js tab=js-ts
import { defineConfig } from '@playwright/test';
export default defineConfig({
use: {
video: 'on-first-retry',
},
});
```
## Record test trace
Playwright Test can produce test traces while running the tests. Later on, you can view the trace and get detailed information about Playwright execution by opening [Trace Viewer](./trace-viewer.md). By default tracing is off, controlled by the `trace` option.
- `'off'` - Do not record trace.
- `'on'` - Record trace for each test.
- `'retain-on-failure'` - Record trace for each test, but remove it from successful test runs.
- `'on-first-retry'` - Record trace only when retrying a test for the first time.
Trace files will appear in the test output directory, typically `test-results`. See [`property: TestOptions.trace`] for advanced configuration.
```js tab=js-js
// @ts-check
const { defineConfig } = require('@playwright/test');
module.exports = defineConfig({
use: {
trace: 'retain-on-failure',
},
});
```
```js tab=js-ts
import { defineConfig } from '@playwright/test';
export default defineConfig({
use: {
trace: 'retain-on-failure',
},
});
```
## More browser and context options
Any options accepted by [`method: BrowserType.launch`] or [`method: Browser.newContext`] can be put into `launchOptions` or `contextOptions` respectively in the `use` section. Take a look at the [full list of available options][TestOptions].
```js tab=js-js
// @ts-check
const { defineConfig } = require('@playwright/test');
module.exports = defineConfig({
use: {
launchOptions: {
slowMo: 50,
// Proxy settings used for all pages in the test.
proxy: {
server: 'http://myproxy.com:3128',
bypass: 'localhost',
},
},
});
```
| Option | Description |
| :- | :- |
| [`property: TestOptions.acceptDownloads`] | Whether to automatically download all the attachments, defaults to `true`. [Learn more](./downloads.md) about working with downloads. |
| [`property: TestOptions.extraHTTPHeaders`] | An object containing additional HTTP headers to be sent with every request. All header values must be strings. |
| [`property: TestOptions.httpCredentials`] | Credentials for [HTTP authentication](./network.md#http-authentication). |
| [`property: TestOptions.ignoreHTTPSErrors`] | Whether to ignore HTTPS errors during navigation. |
| [`property: TestOptions.offline`] | Whether to emulate network being offline. |
| [`property: TestOptions.proxy`] | [Proxy settings](./network.md#http-proxy) used for all pages in the test. |
```js tab=js-ts
:::note
You don't have to configure anything to mock network requests. Just define a custom [Route] that mocks the network for a browser context. See our [network mocking guide](./network.md) to learn more.
:::
### Recording Options
With Playwright you can capture screenshots, record videos as well as traces of your test. By default these are turned off but you can enable them by setting the `screenshot`, `video` and `trace` options in your `playwright.config.js` file.
Trace files, screenshots and videos will appear in the test output directory, typically `test-results`.
```js
import { defineConfig } from '@playwright/test';
export default defineConfig({
use: {
// Capture screenshot after each test failure.
screenshot: 'only-on-failure'
// Record trace only when retrying a test for the first time.
trace: 'on-first-retry',
// Record video only when retrying a test for the first time.
video: 'on-first-retry'
},
});
```
| Option | Description |
| :- | :- |
| [`property: TestOptions.screenshot`] | Capture [screenshots](./screenshots.md) of your test. Options include `'off'`, `'on'` and `'only-on-failure'` |
| [`property: TestOptions.trace`] | Playwright can produce test traces while running the tests. Later on, you can view the trace and get detailed information about Playwright execution by opening [Trace Viewer](./trace-viewer.md). Options include: `'off'`, `'on'`, `'retain-on-failure'` and `'on-first-retry'` |
| [`property: TestOptions.video`] | Playwright can record [videos](./videos.md) for your tests. Options include: `'off'`, `'on'`, `'retain-on-failure'` and `'on-first-retry'` |
### Other Options
```js
import { defineConfig } from '@playwright/test';
export default defineConfig({
use: {
// Maximum time each action such as `click()` can take. Defaults to 0 (no limit).
actionTimeout: 0,
// Name of the browser that runs tests. For example `chromium`, `firefox`, `webkit`.
browserName: 'chromium',
// Toggles bypassing Content-Security-Policy.
bypassCSP: true,
// Channel to use, for example "chrome", "chrome-beta", "msedge", "msedge-beta".
channel: 'chrome',
// Run browser in headless mode.
headless: false,
// Change the default data-testid attribute.
testIdAttribute: 'pw-test-id',
},
});
```
| Option | Description |
| :- | :- |
| [`property: TestOptions.actionTimeout`] | Timeout for each Playwright action in milliseconds. Defaults to `0` (no timeout). Learn more about [timeouts](./test-timeouts.md) and how to set them for a single test. |
| [`property: TestOptions.browserName`] | Name of the browser that runs tests. Defaults to 'chromium'. Options include `chromium`, `firefox`, or `webkit`. |
| [`property: TestOptions.bypassCSP`] |Toggles bypassing Content-Security-Policy. Useful when CSP includes the production origin. Defaults to `false`. |
| [`property: TestOptions.channel`] | Browser channel to use. [Learn more](./browsers.md) about different browsers and channels. |
| [`property: TestOptions.headless`] | Whether to run the browser in headless mode meaning no browser is shown when running tests. Defaults to `true`. |
| [`property: TestOptions.testIdAttribute`] | Changes the default [`data-testid` attribute](./locators.md#locate-by-test-id) used by Playwright locators. |
### More browser and context options
Any options accepted by [`method: BrowserType.launch`] or [`method: Browser.newContext`] can be put into `launchOptions` or `contextOptions` respectively in the `use` section.
```js
import { defineConfig } from '@playwright/test';
export default defineConfig({
use: {
launchOptions: {
@ -423,13 +206,13 @@ export default defineConfig({
However, most common ones like `headless` or `viewport` are available directly in the `use` section - see [basic options](#basic-options), [emulation](./emulation.md) or [network](#network).
## Explicit Context Creation and Option Inheritance
### Explicit Context Creation and Option Inheritance
If using the built-in `browser` fixture, calling [`method: Browser.newContext`] will create a context with options inherited from the config:
```js tab=js-ts
// playwright.config.ts
```js
import { defineConfig } from '@playwright/test';
export default defineConfig({
use: {
userAgent: 'some custom ua',
@ -438,24 +221,9 @@ export default defineConfig({
});
```
```js tab=js-js
// @ts-check
// example.spec.js
const { defineConfig } = require('@playwright/test');
module.exports = defineConfig({
use: {
userAgent: 'some custom ua',
viewport: { width: 100, height: 100 },
},
});
```
An example test illustrating the initial context options are set:
```js tab=js-ts
// example.spec.ts
```js
import { test, expect } from "@playwright/test";
test('should inherit use options on context when using built-in browser fixture', async ({
@ -469,93 +237,62 @@ test('should inherit use options on context when using built-in browser fixture'
});
```
```js tab=js-js
// @ts-check
// example.spec.ts
const { test, expect } = require("@playwright/test");
### Configuration Scopes
test('should inherit use options on context when using built-in browser fixture', async ({
browser,
}) => {
const context = await browser.newContext();
const page = await context.newPage();
expect(await page.evaluate(() => navigator.userAgent)).toBe('some custom ua');
expect(await page.evaluate(() => window.innerWidth)).toBe(100);
await context.close();
});
```
You can configure Playwright globally, per project, or per test. For example, you can set the locale to be used globally by adding `locale` to the `use` option of the Playwright config, and then override it for a specific project using the `project` option in the config. You can also override it for a specific test by adding `test.use({})` in the test file and passing in the options.
## Testing options
In addition to configuring [Browser] or [BrowserContext], videos or screenshots, Playwright Test has many options to configure how your tests are run. Below are the most common ones, see [TestConfig] for the full list.
- `forbidOnly`: Whether to exit with an error if any tests are marked as `test.only`. Useful on CI.
- `globalSetup`: Path to the global setup file. This file will be required and run before all the tests. It must export a single function.
- `globalTeardown`: Path to the global teardown file. This file will be required and run after all the tests. It must export a single function.
- `retries`: The maximum number of retry attempts per test.
- `testDir`: Directory with the test files.
- `testIdAttribute`: Set a custom data attribute for your [`method: Page.getByTestId`] locators.
- `testIgnore`: Glob patterns or regular expressions that should be ignored when looking for the test files. For example, `'**/test-assets'`.
- `testMatch`: Glob patterns or regular expressions that match test files. For example, `'**/todo-tests/*.spec.ts'`. By default, Playwright Test runs `.*(test|spec)\.(js|ts|mjs)` files.
- `timeout`: Time in milliseconds given to each test. Learn more about [various timeouts](./test-timeouts.md).
- `webServer: { command: string, port?: number, url?: string, ignoreHTTPSErrors?: boolean, timeout?: number, reuseExistingServer?: boolean, cwd?: string, env?: object }` - Launch a process and wait that it's ready before the tests will start. See [launch web server](./test-advanced.md#launching-a-development-web-server-during-the-tests) configuration for examples.
- `workers`: The maximum number of concurrent worker processes to use for parallelizing tests. Can also be set as percentage of logical CPU cores, e.g. `'50%'.`
You can specify these options in the configuration file. Note that testing options are **top-level**, do not put them into the `use` section.
```js tab=js-js
// playwright.config.js
// @ts-check
const { defineConfig } = require('@playwright/test');
module.exports = defineConfig({
// Look for test files in the "tests" directory, relative to this configuration file
testDir: 'tests',
// change the default data-testid to a custom attribute
testIdAttribute: 'data-pw'
// Each test is given 30 seconds
timeout: 30000,
// Forbid test.only on CI
forbidOnly: !!process.env.CI,
// Two retries for each test
retries: 2,
// Limit the number of workers on CI, use default locally
workers: process.env.CI ? 2 : undefined,
use: {
// Configure browser and context here
},
});
```
```js tab=js-ts
// playwright.config.ts
```js
import { defineConfig } from '@playwright/test';
export default defineConfig({
// Look for test files in the "tests" directory, relative to this configuration file
testDir: 'tests',
// Each test is given 30 seconds
timeout: 30000,
// Forbid test.only on CI
forbidOnly: !!process.env.CI,
// Two retries for each test
retries: 2,
// Limit the number of workers on CI, use default locally
workers: process.env.CI ? 2 : undefined,
use: {
// Configure browser and context here
locale: 'en-GB'
},
});
```
You can override options for a specific project using the `project` option in the Playwright config.
```js
import { defineConfig, devices } from '@playwright/test';
export default defineConfig({
projects: [
{
name: 'chromium',
use: {
...devices['Desktop Chrome'],
locale: 'de-DE'
},
},
],
});
```
You can override options for a specific test file by using the `test.use()` method and passing in the options. For example to run tests with the French locale for a specific test:
```js
import { test, expect } from '@playwright/test';
test.use({ locale: 'fr-FR' });
test('example', async ({ page }) => {
// ...
});
```
The same works inside a describe block. For example to run tests in a describe block with the French locale:
```js
import { test, expect } from '@playwright/test';
test.describe('french language block', () => {
test.use({ { locale: 'fr-FR' }});
test('example', async ({ page }) => {
// ...
});
});
```