Skip to content

Latest commit

 

History

History
234 lines (179 loc) · 8.55 KB

test-configuration-js.md

File metadata and controls

234 lines (179 loc) · 8.55 KB
id title
test-configuration
Test configuration

Introduction

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.

Basic Configuration

Here are some of the most common configuration options.

import { defineConfig, devices } from '@playwright/test';

export default defineConfig({
  // Look for test files in the "tests" directory, relative to this configuration file.
  testDir: 'tests',

  // Run all tests in parallel.
  fullyParallel: true,

  // Fail the build on CI if you accidentally left test.only in the source code.
  forbidOnly: !!process.env.CI,

  // Retry on CI only.
  retries: process.env.CI ? 2 : 0,

  // Opt out of parallel tests on CI.
  workers: process.env.CI ? 1 : undefined,

  // Reporter to use
  reporter: 'html',

  use: {
    // 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',
  },
  // Configure projects for major browsers.
  projects: [
    {
      name: 'chromium',
      use: { ...devices['Desktop Chrome'] },
    },
  ],
  // 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,
  },
});
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 for more details.
[property: TestConfig.projects] Run tests in multiple configurations or on multiple browsers
[property: TestConfig.reporter] Reporter to use. See Test Reporters to learn more about which reporters are available.
[property: TestConfig.retries] The maximum number of retry attempts per test. See Test Retries 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 for more details.

Filtering Tests

Filter tests by glob patterns or regular expressions.

import { defineConfig } from '@playwright/test';

export default defineConfig({
  // 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',
});
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.

Advanced Configuration

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 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.

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,
    },

    toMatchSnapshot: {
      // An acceptable ratio of pixels that are different to the
      // total amount of pixels, between 0 and 1.
      maxDiffPixelRatio: 0.1,
    },
  },

});
Option Description
[property: TestConfig.expect] Web first assertions 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 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.

Add custom matchers using expect.extend

You can extend Playwright assertions by providing custom matchers. These matchers will be available on the expect object.

In this example we add a custom toHaveAmount function. Custom matcher should return a message callback and a pass flag indicating whether the assertion passed.

import { expect as baseExpect } from '@playwright/test';
import type { Page, Locator } from '@playwright/test';

export { test } from '@playwright/test';

export const expect = baseExpect.extend({
  async toHaveAmount(locator: Locator, expected: number, options?: { timeout?: number }) {
    let pass: boolean;
    let matcherResult: any;
    try {
      await baseExpect(locator).toHaveAttribute('data-amount', String(expected), options);
      pass = true;
    } catch (e: any) {
      matcherResult = e.matcherResult;
      pass = false;
    }

    const message = pass
      ? () => this.utils.matcherHint('toHaveAmount', undefined, undefined, { isNot: this.isNot }) +
          '\n\n' +
          `Locator: ${locator}\n`,
          `Expected: ${this.isNot ? 'not' : ''}${this.utils.printExpected(expected)}\n` +
          (matcherResult ? `Received: ${this.utils.printReceived(matcherResult.actual)}` : '')
      : () =>  this.utils.matcherHint('toHaveAmount', undefined, undefined, expectOptions) +
          '\n\n' +
          `Locator: ${locator}\n`,
          `Expected: ${this.utils.printExpected(expected)}\n` +
          (matcherResult ? `Received: ${this.utils.printReceived(matcherResult.actual)}` : '');

    return {
      message,
      pass,
      name: 'toHaveAmount',
      expected,
      actual: matcherResult?.actual,
    };
  },
});

Now we can use toHaveAmount in the test.

import { test, expect } from './fixtures';

test('amount', async () => {
  await expect(page.locator('.cart')).toHaveAmount(4);
});

:::note Do not confuse Playwright's expect with the expect library. The latter is not fully integrated with Playwright test runner, so make sure to use Playwright's own expect. :::

Combine custom matchers from multiple modules

You can combine custom matchers from multiple files or modules.

import { mergeTests, mergeExpects } from '@playwright/test';
import { test as dbTest, expect as dbExpect } from 'database-test-utils';
import { test as a11yTest, expect as a11yExpect } from 'a11y-test-utils';

export const expect = mergeExpects(dbExpect, a11yExpect);
export const test = mergeTests(dbTest, a11yTest);
import { test, expect } from './fixtures';

test('passes', async ({ database }) => {
  await expect(database).toHaveDatabaseUser('admin');
});