Skip to content


Choose a tag to compare
@aslushnikov aslushnikov released this 13 Aug 23:40

Playwright v1.14 updates

馃幁 Playwright Library

鈿★笍 New "strict" mode

Selector ambiguity is a common problem in automation testing. "strict" mode
ensures that your selector points to a single element and throws otherwise.

Pass strict: true into your action calls to opt in.

// This will throw if you have more than one button!
await'button', { strict: true });

馃搷 New Locators API

Locator represents a view to the element(s) on the page. It captures the logic sufficient to retrieve the element at any given moment.

The difference between the Locator and ElementHandle is that the latter points to a particular element, while Locator captures the logic of how to retrieve that element.

Also, locators are "strict" by default!

const locator = page.locator('button');

Learn more in the documentation.

馃З Experimental React and Vue selector engines

React and Vue selectors allow selecting elements by its component name and/or property values. The syntax is very similar to attribute selectors and supports all attribute selector operators.


Learn more in the react selectors documentation and the vue selectors documentation.

鉁 New nth and visible selector engines

  • nth selector engine is equivalent to the :nth-match pseudo class, but could be combined with other selector engines.
  • visible selector engine is equivalent to the :visible pseudo class, but could be combined with other selector engines.
// select the first button among all buttons
await'button >> nth=0');
// or if you are using locators, you can use first(), nth() and last()
await page.locator('button').first().click();

// click a visible button
await'button >> visible=true');

馃幁 Playwright Test

鉁 Web-First Assertions

expect now supports lots of new web-first assertions.

Consider the following example:

await expect(page.locator('.status')).toHaveText('Submitted');

Playwright Test will be re-testing the node with the selector .status until fetched Node has the "Submitted" text. It will be re-fetching the node and checking it over and over, until the condition is met or until the timeout is reached. You can either pass this timeout or configure it once via the testProject.expect value in test config.

By default, the timeout for assertions is not set, so it'll wait forever, until the whole test times out.

List of all new assertions:

鉀 Serial mode with describe.serial

Declares a group of tests that should always be run serially. If one of the tests fails, all subsequent tests are skipped. All tests in a group are retried together.

test.describe.serial('group', () => {
  test('runs first', async ({ page }) => { /* ... */ });
  test('runs second', async ({ page }) => { /* ... */ });

Learn more in the documentation.

馃惥 Steps API with test.step

Split long tests into multiple steps using test.step() API:

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

test('test', async ({ page }) => {
  await test.step('Log in', async () => {
    // ...
  await test.step('news feed', async () => {
    // ...

Step information is exposed in reporters API.

馃寧 Launch web server before running tests

To launch a server during the tests, use the webServer option in the configuration file. The server will wait for a given port to be available before running the tests, and the port will be passed over to Playwright as a baseURL when creating a context.

// playwright.config.ts
import { PlaywrightTestConfig } from '@playwright/test';
const config: PlaywrightTestConfig = {
  webServer: {
    command: 'npm run start', // command to launch
    port: 3000, // port to await for 
    timeout: 120 * 1000, 
    reuseExistingServer: !process.env.CI,
export default config;

Learn more in the documentation.

Browser Versions

  • Chromium 94.0.4595.0
  • Mozilla Firefox 91.0
  • WebKit 15.0

This version of Playwright was also tested against the following stable channels:

  • Google Chrome 92
  • Microsoft Edge 92