Playwright is a framework for Web Testing and Automation. It allows testing Chromium, Firefox and WebKit with a single API.
APACHE-2.0 License
Bot releases are hidden (Show)
Published by mxschmitt 29 days ago
https://github.com/microsoft/playwright/pull/32699- [REGRESSION]: fix(codegen): use content_frame property in python/.NET
https://github.com/microsoft/playwright/issues/32706- [REGRESSION]: page.pause() does not pause test timeout after 1.47
https://github.com/microsoft/playwright/pull/32661 - fix(trace-viewer): time delta between local and remote actions
This version was also tested against the following stable channels:
Published by mxschmitt about 1 month ago
https://github.com/microsoft/playwright/issues/32480 - [REGRESSION]: tsconfig.json's compilerOptions.paths no longer working in 1.47
https://github.com/microsoft/playwright/issues/32552 - [REGRESSION]: broken UI in Trace Viewer while showing network response body
This version was also tested against the following stable channels:
The Network tab in the UI mode and trace viewer has several nice improvements:
Credit to @kubajanik for these wonderful improvements!
--tsconfig
CLI optionBy default, Playwright will look up the closest tsconfig for each imported file using a heuristic. You can now specify a single tsconfig file in the command line, and Playwright will use it for all imported files, not only test files:
# Pass a specific tsconfig
npx playwright test --tsconfig tsconfig.test.json
URLSearchParams
and string
as query parametersYou can now pass URLSearchParams
and string
as query parameters to APIRequestContext:
test('query params', async ({ request }) => {
const searchParams = new URLSearchParams();
searchParams.set('userId', 1);
const response = await request.get(
'https://jsonplaceholder.typicode.com/posts',
{
params: searchParams // or as a string: 'userId=1'
}
);
// ...
});
mcr.microsoft.com/playwright:v1.47.0
now serves a Playwright image based on Ubuntu 24.04 Noble.mcr.microsoft.com/playwright:v1.47.0-jammy
instead.:latest
tag for Playwright Docker images is no longer being published. Pin to a specific version for better stability and reproducibility.behavior
in page.removeAllListeners(), browser.removeAllListeners() and browserContext.removeAllListeners() to wait for ongoing listeners to complete.cert
and key
as buffers instead of file paths.text/html
content type can now be opened in a new tab in the HTML report. This is useful for including third-party reports or other HTML content in the Playwright test report and distributing it to your team.noWaitAfter
in locator.selectOption() was deprecated.macos-13
. We recommend upgrading GitHub Actions to macos-14
.This version was also tested against the following stable channels:
Published by mxschmitt 2 months ago
https://github.com/microsoft/playwright/issues/32004 - [REGRESSION]: Client Certificates don't work with Microsoft IIS
https://github.com/microsoft/playwright/issues/32004 - [REGRESSION]: Websites stall on TLS handshake errors when using Client Certificates
https://github.com/microsoft/playwright/issues/32146 - [BUG]: Credential scanners warn about internal socks-proxy TLS certificates
https://github.com/microsoft/playwright/issues/32056 - [REGRESSION]: 1.46.0 (TypeScript) - custom fixtures extend no longer chainable
https://github.com/microsoft/playwright/issues/32070 - [Bug]: --only-changed flag and project dependencies
https://github.com/microsoft/playwright/issues/32188 - [Bug]: --only-changed with shallow clone throws "unknown revision" error
This version was also tested against the following stable channels:
Published by dgozman 2 months ago
Playwright now allows to supply client-side certificates, so that server can verify them, as specified by TLS Client Authentication.
When client certificates are specified, all browser traffic is routed through a proxy that establishes the secure TLS connection, provides client certificates to the server and validates server certificates.
The following snippet sets up a client certificate for https://example.com
:
import { defineConfig } from '@playwright/test';
export default defineConfig({
// ...
use: {
clientCertificates: [{
origin: 'https://example.com',
certPath: './cert.pem',
keyPath: './key.pem',
passphrase: 'mysecretpassword',
}],
},
// ...
});
You can also provide client certificates to a particular test project or as a parameter of browser.newContext() and apiRequest.newContext().
--only-changed
cli optionNew CLI option --only-changed
allows to only run test files that have been changed since the last git commit or from a specific git "ref".
# Only run test files with uncommitted changes
npx playwright test --only-changed
# Only run test files changed relative to the "main" branch
npx playwright test --only-changed=main
router
fixtureThis release introduces an experimental router
fixture to intercept and handle network requests in component testing.
There are two ways to use the router fixture:
router.route(url, handler)
that behaves similarly to page.route().router.use(handlers)
and pass MSW library request handlers to it.Here is an example of reusing your existing MSW handlers in the test.
import { handlers } from '@src/mocks/handlers';
test.beforeEach(async ({ router }) => {
// install common handlers before each test
await router.use(...handlers);
});
test('example test', async ({ mount }) => {
// test as usual, your handlers are active
// ...
});
This fixture is only available in component tests.
baseURL
.maxRetries
option in apiRequestContext.fetch() which retries on the ECONNRESET
network error.Fixture values that are array of objects, when specified in the test.use()
block, may require being wrapped into a fixture tuple. This is best seen on the example:
import { test as base } from '@playwright/test';
// Define an option fixture that has an "array of objects" value
type User = { name: string, password: string };
const test = base.extend<{ users: User[] }>({
users: [ [], { option: true } ],
});
// Specify option value in the test.use block.
test.use({
// WRONG: this syntax may not work for you
users: [
{ name: 'John Doe', password: 'secret' },
{ name: 'John Smith', password: 's3cr3t' },
],
// CORRECT: this syntax will work. Note extra [] around the value, and the "scope" property.
users: [[
{ name: 'John Doe', password: 'secret' },
{ name: 'John Smith', password: 's3cr3t' },
], { scope: 'test' }],
});
test('example test', async () => {
// ...
});
This version was also tested against the following stable channels:
Published by yury-s 3 months ago
https://github.com/microsoft/playwright/issues/31764 - [Bug]: some actions do not appear in the trace file
https://github.com/microsoft/playwright-java/issues/1617 - [Bug]: Traceviewer not reporting all actions
This version was also tested against the following stable channels:
Published by mxschmitt 3 months ago
https://github.com/microsoft/playwright/issues/31613 - [REGRESSION]: Trace is not showing any screenshots nor test name
https://github.com/microsoft/playwright/issues/31601 - [REGRESSION]: missing trace for 2nd browser
https://github.com/microsoft/playwright/issues/31541 - [REGRESSION]: Failing tests have a trace with no images and with steps missing
This version was also tested against the following stable channels:
Published by mxschmitt 4 months ago
https://github.com/microsoft/playwright/issues/31473 - [REGRESSION]: Playwright raises an error ENOENT: no such file or directory, open 'test-results/.playwright-artifacts-0/hash.zip' with Electron
https://github.com/microsoft/playwright/issues/31442 - [REGRESSION]: Locators of elements changing from/to hidden have operations hanging when using --disable-web-security
https://github.com/microsoft/playwright/issues/31431 - [REGRESSION]: NewTab doesn't work properly with Chrome with --disable-web-security
https://github.com/microsoft/playwright/issues/31425 - [REGRESSION]: beforeEach hooks are not skipped when describe condition depends on fixtures
https://github.com/microsoft/playwright/issues/31491 - [REGRESSION]: @playwright/experimental-ct-react
doesn't work with VSCode extension and PNPM
This version was also tested against the following stable channels:
Published by dgozman 4 months ago
Utilizing the new Clock API allows to manipulate and control time within tests to verify time-related behavior. This API covers many common scenarios, including:
// Initialize clock and let the page load naturally.
await page.clock.install({ time: new Date('2024-02-02T08:00:00') });
await page.goto('http://localhost:3333');
// Pretend that the user closed the laptop lid and opened it again at 10am,
// Pause the time once reached that point.
await page.clock.pauseAt(new Date('2024-02-02T10:00:00'));
// Assert the page state.
await expect(page.getByTestId('current-time')).toHaveText('2/2/2024, 10:00:00 AM');
// Close the laptop lid again and open it at 10:30am.
await page.clock.fastForward('30:00');
await expect(page.getByTestId('current-time')).toHaveText('2/2/2024, 10:30:00 AM');
See the clock guide for more details.
New CLI option --fail-on-flaky-tests
that sets exit code to 1
upon any flaky tests. Note that by default, the test runner exits with code 0
when all failed tests recovered upon a retry. With this option, the test run will fail in such case.
New enviroment variable PLAYWRIGHT_FORCE_TTY
controls whether built-in list
, line
and dot
reporters assume a live terminal. For example, this could be useful to disable tty behavior when your CI environment does not handle ANSI control sequences well. Alternatively, you can enable tty behavior even when to live terminal is present, if you plan to post-process the output and handle control sequences.
# Avoid TTY features that output ANSI control sequences
PLAYWRIGHT_FORCE_TTY=0 npx playwright test
# Enable TTY features, assuming a terminal width 80
PLAYWRIGHT_FORCE_TTY=80 npx playwright test
New options testConfig.respectGitIgnore and testProject.respectGitIgnore control whether files matching .gitignore
patterns are excluded when searching for tests.
New property timeout
is now available for custom expect matchers. This property takes into account playwright.config.ts
and expect.configure()
.
import { expect as baseExpect } from '@playwright/test';
export const expect = baseExpect.extend({
async toHaveAmount(locator: Locator, expected: number, options?: { timeout?: number }) {
// When no timeout option is specified, use the config timeout.
const timeout = options?.timeout ?? this.timeout;
// ... implement the assertion ...
},
});
Method locator.setInputFiles() now supports uploading a directory for <input type=file webkitdirectory>
elements.
await page.getByLabel('Upload directory').setInputFiles(path.join(__dirname, 'mydir'));
Multiple methods like locator.click() or locator.press() now support a ControlOrMeta
modifier key. This key maps to Meta
on macOS and maps to Control
on Windows and Linux.
// Press the common keyboard shortcut Control+S or Meta+S to trigger a "Save" operation.
await page.keyboard.press('ControlOrMeta+S');
New property httpCredentials.send
in apiRequest.newContext() that allows to either always send the Authorization
header or only send it in response to 401 Unauthorized
.
New option reason
in apiRequestContext.dispose() that will be included in the error message of ongoing operations interrupted by the context disposal.
New option host
in browserType.launchServer() allows to accept websocket connections on a specific address instead of unspecified 0.0.0.0
.
Playwright now supports Chromium, Firefox and WebKit on Ubuntu 24.04.
v1.45 is the last release to receive WebKit update for macOS 12 Monterey. Please update macOS to keep using the latest WebKit.
This version was also tested against the following stable channels:
Published by mxschmitt 5 months ago
https://github.com/microsoft/playwright/issues/30779 - [REGRESSION]: When using video: 'on'
with VSCode extension the browser got closed
https://github.com/microsoft/playwright/issues/30755 - [REGRESSION]: Electron launch with spaces inside executablePath didn't work
https://github.com/microsoft/playwright/issues/30770 - [REGRESSION]: Mask elements outside of viewport when creating fullscreen screenshots didn't work
https://github.com/microsoft/playwright/issues/30858 - [REGRESSION]: ipv6 got shown instead of localhost in show-trace/show-report
This version was also tested against the following stable channels:
Published by yury-s 6 months ago
Accessibility assertions
expect(locator).toHaveAccessibleName() checks if the element has the specified accessible name:
const locator = page.getByRole('button');
await expect(locator).toHaveAccessibleName('Submit');
expect(locator).toHaveAccessibleDescription() checks if the element has the specified accessible description:
const locator = page.getByRole('button');
await expect(locator).toHaveAccessibleDescription('Upload a photo');
expect(locator).toHaveRole() checks if the element has the specified ARIA role:
const locator = page.getByTestId('save-button');
await expect(locator).toHaveRole('button');
Locator handler
noWaitAfter
option.times
option in page.addLocatorHandler() to specify maximum number of times the handler should be run.const locator = page.getByText('This interstitial covers the button');
await page.addLocatorHandler(locator, async overlay => {
await overlay.locator('#close').click();
}, { times: 3, noWaitAfter: true });
// Run your tests that can be interrupted by the overlay.
// ...
await page.removeLocatorHandler(locator);
Miscellaneous options
multipart
option in apiRequestContext.fetch()
now accepts FormData
and supports repeating fields with the same name.
const formData = new FormData();
formData.append('file', new File(['let x = 2024;'], 'f1.js', { type: 'text/javascript' }));
formData.append('file', new File(['hello'], 'f2.txt', { type: 'text/plain' }));
context.request.post('https://example.com/uploadFiles', {
multipart: formData
});
expect(callback).toPass({ intervals })
can now be configured by expect.toPass.inervals
option globally in testConfig.expect or per project in testProject.expect.
expect(page).toHaveURL(url)
now supports ignoreCase
option.
testProject.ignoreSnapshots allows to configure per project whether to skip screenshot expectations.
Reporter API
outputFile
. The same option can also be specified as PLAYWRIGHT_BLOB_OUTPUT_FILE
environment variable that might be more convenient on CI/CD.includeProjectInTestName
option.Command line
--last-failed
CLI option for running only tests that failed in the previous run.
First run all tests:
$ npx playwright test
Running 103 tests using 5 workers
...
2 failed
[chromium] › my-test.spec.ts:8:5 › two ─────────────────────────────────────────────────────────
[chromium] › my-test.spec.ts:13:5 › three ──────────────────────────────────────────────────────
101 passed (30.0s)
Now fix the failing tests and run Playwright again with --last-failed
option:
$ npx playwright test --last-failed
Running 2 tests using 2 workers
2 passed (1.2s)
This version was also tested against the following stable channels:
Published by dgozman 6 months ago
https://github.com/microsoft/playwright/issues/30300 - [REGRESSION]: UI mode restarts if keep storage state
https://github.com/microsoft/playwright/issues/30339 - [REGRESSION]: Brand new install of playwright, unable to run chromium with show browser using vscode
This version was also tested against the following stable channels:
Published by dgozman 7 months ago
Method browserContext.clearCookies() now supports filters to remove only some cookies.
// Clear all cookies.
await context.clearCookies();
// New: clear cookies with a particular name.
await context.clearCookies({ name: 'session-id' });
// New: clear cookies for a particular domain.
await context.clearCookies({ domain: 'my-origin.com' });
New mode retain-on-first-failure
for testOptions.trace. In this mode, trace is recorded for the first run of each test, but not for retires. When test run fails, the trace file is retained, otherwise it is removed.
import { defineConfig } from '@playwright/test';
export default defineConfig({
use: {
trace: 'retain-on-first-failure',
},
});
New property testInfo.tags exposes test tags during test execution.
test('example', async ({ page }) => {
console.log(test.info().tags);
});
New method locator.contentFrame() converts a Locator
object to a FrameLocator
. This can be useful when you have a Locator
object obtained somewhere, and later on would like to interact with the content inside the frame.
const locator = page.locator('iframe[name="embedded"]');
// ...
const frameLocator = locator.contentFrame();
await frameLocator.getByRole('button').click();
New method frameLocator.owner() converts a FrameLocator
object to a Locator
. This can be useful when you have a FrameLocator
object obtained somewhere, and later on would like to interact with the iframe
element.
const frameLocator = page.frameLocator('iframe[name="embedded"]');
// ...
const locator = frameLocator.owner();
await expect(locator).toBeVisible();
@fast
or clicking on the tag itself.This version was also tested against the following stable channels:
Published by dgozman 8 months ago
https://github.com/microsoft/playwright/issues/29732 - [Regression]: HEAD requests to webServer.url since v1.42.0
https://github.com/microsoft/playwright/issues/29746 - [Regression]: Playwright CT CLI scripts fail due to broken initializePlugin import
https://github.com/microsoft/playwright/issues/29739 - [Bug]: Component tests fails when imported a module with a dot in a name
https://github.com/microsoft/playwright/issues/29731 - [Regression]: 1.42.0 breaks some import statements
https://github.com/microsoft/playwright/issues/29760 - [Bug]: Possible regression with chained locators in v1.42
This version was also tested against the following stable channels:
Published by yury-s 8 months ago
Test tags
New tag syntax for adding tags to the tests (@-tokens in the test title are still supported).
test('test customer login', { tag: ['@fast', '@login'] }, async ({ page }) => {
// ...
});
Use --grep
command line option to run only tests with certain tags.
npx playwright test --grep @fast
Annotating skipped tests
New annotation syntax for test annotations allows annotating the tests that do not run.
test('test full report', {
annotation: [
{ type: 'issue', description: 'https://github.com/microsoft/playwright/issues/23180' },
{ type: 'docs', description: 'https://playwright.dev/docs/test-annotations#tag-tests' },
],
}, async ({ page }) => {
// ...
});
page.addLocatorHandler()
[!WARNING]
This feature is experimental, we are actively looking for the feedback based on your scenarios.
New method page.addLocatorHandler() registers a callback that will be invoked when specified element becomes visible and may block Playwright actions. The callback can get rid of the overlay. Here is an example that closes a cookie dialog when it appears.
// Setup the handler.
await page.addLocatorHandler(
page.getByRole('heading', { name: 'Hej! You are in control of your cookies.' }),
async () => {
await page.getByRole('button', { name: 'Accept all' }).click();
});
// Write the test as usual.
await page.goto('https://www.ikea.com/');
await page.getByRole('link', { name: 'Collection of blue and white' }).click();
await expect(page.getByRole('heading', { name: 'Light and easy' })).toBeVisible();
Project wildcard filter
Playwright command line flag now supports '*' wildcard when filtering by project.
npx playwright test --project='*mobile*'
Other APIs
expect(callback).toPass({ timeout })
The timeout can now be configured by expect.toPass.timeout
option globally or in project config
electronApplication.on('console')
electronApplication.on('console') event is emitted when Electron main process calls console API methods.
electronApp.on('console', async msg => {
const values = [];
for (const arg of msg.args())
values.push(await arg.jsonValue());
console.log(...values);
});
await electronApp.evaluate(() => console.log('hello', 5, { foo: 'bar' }));
page.pdf() accepts two new options tagged
and outline
.
Mixing the test instances in the same suite is no longer supported. Allowing it was an oversight as it makes reasoning about the semantics unnecessarily hard.
const test = baseTest.extend({ item: async ({}, use) => {} });
baseTest.describe('Admin user', () => {
test('1', async ({ page, item }) => {});
test('2', async ({ page, item }) => {});
});
This version was also tested against the following stable channels:
Published by mxschmitt 9 months ago
https://github.com/microsoft/playwright/issues/29123 - [REGRESSION] route.continue: Protocol error (Fetch.continueRequest): Invalid InterceptionId.
This version was also tested against the following stable channels:
Published by mxschmitt 9 months ago
https://github.com/microsoft/playwright/issues/29067 - [REGRESSION] Codegen/Recorder: not all clicks are being actioned nor recorded
https://github.com/microsoft/playwright/issues/29028 - [REGRESSION] React component tests throw type error when passing null/undefined to component
https://github.com/microsoft/playwright/issues/29027 - [REGRESSION] React component tests not passing Date prop values
https://github.com/microsoft/playwright/issues/29023 - [REGRESSION] React component tests not rendering children prop
https://github.com/microsoft/playwright/issues/29019 - [REGRESSION] trace.playwright.dev does not currently support the loading from URL
This version was also tested against the following stable channels:
Published by mxschmitt 9 months ago
style
in page.screenshot([options]) and locator.screenshot([options]) to add custom CSS to the page before taking a screenshot.stylePath
for methods expect(page).toHaveScreenshot(name[, options]) and expect(locator).toHaveScreenshot(name[, options]) to apply a custom stylesheet while making the screenshot.fileName
option for Blob reporter, to specify the name of the report to be created.This version was also tested against the following stable channels:
Published by dgozman 11 months ago
https://github.com/microsoft/playwright/issues/28319 - [REGRESSION]: Version 1.40.0 Produces corrupted traces
https://github.com/microsoft/playwright/issues/28371 - [BUG] The color of the 'ok' text did not change to green in the vs code test results section
https://github.com/microsoft/playwright/issues/28321 - [BUG] Ambiguous test outcome and status for serial mode
https://github.com/microsoft/playwright/issues/28362 - [BUG] Merging blobs ends up in Error: Cannot create a string longer than 0x1fffffe8 characters
https://github.com/microsoft/playwright/pull/28239 - fix: collect all errors in removeFolders
This version was also tested against the following stable channels:
Published by dgozman 11 months ago
New tools to generate assertions:
Here is an example of a generated test with assertions:
import { test, expect } from '@playwright/test';
test('test', async ({ page }) => {
await page.goto('https://playwright.dev/');
await page.getByRole('link', { name: 'Get started' }).click();
await expect(page.getByLabel('Breadcrumbs').getByRole('list')).toContainText('Installation');
await expect(page.getByLabel('Search')).toBeVisible();
await page.getByLabel('Search').click();
await page.getByPlaceholder('Search docs').fill('locator');
await expect(page.getByPlaceholder('Search docs')).toHaveValue('locator');
});
reason
in page.close(), browserContext.close() and browser.close(). Close reason is reported for all operations interrupted by the closure.firefoxUserPrefs
in browserType.launchPersistentContext(userDataDir).This version was also tested against the following stable channels: