From 715f843204bbe12977535e24d22d5932056f1995 Mon Sep 17 00:00:00 2001
From: "microsoft-playwright-automation[bot]"
<203992400+microsoft-playwright-automation[bot]@users.noreply.github.com>
Date: Wed, 12 Aug 2026 10:30:11 +0000
Subject: [PATCH] feat(roll): roll to ToT Playwright (12-08-26)
---
dotnet/docs/api/class-apirequestcontext.mdx | 2 +
dotnet/docs/api/class-browser.mdx | 6 +
dotnet/docs/api/class-browsertype.mdx | 3 +
dotnet/docs/api/class-frame.mdx | 6 +
dotnet/docs/api/class-page.mdx | 6 +
dotnet/docs/api/class-tracing.mdx | 2 +-
dotnet/docs/browsers.mdx | 2 +-
dotnet/docs/ci.mdx | 10 +-
dotnet/docs/docker.mdx | 18 +-
dotnet/docs/emulation.mdx | 2 +-
dotnet/docs/getting-started-cli.mdx | 43 +-
dotnet/docs/release-notes.mdx | 28 +
java/docs/api/class-apirequestcontext.mdx | 2 +
java/docs/api/class-browser.mdx | 6 +
java/docs/api/class-browsertype.mdx | 3 +
java/docs/api/class-frame.mdx | 6 +
java/docs/api/class-page.mdx | 6 +
java/docs/api/class-tracing.mdx | 2 +-
java/docs/browsers.mdx | 2 +-
java/docs/getting-started-cli.mdx | 43 +-
java/docs/release-notes.mdx | 30 +
nodejs/docs/accessibility-testing.mdx | 1 +
nodejs/docs/actionability.mdx | 1 +
nodejs/docs/api-testing.mdx | 1 +
nodejs/docs/api/class-android.mdx | 1 +
nodejs/docs/api/class-androiddevice.mdx | 4 +
nodejs/docs/api/class-androidinput.mdx | 1 +
nodejs/docs/api/class-androidsocket.mdx | 1 +
nodejs/docs/api/class-androidwebview.mdx | 1 +
nodejs/docs/api/class-apirequest.mdx | 1 +
nodejs/docs/api/class-apirequestcontext.mdx | 3 +
nodejs/docs/api/class-apiresponse.mdx | 1 +
.../docs/api/class-apiresponseassertions.mdx | 1 +
nodejs/docs/api/class-browser.mdx | 7 +
nodejs/docs/api/class-browsercontext.mdx | 1 +
nodejs/docs/api/class-browserserver.mdx | 1 +
nodejs/docs/api/class-browsertype.mdx | 4 +
nodejs/docs/api/class-by.mdx | 565 ++++++++++++++++++
nodejs/docs/api/class-cdpsession.mdx | 1 +
nodejs/docs/api/class-clock.mdx | 1 +
nodejs/docs/api/class-consolemessage.mdx | 1 +
nodejs/docs/api/class-coverage.mdx | 1 +
nodejs/docs/api/class-credentials.mdx | 1 +
nodejs/docs/api/class-debugger.mdx | 1 +
nodejs/docs/api/class-dialog.mdx | 1 +
nodejs/docs/api/class-disposable.mdx | 1 +
nodejs/docs/api/class-download.mdx | 1 +
nodejs/docs/api/class-electron.mdx | 1 +
nodejs/docs/api/class-electronapplication.mdx | 1 +
nodejs/docs/api/class-elementhandle.mdx | 1 +
nodejs/docs/api/class-filechooser.mdx | 1 +
nodejs/docs/api/class-fixtures.mdx | 1 +
nodejs/docs/api/class-frame.mdx | 49 ++
nodejs/docs/api/class-framelocator.mdx | 43 ++
nodejs/docs/api/class-fullconfig.mdx | 1 +
nodejs/docs/api/class-fullproject.mdx | 1 +
nodejs/docs/api/class-genericassertions.mdx | 1 +
nodejs/docs/api/class-jshandle.mdx | 1 +
nodejs/docs/api/class-keyboard.mdx | 1 +
nodejs/docs/api/class-location.mdx | 1 +
nodejs/docs/api/class-locator.mdx | 91 +++
nodejs/docs/api/class-locatorassertions.mdx | 1 +
nodejs/docs/api/class-logger.mdx | 1 +
nodejs/docs/api/class-mouse.mdx | 1 +
nodejs/docs/api/class-page.mdx | 85 +++
nodejs/docs/api/class-pageassertions.mdx | 1 +
nodejs/docs/api/class-playwright.mdx | 28 +
.../docs/api/class-playwrightassertions.mdx | 1 +
nodejs/docs/api/class-reporter.mdx | 1 +
nodejs/docs/api/class-request.mdx | 1 +
nodejs/docs/api/class-response.mdx | 1 +
nodejs/docs/api/class-route.mdx | 1 +
nodejs/docs/api/class-screencast.mdx | 1 +
nodejs/docs/api/class-selectors.mdx | 1 +
nodejs/docs/api/class-snapshotassertions.mdx | 1 +
nodejs/docs/api/class-suite.mdx | 1 +
nodejs/docs/api/class-test.mdx | 1 +
nodejs/docs/api/class-testcase.mdx | 1 +
nodejs/docs/api/class-testconfig.mdx | 1 +
nodejs/docs/api/class-testerror.mdx | 1 +
nodejs/docs/api/class-testinfo.mdx | 1 +
nodejs/docs/api/class-testinfoerror.mdx | 1 +
nodejs/docs/api/class-testoptions.mdx | 106 +++-
nodejs/docs/api/class-testproject.mdx | 1 +
nodejs/docs/api/class-testresult.mdx | 1 +
nodejs/docs/api/class-testrun.mdx | 1 +
nodejs/docs/api/class-teststep.mdx | 1 +
nodejs/docs/api/class-teststepinfo.mdx | 1 +
nodejs/docs/api/class-timeouterror.mdx | 1 +
nodejs/docs/api/class-touchscreen.mdx | 1 +
nodejs/docs/api/class-tracing.mdx | 18 +-
nodejs/docs/api/class-video.mdx | 1 +
nodejs/docs/api/class-weberror.mdx | 1 +
nodejs/docs/api/class-websocket.mdx | 1 +
nodejs/docs/api/class-websocketroute.mdx | 1 +
nodejs/docs/api/class-webstorage.mdx | 1 +
nodejs/docs/api/class-worker.mdx | 1 +
nodejs/docs/api/class-workerinfo.mdx | 1 +
nodejs/docs/aria-snapshots.mdx | 1 +
nodejs/docs/auth.mdx | 1 +
nodejs/docs/best-practices.mdx | 1 +
nodejs/docs/browser-contexts.mdx | 1 +
nodejs/docs/browsers.mdx | 3 +-
nodejs/docs/canary-releases.mdx | 1 +
nodejs/docs/chrome-extensions.mdx | 1 +
nodejs/docs/ci-intro.mdx | 1 +
nodejs/docs/ci.mdx | 21 +-
nodejs/docs/clock.mdx | 1 +
nodejs/docs/codegen-intro.mdx | 1 +
nodejs/docs/codegen.mdx | 1 +
nodejs/docs/debug.mdx | 1 +
nodejs/docs/dialogs.mdx | 1 +
nodejs/docs/docker.mdx | 21 +-
nodejs/docs/downloads.mdx | 1 +
nodejs/docs/emulation.mdx | 3 +-
nodejs/docs/evaluating.mdx | 1 +
nodejs/docs/events.mdx | 1 +
nodejs/docs/extensibility.mdx | 1 +
nodejs/docs/frames.mdx | 1 +
nodejs/docs/getting-started-cli.mdx | 44 +-
nodejs/docs/getting-started-mcp.mdx | 1 +
nodejs/docs/getting-started-vscode.mdx | 1 +
nodejs/docs/handles.mdx | 1 +
nodejs/docs/input.mdx | 1 +
nodejs/docs/intro.mdx | 1 +
nodejs/docs/languages.mdx | 1 +
nodejs/docs/library.mdx | 1 +
nodejs/docs/locators.mdx | 34 ++
nodejs/docs/mock-browser.mdx | 1 +
nodejs/docs/mock.mdx | 1 +
nodejs/docs/navigations.mdx | 1 +
nodejs/docs/network.mdx | 1 +
nodejs/docs/other-locators.mdx | 1 +
nodejs/docs/pages.mdx | 1 +
nodejs/docs/pom.mdx | 1 +
nodejs/docs/protractor.mdx | 1 +
nodejs/docs/puppeteer.mdx | 1 +
nodejs/docs/release-notes.mdx | 2 +
nodejs/docs/running-tests.mdx | 1 +
nodejs/docs/screenshots.mdx | 1 +
nodejs/docs/selenium-grid.mdx | 1 +
nodejs/docs/service-workers.mdx | 1 +
nodejs/docs/test-agents.mdx | 1 +
nodejs/docs/test-annotations.mdx | 1 +
nodejs/docs/test-assertions.mdx | 1 +
nodejs/docs/test-cli.mdx | 1 +
nodejs/docs/test-components.mdx | 5 +-
nodejs/docs/test-configuration.mdx | 1 +
nodejs/docs/test-fixtures.mdx | 1 +
nodejs/docs/test-global-setup-teardown.mdx | 1 +
nodejs/docs/test-parallel.mdx | 1 +
nodejs/docs/test-parameterize.mdx | 1 +
nodejs/docs/test-projects.mdx | 3 +-
nodejs/docs/test-reporters.mdx | 1 +
nodejs/docs/test-retries.mdx | 1 +
nodejs/docs/test-sharding.mdx | 1 +
nodejs/docs/test-snapshots.mdx | 1 +
nodejs/docs/test-timeouts.mdx | 1 +
nodejs/docs/test-typescript.mdx | 1 +
nodejs/docs/test-ui-mode.mdx | 1 +
nodejs/docs/test-use-options.mdx | 1 +
nodejs/docs/test-webserver.mdx | 1 +
nodejs/docs/testing-library.mdx | 42 +-
nodejs/docs/touch-events.mdx | 1 +
nodejs/docs/trace-viewer-intro.mdx | 1 +
nodejs/docs/trace-viewer.mdx | 1 +
nodejs/docs/videos.mdx | 1 +
nodejs/docs/webview2.mdx | 1 +
nodejs/docs/writing-tests.mdx | 1 +
python/docs/api/class-apirequestcontext.mdx | 2 +
python/docs/api/class-browser.mdx | 6 +
python/docs/api/class-browsertype.mdx | 3 +
python/docs/api/class-frame.mdx | 91 +--
python/docs/api/class-page.mdx | 91 +--
python/docs/api/class-tracing.mdx | 2 +-
python/docs/browsers.mdx | 2 +-
python/docs/ci.mdx | 12 +-
python/docs/docker.mdx | 20 +-
python/docs/emulation.mdx | 2 +-
python/docs/getting-started-cli.mdx | 43 +-
python/docs/release-notes.mdx | 28 +
src/components/GitHubStarButton/index.tsx | 2 +-
182 files changed, 1643 insertions(+), 196 deletions(-)
create mode 100644 nodejs/docs/api/class-by.mdx
diff --git a/dotnet/docs/api/class-apirequestcontext.mdx b/dotnet/docs/api/class-apirequestcontext.mdx
index 90e4351a03..68b708efdc 100644
--- a/dotnet/docs/api/class-apirequestcontext.mdx
+++ b/dotnet/docs/api/class-apirequestcontext.mdx
@@ -577,6 +577,8 @@ await ApiRequestContext.StorageStateAsync(options);
Added in: v1.60apiRequestContext.Tracing
+Tracing recorder for requests made through this API request context.
+
**Usage**
```csharp
diff --git a/dotnet/docs/api/class-browser.mdx b/dotnet/docs/api/class-browser.mdx
index 0ca1d4a6ff..9104f28fa0 100644
--- a/dotnet/docs/api/class-browser.mdx
+++ b/dotnet/docs/api/class-browser.mdx
@@ -311,6 +311,9 @@ await browser.CloseAsync();
- `Permissions` [IEnumerable]?<[string]> *(optional)*#
A list of permissions to grant to all pages in this context. See [BrowserContext.GrantPermissionsAsync()](/api/class-browsercontext.mdx#browser-context-grant-permissions) for more details. Defaults to none.
+ - `PierceFrames` [bool]? *(optional)*#
+
+ If set to true, all selectors in this context will pierce frames by default, as if every locator was created through [Page.PierceFrames()](/api/class-page.mdx#page-pierce-frames). Defaults to `false`.
- `Proxy` Proxy? *(optional)*#
- `Server` [string]
@@ -533,6 +536,9 @@ await Browser.NewPageAsync(options);
- `Permissions` [IEnumerable]?<[string]> *(optional)*#
A list of permissions to grant to all pages in this context. See [BrowserContext.GrantPermissionsAsync()](/api/class-browsercontext.mdx#browser-context-grant-permissions) for more details. Defaults to none.
+ - `PierceFrames` [bool]? *(optional)*#
+
+ If set to true, all selectors in this context will pierce frames by default, as if every locator was created through [Page.PierceFrames()](/api/class-page.mdx#page-pierce-frames). Defaults to `false`.
- `Proxy` Proxy? *(optional)*#
- `Server` [string]
diff --git a/dotnet/docs/api/class-browsertype.mdx b/dotnet/docs/api/class-browsertype.mdx
index fd6bbb2de7..352cd2c242 100644
--- a/dotnet/docs/api/class-browsertype.mdx
+++ b/dotnet/docs/api/class-browsertype.mdx
@@ -461,6 +461,9 @@ await BrowserType.LaunchPersistentContextAsync(userDataDir, options);
- `Permissions` [IEnumerable]?<[string]> *(optional)*#
A list of permissions to grant to all pages in this context. See [BrowserContext.GrantPermissionsAsync()](/api/class-browsercontext.mdx#browser-context-grant-permissions) for more details. Defaults to none.
+ - `PierceFrames` [bool]? *(optional)*#
+
+ If set to true, all selectors in this context will pierce frames by default, as if every locator was created through [Page.PierceFrames()](/api/class-page.mdx#page-pierce-frames). Defaults to `false`.
- `Proxy` Proxy? *(optional)*#
- `Server` [string]
diff --git a/dotnet/docs/api/class-frame.mdx b/dotnet/docs/api/class-frame.mdx
index 32c2b5dd2d..11c29790cb 100644
--- a/dotnet/docs/api/class-frame.mdx
+++ b/dotnet/docs/api/class-frame.mdx
@@ -900,6 +900,12 @@ var locator = frame.PierceFrames.GetByRole(AriaRole.Button);
await locator.ClickAsync();
```
+**Arguments**
+- `options` `FramePierceFramesOptions?` *(optional)*
+ - `Pierce` [bool]? *(optional)*#
+
+ Whether to pierce frames. Pass `false` to opt out of frame piercing enabled by the [PierceFrames](/api/class-browser.mdx#browser-new-context-option-pierce-frames) context option. Defaults to `true`.
+
**Returns**
- [FrameLocator]#
diff --git a/dotnet/docs/api/class-page.mdx b/dotnet/docs/api/class-page.mdx
index 72421c21b4..6e4b686dbc 100644
--- a/dotnet/docs/api/class-page.mdx
+++ b/dotnet/docs/api/class-page.mdx
@@ -1643,6 +1643,12 @@ var locator = page.PierceFrames.GetByRole(AriaRole.Button);
await locator.ClickAsync();
```
+**Arguments**
+- `options` `PagePierceFramesOptions?` *(optional)*
+ - `Pierce` [bool]? *(optional)*#
+
+ Whether to pierce frames. Pass `false` to opt out of frame piercing enabled by the [PierceFrames](/api/class-browser.mdx#browser-new-context-option-pierce-frames) context option. Defaults to `true`.
+
**Returns**
- [FrameLocator]#
diff --git a/dotnet/docs/api/class-tracing.mdx b/dotnet/docs/api/class-tracing.mdx
index 44cad0d0d8..082083f0e7 100644
--- a/dotnet/docs/api/class-tracing.mdx
+++ b/dotnet/docs/api/class-tracing.mdx
@@ -218,7 +218,7 @@ await context.Tracing.StopChunkAsync(new()
Start recording a HAR (HTTP Archive) of network activity in this context. The HAR file is written to disk when [Tracing.StopHarAsync()](/api/class-tracing.mdx#tracing-stop-har) is called, or when the returned [Disposable] is disposed.
-Only one HAR recording can be active at a time per [BrowserContext].
+Only one HAR recording can be active at a time per [Tracing] instance.
**Usage**
diff --git a/dotnet/docs/browsers.mdx b/dotnet/docs/browsers.mdx
index f3e6ebc4fb..ce3076574f 100644
--- a/dotnet/docs/browsers.mdx
+++ b/dotnet/docs/browsers.mdx
@@ -68,7 +68,7 @@ See [system requirements](./intro.mdx#system-requirements) for officially suppor
## Configure Browsers
-Playwright can run tests on Chromium, WebKit and Firefox browsers as well as branded browsers such as Google Chrome and Microsoft Edge. It can also run on emulated tablet and mobile devices. See the [registry of device parameters](https://github.com/microsoft/playwright/blob/main/packages/playwright-core/src/server/deviceDescriptorsSource.json) for a complete list of selected desktop, tablet and mobile devices.
+Playwright can run tests on Chromium, WebKit and Firefox browsers as well as branded browsers such as Google Chrome and Microsoft Edge. It can also run on emulated tablet and mobile devices. See the [registry of device parameters](https://github.com/microsoft/playwright/blob/main/packages/isomorphic/deviceDescriptorsSource.json) for a complete list of selected desktop, tablet and mobile devices.
### Run tests on different browsers
diff --git a/dotnet/docs/ci.mdx b/dotnet/docs/ci.mdx
index 9ee53130e2..cef755a891 100644
--- a/dotnet/docs/ci.mdx
+++ b/dotnet/docs/ci.mdx
@@ -76,7 +76,7 @@ jobs:
name: 'Playwright Tests'
runs-on: ubuntu-latest
container:
- image: mcr.microsoft.com/playwright/dotnet:v1.61.0-noble
+ image: mcr.microsoft.com/playwright/dotnet:v1.62.0-noble
options: --user 1001
steps:
- uses: actions/checkout@v6
@@ -159,7 +159,7 @@ trigger:
pool:
vmImage: ubuntu-latest
-container: mcr.microsoft.com/playwright/dotnet:v1.61.0-noble
+container: mcr.microsoft.com/playwright/dotnet:v1.62.0-noble
steps:
- task: UseDotNet@2
@@ -182,7 +182,7 @@ Running Playwright on CircleCI is very similar to running on GitHub Actions. In
executors:
pw-noble-development:
docker:
- - image: mcr.microsoft.com/playwright/dotnet:v1.61.0-noble
+ - image: mcr.microsoft.com/playwright/dotnet:v1.62.0-noble
```
Note: When using the docker agent definition, you are specifying the resource class of where playwright runs to the 'medium' tier [here](https://circleci.com/docs/configuration-reference?#docker-execution-environment). The default behavior of Playwright is to set the number of workers to the detected core count (2 in the case of the medium tier). Overriding the number of workers to greater than this number will cause unnecessary timeouts and failures.
@@ -193,7 +193,7 @@ Jenkins supports Docker agents for pipelines. Use the [Playwright Docker image](
```groovy
pipeline {
- agent { docker { image 'mcr.microsoft.com/playwright/dotnet:v1.61.0-noble' } }
+ agent { docker { image 'mcr.microsoft.com/playwright/dotnet:v1.62.0-noble' } }
stages {
stage('e2e-tests') {
steps {
@@ -210,7 +210,7 @@ pipeline {
Bitbucket Pipelines can use public [Docker images as build environments](https://confluence.atlassian.com/bitbucket/use-docker-images-as-build-environments-792298897.html). To run Playwright tests on Bitbucket, use our public Docker image ([see Dockerfile](./docker.mdx)).
```yml
-image: mcr.microsoft.com/playwright/dotnet:v1.61.0-noble
+image: mcr.microsoft.com/playwright/dotnet:v1.62.0-noble
```
### GitLab CI
diff --git a/dotnet/docs/docker.mdx b/dotnet/docs/docker.mdx
index c4c21db04f..b2968fedc1 100644
--- a/dotnet/docs/docker.mdx
+++ b/dotnet/docs/docker.mdx
@@ -22,7 +22,7 @@ This Docker image is intended to be used for testing and development purposes on
### Pull the image
```bash
-docker pull mcr.microsoft.com/playwright/dotnet:v1.61.0-noble
+docker pull mcr.microsoft.com/playwright/dotnet:v1.62.0-noble
```
### Run the image
@@ -34,7 +34,7 @@ By default, the Docker image will use the `root` user to run the browsers. This
On trusted websites, you can avoid creating a separate user and use root for it since you trust the code which will run on the browsers.
```bash
-docker run -it --rm --ipc=host mcr.microsoft.com/playwright/dotnet:v1.61.0-noble /bin/bash
+docker run -it --rm --ipc=host mcr.microsoft.com/playwright/dotnet:v1.62.0-noble /bin/bash
```
#### Crawling and scraping
@@ -42,7 +42,7 @@ docker run -it --rm --ipc=host mcr.microsoft.com/playwright/dotnet:v1.61.0-noble
On untrusted websites, it's recommended to use a separate user for launching the browsers in combination with the seccomp profile. Inside the container or if you are using the Docker image as a base image you have to use `adduser` for it.
```bash
-docker run -it --rm --ipc=host --user pwuser --security-opt seccomp=seccomp_profile.json mcr.microsoft.com/playwright/dotnet:v1.61.0-noble /bin/bash
+docker run -it --rm --ipc=host --user pwuser --security-opt seccomp=seccomp_profile.json mcr.microsoft.com/playwright/dotnet:v1.62.0-noble /bin/bash
```
[`seccomp_profile.json`](https://github.com/microsoft/playwright/blob/main/utils/docker/seccomp_profile.json) is needed to run Chromium with sandbox. This is a [default Docker seccomp profile](https://github.com/docker/engine/blob/d0d99b04cf6e00ed3fc27e81fc3d94e7eda70af3/profiles/seccomp/default.json) with extra user namespace cloning permissions:
@@ -82,7 +82,7 @@ You can run Playwright Server in Docker while keeping your tests running on the
Start the Playwright Server in Docker:
```bash
-docker run -p 3000:3000 --rm --init -it --workdir /home/pwuser --user pwuser mcr.microsoft.com/playwright:v1.61.0-noble /bin/sh -c "npx -y playwright@1.61.0 run-server --port 3000 --host 0.0.0.0"
+docker run -p 3000:3000 --rm --init -it --workdir /home/pwuser --user pwuser mcr.microsoft.com/playwright:v1.62.0-noble /bin/sh -c "npx -y playwright@1.62.0 run-server --port 3000 --host 0.0.0.0"
```
#### Connecting to the Server
@@ -99,7 +99,7 @@ await using var browser = await playwright.Chromium.ConnectAsync("ws://127.0.0.1
If you need to access local servers from within the Docker container:
```bash
-docker run --add-host=hostmachine:host-gateway -p 3000:3000 --rm --init -it --workdir /home/pwuser --user pwuser mcr.microsoft.com/playwright:v1.61.0-noble /bin/sh -c "npx -y playwright@1.61.0 run-server --port 3000 --host 0.0.0.0"
+docker run --add-host=hostmachine:host-gateway -p 3000:3000 --rm --init -it --workdir /home/pwuser --user pwuser mcr.microsoft.com/playwright:v1.62.0-noble /bin/sh -c "npx -y playwright@1.62.0 run-server --port 3000 --host 0.0.0.0"
```
This makes `hostmachine` point to the host's localhost. Your tests should use `hostmachine` instead of `localhost` when accessing local servers.
@@ -132,10 +132,10 @@ Once this is enabled you can open the port specified in a new browser tab and yo
See [all available image tags].
We currently publish images with the following tags:
-- `:v1.61.0` - Playwright v1.61.0 release docker image based on Ubuntu 24.04 LTS (Noble Numbat).
-- `:v1.61.0-noble` - Playwright v1.61.0 release docker image based on Ubuntu 24.04 LTS (Noble Numbat).
-- `:v1.61.0-jammy` - Playwright v1.61.0 release docker image based on Ubuntu 22.04 LTS (Jammy Jellyfish).
-- `:v1.61.0-resolute` - Playwright v1.61.0 release docker image based on Ubuntu 26.04 LTS (Resolute Raccoon).
+- `:v1.62.0` - Playwright v1.62.0 release docker image based on Ubuntu 24.04 LTS (Noble Numbat).
+- `:v1.62.0-noble` - Playwright v1.62.0 release docker image based on Ubuntu 24.04 LTS (Noble Numbat).
+- `:v1.62.0-jammy` - Playwright v1.62.0 release docker image based on Ubuntu 22.04 LTS (Jammy Jellyfish).
+- `:v1.62.0-resolute` - Playwright v1.62.0 release docker image based on Ubuntu 26.04 LTS (Resolute Raccoon).
:::note
diff --git a/dotnet/docs/emulation.mdx b/dotnet/docs/emulation.mdx
index a25624864d..f86ddacb08 100644
--- a/dotnet/docs/emulation.mdx
+++ b/dotnet/docs/emulation.mdx
@@ -12,7 +12,7 @@ With Playwright you can test your app on any browser as well as emulate a real d
## Devices
-Playwright comes with a [registry of device parameters](https://github.com/microsoft/playwright/blob/main/packages/playwright-core/src/server/deviceDescriptorsSource.json) using [Playwright.Devices](/api/class-playwright.mdx#playwright-devices) for selected desktop, tablet and mobile devices. It can be used to simulate browser behavior for a specific device such as user agent, screen size, viewport and if it has touch enabled. All tests will run with the specified device parameters.
+Playwright comes with a [registry of device parameters](https://github.com/microsoft/playwright/blob/main/packages/isomorphic/deviceDescriptorsSource.json) using [Playwright.Devices](/api/class-playwright.mdx#playwright-devices) for selected desktop, tablet and mobile devices. It can be used to simulate browser behavior for a specific device such as user agent, screen size, viewport and if it has touch enabled. All tests will run with the specified device parameters.
```csharp
using Microsoft.Playwright;
diff --git a/dotnet/docs/getting-started-cli.mdx b/dotnet/docs/getting-started-cli.mdx
index 69684ba510..7081a524ca 100644
--- a/dotnet/docs/getting-started-cli.mdx
+++ b/dotnet/docs/getting-started-cli.mdx
@@ -17,25 +17,30 @@ Playwright comes with `playwright-cli`, a command-line interface for browser aut
## Prerequisites
Before you begin, make sure you have the following installed:
-- [Node.js](https://nodejs.org/) 20 or newer
+- Playwright for your language, **or** [Node.js](https://nodejs.org/) 20+ for the standalone `@playwright/cli` package
- A coding agent: Claude Code, GitHub Copilot, or similar
## Installation
-Install `playwright-cli` globally:
+Install the standalone CLI globally (works with any language):
```bash
npm install -g @playwright/cli@latest
playwright-cli --help
```
-Alternatively, install `@playwright/cli` as a local dependency and use `npx`:
+Or use the CLI bundled with your Playwright install:
```bash
-npm install -D @playwright/cli@latest
-npx playwright-cli --help
+# JavaScript / TypeScript
+npx playwright cli --help
+
+# Python
+python -m playwright cli --help
```
+When using a bundled entry point, replace `playwright-cli` with `npx playwright cli` or `python -m playwright cli` in the commands below.
+
### Installing skills
Coding agents like Claude Code and GitHub Copilot can use locally installed skills for richer context about available commands:
@@ -44,6 +49,12 @@ Coding agents like Claude Code and GitHub Copilot can use locally installed skil
playwright-cli install --skills
```
+To share the skills across all your projects, add the `-g` flag to install them into your home directory (`~/.claude/skills` or, with `--skills=agents`, `~/.agents/skills`):
+
+```bash
+playwright-cli install --skills -g
+```
+
### Skills-less operation
You can also point your agent at the CLI directly and let it discover commands on its own:
@@ -103,7 +114,7 @@ playwright-cli check # check a checkbox or radio button
playwright-cli uncheck # uncheck a checkbox
playwright-cli hover # hover over element
playwright-cli drag # drag and drop between elements
-playwright-cli upload # upload files
+playwright-cli upload # upload one or multiple files
playwright-cli close # close the page
```
@@ -289,11 +300,29 @@ playwright-cli attach --extension
This requires the [Playwright Extension](https://github.com/microsoft/playwright/blob/main/packages/extension/README.md) to be installed.
+## Debugging tests
+
+Coding agents can pause a test at the start, attach with `playwright-cli`, and explore the live browser — useful for diagnosing and fixing failures.
+
+```bash
+# JavaScript / TypeScript
+PLAYWRIGHT_HTML_OPEN=never npx playwright test --debug=cli
+# → Debugging Instructions with session name, e.g. tw-abcdef
+playwright-cli attach tw-abcdef
+
+# Python (pytest-playwright; -s keeps the attach line visible)
+pytest --playwright-debug=cli -s
+playwright-cli attach tw-abcdef
+```
+
+Keep the test running in the background while you attach. The installed skill documents this workflow for agents.
+
## Quick Reference
| Action | Command |
| ------------------------- | --------------------------------------------------- |
| **Install CLI** | `npm install -g @playwright/cli@latest` |
+| **Use bundled CLI** | `npx playwright cli …` / `python -m playwright cli …` |
| **Install skills** | `playwright-cli install --skills` |
| **Open a page** | `playwright-cli open https://example.com` |
| **Click an element** | `playwright-cli click e15` |
@@ -303,6 +332,8 @@ This requires the [Playwright Extension](https://github.com/microsoft/playwright
| **Run headed** | `playwright-cli open https://example.com --headed` |
| **Use Firefox** | `playwright-cli open --browser=firefox` |
| **Monitor sessions** | `playwright-cli show` |
+| **Debug JS test** | `npx playwright test --debug=cli` |
+| **Debug Python test** | `pytest --playwright-debug=cli -s` |
## What's Next
- [Write tests using web-first assertions, page fixtures, and locators](./writing-tests.mdx)
diff --git a/dotnet/docs/release-notes.mdx b/dotnet/docs/release-notes.mdx
index f510706f5b..6c0b50157f 100644
--- a/dotnet/docs/release-notes.mdx
+++ b/dotnet/docs/release-notes.mdx
@@ -9,6 +9,34 @@ import HTMLCard from '@site/src/components/HTMLCard';
import LiteYouTube from '@site/src/components/LiteYouTube';
+## Version 1.62
+
+### 🖼️ WebP screenshots
+
+[Page.ScreenshotAsync()](/api/class-page.mdx#page-screenshot) and [Locator.ScreenshotAsync()](/api/class-locator.mdx#locator-screenshot) can now capture screenshots in the WebP format — Playwright infers the format from a `.webp` file extension, or you can set the `type` explicitly. Quality `100` (the default) is lossless, while lower values use lossy compression:
+
+```csharp
+await page.ScreenshotAsync(new() { Path = "homepage.webp", Quality = 50 });
+```
+
+### New APIs
+- New `scroll` option (`"auto"` | `"none"`) on actions to opt out of Playwright's automatic scroll-into-view.
+- New [Locator.WaitForFunctionAsync()](/api/class-locator.mdx#locator-wait-for-function) waits until a function — called with the matching element — returns a truthy value.
+- New [ApiResponse.Timing](/api/class-apiresponse.mdx#api-response-timing) returns resource timing information for an API response.
+
+### Announcements
+* 📋 The clipboard is now isolated from the operating system in headless mode, so tests that use `navigator.clipboard` no longer read or overwrite the clipboard of the machine running them.
+* ⚠️ Debian 11 is not supported anymore.
+
+### Browser Versions
+- Chromium 151.0.7922.34
+- Mozilla Firefox 153.0
+- WebKit 26.5
+
+This version was also tested against the following stable channels:
+- Google Chrome 151
+- Microsoft Edge 151
+
## Version 1.61
### 🔑 WebAuthn passkeys
diff --git a/java/docs/api/class-apirequestcontext.mdx b/java/docs/api/class-apirequestcontext.mdx
index b2ac3bbf9f..ea64030771 100644
--- a/java/docs/api/class-apirequestcontext.mdx
+++ b/java/docs/api/class-apirequestcontext.mdx
@@ -318,6 +318,8 @@ APIRequestContext.storageState(options);
Added in: v1.60apiRequestContext.tracing()
+Tracing recorder for requests made through this API request context.
+
**Usage**
```java
diff --git a/java/docs/api/class-browser.mdx b/java/docs/api/class-browser.mdx
index 416f0a4c84..e7b873a907 100644
--- a/java/docs/api/class-browser.mdx
+++ b/java/docs/api/class-browser.mdx
@@ -316,6 +316,9 @@ browser.close();
- `setPermissions` [List]<[String]> *(optional)*#
A list of permissions to grant to all pages in this context. See [BrowserContext.grantPermissions()](/api/class-browsercontext.mdx#browser-context-grant-permissions) for more details. Defaults to none.
+ - `setPierceFrames` [boolean] *(optional)*#
+
+ If set to true, all selectors in this context will pierce frames by default, as if every locator was created through [Page.pierceFrames()](/api/class-page.mdx#page-pierce-frames). Defaults to `false`.
- `setProxy` Proxy *(optional)*#
- `setServer` [String]
@@ -539,6 +542,9 @@ Browser.newPage(options);
- `setPermissions` [List]<[String]> *(optional)*#
A list of permissions to grant to all pages in this context. See [BrowserContext.grantPermissions()](/api/class-browsercontext.mdx#browser-context-grant-permissions) for more details. Defaults to none.
+ - `setPierceFrames` [boolean] *(optional)*#
+
+ If set to true, all selectors in this context will pierce frames by default, as if every locator was created through [Page.pierceFrames()](/api/class-page.mdx#page-pierce-frames). Defaults to `false`.
- `setProxy` Proxy *(optional)*#
- `setServer` [String]
diff --git a/java/docs/api/class-browsertype.mdx b/java/docs/api/class-browsertype.mdx
index 40ae0a2e0b..dd1a6f6d44 100644
--- a/java/docs/api/class-browsertype.mdx
+++ b/java/docs/api/class-browsertype.mdx
@@ -461,6 +461,9 @@ BrowserType.launchPersistentContext(userDataDir, options);
- `setPermissions` [List]<[String]> *(optional)*#
A list of permissions to grant to all pages in this context. See [BrowserContext.grantPermissions()](/api/class-browsercontext.mdx#browser-context-grant-permissions) for more details. Defaults to none.
+ - `setPierceFrames` [boolean] *(optional)*#
+
+ If set to true, all selectors in this context will pierce frames by default, as if every locator was created through [Page.pierceFrames()](/api/class-page.mdx#page-pierce-frames). Defaults to `false`.
- `setProxy` Proxy *(optional)*#
- `setServer` [String]
diff --git a/java/docs/api/class-frame.mdx b/java/docs/api/class-frame.mdx
index fb4d70d837..2bc00e1ab7 100644
--- a/java/docs/api/class-frame.mdx
+++ b/java/docs/api/class-frame.mdx
@@ -903,6 +903,12 @@ Locator locator = frame.pierceFrames().getByRole(AriaRole.BUTTON);
locator.click();
```
+**Arguments**
+- `options` `Frame.PierceFramesOptions` *(optional)*
+ - `setPierce` [boolean] *(optional)*#
+
+ Whether to pierce frames. Pass `false` to opt out of frame piercing enabled by the [setPierceFrames](/api/class-browser.mdx#browser-new-context-option-pierce-frames) context option. Defaults to `true`.
+
**Returns**
- [FrameLocator]#
diff --git a/java/docs/api/class-page.mdx b/java/docs/api/class-page.mdx
index 74c15fa5ac..3b963befb0 100644
--- a/java/docs/api/class-page.mdx
+++ b/java/docs/api/class-page.mdx
@@ -1701,6 +1701,12 @@ Locator locator = page.pierceFrames().getByRole(AriaRole.BUTTON);
locator.click();
```
+**Arguments**
+- `options` `Page.PierceFramesOptions` *(optional)*
+ - `setPierce` [boolean] *(optional)*#
+
+ Whether to pierce frames. Pass `false` to opt out of frame piercing enabled by the [setPierceFrames](/api/class-browser.mdx#browser-new-context-option-pierce-frames) context option. Defaults to `true`.
+
**Returns**
- [FrameLocator]#
diff --git a/java/docs/api/class-tracing.mdx b/java/docs/api/class-tracing.mdx
index 63ebc8d600..44806f6a99 100644
--- a/java/docs/api/class-tracing.mdx
+++ b/java/docs/api/class-tracing.mdx
@@ -197,7 +197,7 @@ context.tracing().stopChunk(new Tracing.StopChunkOptions()
Start recording a HAR (HTTP Archive) of network activity in this context. The HAR file is written to disk when [Tracing.stopHar()](/api/class-tracing.mdx#tracing-stop-har) is called, or when the returned [Disposable] is disposed.
-Only one HAR recording can be active at a time per [BrowserContext].
+Only one HAR recording can be active at a time per [Tracing] instance.
**Usage**
diff --git a/java/docs/browsers.mdx b/java/docs/browsers.mdx
index 5b214a230a..607f4baadd 100644
--- a/java/docs/browsers.mdx
+++ b/java/docs/browsers.mdx
@@ -56,7 +56,7 @@ See [system requirements](./intro.mdx#system-requirements) for officially suppor
## Configure Browsers
-Playwright can run tests on Chromium, WebKit and Firefox browsers as well as branded browsers such as Google Chrome and Microsoft Edge. It can also run on emulated tablet and mobile devices. See the [registry of device parameters](https://github.com/microsoft/playwright/blob/main/packages/playwright-core/src/server/deviceDescriptorsSource.json) for a complete list of selected desktop, tablet and mobile devices.
+Playwright can run tests on Chromium, WebKit and Firefox browsers as well as branded browsers such as Google Chrome and Microsoft Edge. It can also run on emulated tablet and mobile devices. See the [registry of device parameters](https://github.com/microsoft/playwright/blob/main/packages/isomorphic/deviceDescriptorsSource.json) for a complete list of selected desktop, tablet and mobile devices.
### Run tests on different browsers
diff --git a/java/docs/getting-started-cli.mdx b/java/docs/getting-started-cli.mdx
index 10bd768b9b..6f815e4d98 100644
--- a/java/docs/getting-started-cli.mdx
+++ b/java/docs/getting-started-cli.mdx
@@ -17,25 +17,30 @@ Playwright comes with `playwright-cli`, a command-line interface for browser aut
## Prerequisites
Before you begin, make sure you have the following installed:
-- [Node.js](https://nodejs.org/) 20 or newer
+- Playwright for your language, **or** [Node.js](https://nodejs.org/) 20+ for the standalone `@playwright/cli` package
- A coding agent: Claude Code, GitHub Copilot, or similar
## Installation
-Install `playwright-cli` globally:
+Install the standalone CLI globally (works with any language):
```bash
npm install -g @playwright/cli@latest
playwright-cli --help
```
-Alternatively, install `@playwright/cli` as a local dependency and use `npx`:
+Or use the CLI bundled with your Playwright install:
```bash
-npm install -D @playwright/cli@latest
-npx playwright-cli --help
+# JavaScript / TypeScript
+npx playwright cli --help
+
+# Python
+python -m playwright cli --help
```
+When using a bundled entry point, replace `playwright-cli` with `npx playwright cli` or `python -m playwright cli` in the commands below.
+
### Installing skills
Coding agents like Claude Code and GitHub Copilot can use locally installed skills for richer context about available commands:
@@ -44,6 +49,12 @@ Coding agents like Claude Code and GitHub Copilot can use locally installed skil
playwright-cli install --skills
```
+To share the skills across all your projects, add the `-g` flag to install them into your home directory (`~/.claude/skills` or, with `--skills=agents`, `~/.agents/skills`):
+
+```bash
+playwright-cli install --skills -g
+```
+
### Skills-less operation
You can also point your agent at the CLI directly and let it discover commands on its own:
@@ -103,7 +114,7 @@ playwright-cli check # check a checkbox or radio button
playwright-cli uncheck # uncheck a checkbox
playwright-cli hover # hover over element
playwright-cli drag # drag and drop between elements
-playwright-cli upload # upload files
+playwright-cli upload # upload one or multiple files
playwright-cli close # close the page
```
@@ -289,11 +300,29 @@ playwright-cli attach --extension
This requires the [Playwright Extension](https://github.com/microsoft/playwright/blob/main/packages/extension/README.md) to be installed.
+## Debugging tests
+
+Coding agents can pause a test at the start, attach with `playwright-cli`, and explore the live browser — useful for diagnosing and fixing failures.
+
+```bash
+# JavaScript / TypeScript
+PLAYWRIGHT_HTML_OPEN=never npx playwright test --debug=cli
+# → Debugging Instructions with session name, e.g. tw-abcdef
+playwright-cli attach tw-abcdef
+
+# Python (pytest-playwright; -s keeps the attach line visible)
+pytest --playwright-debug=cli -s
+playwright-cli attach tw-abcdef
+```
+
+Keep the test running in the background while you attach. The installed skill documents this workflow for agents.
+
## Quick Reference
| Action | Command |
| ------------------------- | --------------------------------------------------- |
| **Install CLI** | `npm install -g @playwright/cli@latest` |
+| **Use bundled CLI** | `npx playwright cli …` / `python -m playwright cli …` |
| **Install skills** | `playwright-cli install --skills` |
| **Open a page** | `playwright-cli open https://example.com` |
| **Click an element** | `playwright-cli click e15` |
@@ -303,6 +332,8 @@ This requires the [Playwright Extension](https://github.com/microsoft/playwright
| **Run headed** | `playwright-cli open https://example.com --headed` |
| **Use Firefox** | `playwright-cli open --browser=firefox` |
| **Monitor sessions** | `playwright-cli show` |
+| **Debug JS test** | `npx playwright test --debug=cli` |
+| **Debug Python test** | `pytest --playwright-debug=cli -s` |
## What's Next
- [Write tests using web-first assertions, page fixtures, and locators](./writing-tests.mdx)
diff --git a/java/docs/release-notes.mdx b/java/docs/release-notes.mdx
index e5339534eb..71a83af946 100644
--- a/java/docs/release-notes.mdx
+++ b/java/docs/release-notes.mdx
@@ -9,6 +9,36 @@ import HTMLCard from '@site/src/components/HTMLCard';
import LiteYouTube from '@site/src/components/LiteYouTube';
+## Version 1.62
+
+### 🖼️ WebP screenshots
+
+[Page.screenshot()](/api/class-page.mdx#page-screenshot) and [Locator.screenshot()](/api/class-locator.mdx#locator-screenshot) can now capture screenshots in the WebP format — Playwright infers the format from a `.webp` file extension, or you can set the `type` explicitly. Quality `100` (the default) is lossless, while lower values use lossy compression:
+
+```java
+page.screenshot(new Page.ScreenshotOptions()
+ .setPath(Paths.get("homepage.webp"))
+ .setQuality(50));
+```
+
+### New APIs
+- New `scroll` option (`"auto"` | `"none"`) on actions to opt out of Playwright's automatic scroll-into-view.
+- New [Locator.waitForFunction()](/api/class-locator.mdx#locator-wait-for-function) waits until a function — called with the matching element — returns a truthy value.
+- New [APIResponse.timing()](/api/class-apiresponse.mdx#api-response-timing) returns resource timing information for an API response.
+
+### Announcements
+* 📋 The clipboard is now isolated from the operating system in headless mode, so tests that use `navigator.clipboard` no longer read or overwrite the clipboard of the machine running them.
+* ⚠️ Debian 11 is not supported anymore.
+
+### Browser Versions
+- Chromium 151.0.7922.34
+- Mozilla Firefox 153.0
+- WebKit 26.5
+
+This version was also tested against the following stable channels:
+- Google Chrome 151
+- Microsoft Edge 151
+
## Version 1.61
### 🔑 WebAuthn passkeys
diff --git a/nodejs/docs/accessibility-testing.mdx b/nodejs/docs/accessibility-testing.mdx
index 3a1f39e910..dfad404b78 100644
--- a/nodejs/docs/accessibility-testing.mdx
+++ b/nodejs/docs/accessibility-testing.mdx
@@ -341,6 +341,7 @@ test('example using custom fixture', async ({ page, makeAxeBuilder }) => {
[BrowserContext]: /api/class-browsercontext.mdx "BrowserContext"
[BrowserServer]: /api/class-browserserver.mdx "BrowserServer"
[BrowserType]: /api/class-browsertype.mdx "BrowserType"
+[By]: /api/class-by.mdx "By"
[CDPSession]: /api/class-cdpsession.mdx "CDPSession"
[Clock]: /api/class-clock.mdx "Clock"
[ConsoleMessage]: /api/class-consolemessage.mdx "ConsoleMessage"
diff --git a/nodejs/docs/actionability.mdx b/nodejs/docs/actionability.mdx
index 900585a789..8a2b2fedea 100644
--- a/nodejs/docs/actionability.mdx
+++ b/nodejs/docs/actionability.mdx
@@ -131,6 +131,7 @@ For example, consider a scenario where Playwright will click `Sign Up` button re
[BrowserContext]: /api/class-browsercontext.mdx "BrowserContext"
[BrowserServer]: /api/class-browserserver.mdx "BrowserServer"
[BrowserType]: /api/class-browsertype.mdx "BrowserType"
+[By]: /api/class-by.mdx "By"
[CDPSession]: /api/class-cdpsession.mdx "CDPSession"
[Clock]: /api/class-clock.mdx "Clock"
[ConsoleMessage]: /api/class-consolemessage.mdx "ConsoleMessage"
diff --git a/nodejs/docs/api-testing.mdx b/nodejs/docs/api-testing.mdx
index f0938cc717..dbde55037e 100644
--- a/nodejs/docs/api-testing.mdx
+++ b/nodejs/docs/api-testing.mdx
@@ -382,6 +382,7 @@ test('global context request has isolated cookie storage', async ({
[BrowserContext]: /api/class-browsercontext.mdx "BrowserContext"
[BrowserServer]: /api/class-browserserver.mdx "BrowserServer"
[BrowserType]: /api/class-browsertype.mdx "BrowserType"
+[By]: /api/class-by.mdx "By"
[CDPSession]: /api/class-cdpsession.mdx "CDPSession"
[Clock]: /api/class-clock.mdx "Clock"
[ConsoleMessage]: /api/class-consolemessage.mdx "ConsoleMessage"
diff --git a/nodejs/docs/api/class-android.mdx b/nodejs/docs/api/class-android.mdx
index 116a20d5a3..cebb0b488c 100644
--- a/nodejs/docs/api/class-android.mdx
+++ b/nodejs/docs/api/class-android.mdx
@@ -252,6 +252,7 @@ android.setDefaultTimeout(timeout);
[BrowserContext]: /api/class-browsercontext.mdx "BrowserContext"
[BrowserServer]: /api/class-browserserver.mdx "BrowserServer"
[BrowserType]: /api/class-browsertype.mdx "BrowserType"
+[By]: /api/class-by.mdx "By"
[CDPSession]: /api/class-cdpsession.mdx "CDPSession"
[Clock]: /api/class-clock.mdx "Clock"
[ConsoleMessage]: /api/class-consolemessage.mdx "ConsoleMessage"
diff --git a/nodejs/docs/api/class-androiddevice.mdx b/nodejs/docs/api/class-androiddevice.mdx
index bb7f8adc5e..3e351d31f7 100644
--- a/nodejs/docs/api/class-androiddevice.mdx
+++ b/nodejs/docs/api/class-androiddevice.mdx
@@ -287,6 +287,9 @@ await androidDevice.launchBrowser(options);
- `permissions` [Array]<[string]> *(optional)*#
A list of permissions to grant to all pages in this context. See [browserContext.grantPermissions()](/api/class-browsercontext.mdx#browser-context-grant-permissions) for more details. Defaults to none.
+ - `pierceFrames` [boolean] *(optional)*#
+
+ If set to true, all selectors in this context will pierce frames by default, as if every locator was created through [page.pierceFrames()](/api/class-page.mdx#page-pierce-frames). Defaults to `false`.
- `pkg` [string] *(optional)*#
Optional package name to launch instead of default Chrome for Android.
@@ -947,6 +950,7 @@ androidDevice.on('webview', data => {});
[BrowserContext]: /api/class-browsercontext.mdx "BrowserContext"
[BrowserServer]: /api/class-browserserver.mdx "BrowserServer"
[BrowserType]: /api/class-browsertype.mdx "BrowserType"
+[By]: /api/class-by.mdx "By"
[CDPSession]: /api/class-cdpsession.mdx "CDPSession"
[Clock]: /api/class-clock.mdx "Clock"
[ConsoleMessage]: /api/class-consolemessage.mdx "ConsoleMessage"
diff --git a/nodejs/docs/api/class-androidinput.mdx b/nodejs/docs/api/class-androidinput.mdx
index a5fac605e5..cb50556da2 100644
--- a/nodejs/docs/api/class-androidinput.mdx
+++ b/nodejs/docs/api/class-androidinput.mdx
@@ -166,6 +166,7 @@ await androidInput.type(text);
[BrowserContext]: /api/class-browsercontext.mdx "BrowserContext"
[BrowserServer]: /api/class-browserserver.mdx "BrowserServer"
[BrowserType]: /api/class-browsertype.mdx "BrowserType"
+[By]: /api/class-by.mdx "By"
[CDPSession]: /api/class-cdpsession.mdx "CDPSession"
[Clock]: /api/class-clock.mdx "Clock"
[ConsoleMessage]: /api/class-consolemessage.mdx "ConsoleMessage"
diff --git a/nodejs/docs/api/class-androidsocket.mdx b/nodejs/docs/api/class-androidsocket.mdx
index dff843aa45..0d50a6c5f6 100644
--- a/nodejs/docs/api/class-androidsocket.mdx
+++ b/nodejs/docs/api/class-androidsocket.mdx
@@ -93,6 +93,7 @@ androidSocket.on('data', data => {});
[BrowserContext]: /api/class-browsercontext.mdx "BrowserContext"
[BrowserServer]: /api/class-browserserver.mdx "BrowserServer"
[BrowserType]: /api/class-browsertype.mdx "BrowserType"
+[By]: /api/class-by.mdx "By"
[CDPSession]: /api/class-cdpsession.mdx "CDPSession"
[Clock]: /api/class-clock.mdx "Clock"
[ConsoleMessage]: /api/class-consolemessage.mdx "ConsoleMessage"
diff --git a/nodejs/docs/api/class-androidwebview.mdx b/nodejs/docs/api/class-androidwebview.mdx
index 09b1237099..7041c048b1 100644
--- a/nodejs/docs/api/class-androidwebview.mdx
+++ b/nodejs/docs/api/class-androidwebview.mdx
@@ -88,6 +88,7 @@ androidWebView.on('close', data => {});
[BrowserContext]: /api/class-browsercontext.mdx "BrowserContext"
[BrowserServer]: /api/class-browserserver.mdx "BrowserServer"
[BrowserType]: /api/class-browsertype.mdx "BrowserType"
+[By]: /api/class-by.mdx "By"
[CDPSession]: /api/class-cdpsession.mdx "CDPSession"
[Clock]: /api/class-clock.mdx "Clock"
[ConsoleMessage]: /api/class-consolemessage.mdx "ConsoleMessage"
diff --git a/nodejs/docs/api/class-apirequest.mdx b/nodejs/docs/api/class-apirequest.mdx
index c56362531a..51c73ddfbe 100644
--- a/nodejs/docs/api/class-apirequest.mdx
+++ b/nodejs/docs/api/class-apirequest.mdx
@@ -178,6 +178,7 @@ await apiRequest.newContext(options);
[BrowserContext]: /api/class-browsercontext.mdx "BrowserContext"
[BrowserServer]: /api/class-browserserver.mdx "BrowserServer"
[BrowserType]: /api/class-browsertype.mdx "BrowserType"
+[By]: /api/class-by.mdx "By"
[CDPSession]: /api/class-cdpsession.mdx "CDPSession"
[Clock]: /api/class-clock.mdx "Clock"
[ConsoleMessage]: /api/class-consolemessage.mdx "ConsoleMessage"
diff --git a/nodejs/docs/api/class-apirequestcontext.mdx b/nodejs/docs/api/class-apirequestcontext.mdx
index 65e383683e..8049655d3c 100644
--- a/nodejs/docs/api/class-apirequestcontext.mdx
+++ b/nodejs/docs/api/class-apirequestcontext.mdx
@@ -656,6 +656,8 @@ await apiRequestContext.storageState(options);
Added in: v1.60apiRequestContext.tracing
+Tracing recorder for requests made through this API request context.
+
**Usage**
```js
@@ -674,6 +676,7 @@ apiRequestContext.tracing
[BrowserContext]: /api/class-browsercontext.mdx "BrowserContext"
[BrowserServer]: /api/class-browserserver.mdx "BrowserServer"
[BrowserType]: /api/class-browsertype.mdx "BrowserType"
+[By]: /api/class-by.mdx "By"
[CDPSession]: /api/class-cdpsession.mdx "CDPSession"
[Clock]: /api/class-clock.mdx "Clock"
[ConsoleMessage]: /api/class-consolemessage.mdx "ConsoleMessage"
diff --git a/nodejs/docs/api/class-apiresponse.mdx b/nodejs/docs/api/class-apiresponse.mdx
index 0378facd66..b041469b81 100644
--- a/nodejs/docs/api/class-apiresponse.mdx
+++ b/nodejs/docs/api/class-apiresponse.mdx
@@ -297,6 +297,7 @@ apiResponse.url();
[BrowserContext]: /api/class-browsercontext.mdx "BrowserContext"
[BrowserServer]: /api/class-browserserver.mdx "BrowserServer"
[BrowserType]: /api/class-browsertype.mdx "BrowserType"
+[By]: /api/class-by.mdx "By"
[CDPSession]: /api/class-cdpsession.mdx "CDPSession"
[Clock]: /api/class-clock.mdx "Clock"
[ConsoleMessage]: /api/class-consolemessage.mdx "ConsoleMessage"
diff --git a/nodejs/docs/api/class-apiresponseassertions.mdx b/nodejs/docs/api/class-apiresponseassertions.mdx
index 7a9f8ca9f1..1d13fb2b99 100644
--- a/nodejs/docs/api/class-apiresponseassertions.mdx
+++ b/nodejs/docs/api/class-apiresponseassertions.mdx
@@ -69,6 +69,7 @@ await expect(response).not.toBeOK();
[BrowserContext]: /api/class-browsercontext.mdx "BrowserContext"
[BrowserServer]: /api/class-browserserver.mdx "BrowserServer"
[BrowserType]: /api/class-browsertype.mdx "BrowserType"
+[By]: /api/class-by.mdx "By"
[CDPSession]: /api/class-cdpsession.mdx "CDPSession"
[Clock]: /api/class-clock.mdx "Clock"
[ConsoleMessage]: /api/class-consolemessage.mdx "ConsoleMessage"
diff --git a/nodejs/docs/api/class-browser.mdx b/nodejs/docs/api/class-browser.mdx
index 686ff72371..263cbaa239 100644
--- a/nodejs/docs/api/class-browser.mdx
+++ b/nodejs/docs/api/class-browser.mdx
@@ -325,6 +325,9 @@ If directly using this method to create [BrowserContext]s, it is best practice t
- `permissions` [Array]<[string]> *(optional)*#
A list of permissions to grant to all pages in this context. See [browserContext.grantPermissions()](/api/class-browsercontext.mdx#browser-context-grant-permissions) for more details. Defaults to none.
+ - `pierceFrames` [boolean] *(optional)*#
+
+ If set to true, all selectors in this context will pierce frames by default, as if every locator was created through [page.pierceFrames()](/api/class-page.mdx#page-pierce-frames). Defaults to `false`.
- `proxy` [Object] *(optional)*#
- `server` [string]
@@ -618,6 +621,9 @@ await browser.newPage(options);
- `permissions` [Array]<[string]> *(optional)*#
A list of permissions to grant to all pages in this context. See [browserContext.grantPermissions()](/api/class-browsercontext.mdx#browser-context-grant-permissions) for more details. Defaults to none.
+ - `pierceFrames` [boolean] *(optional)*#
+
+ If set to true, all selectors in this context will pierce frames by default, as if every locator was created through [page.pierceFrames()](/api/class-page.mdx#page-pierce-frames). Defaults to `false`.
- `proxy` [Object] *(optional)*#
- `server` [string]
@@ -940,6 +946,7 @@ browser.on('disconnected', data => {});
[BrowserContext]: /api/class-browsercontext.mdx "BrowserContext"
[BrowserServer]: /api/class-browserserver.mdx "BrowserServer"
[BrowserType]: /api/class-browsertype.mdx "BrowserType"
+[By]: /api/class-by.mdx "By"
[CDPSession]: /api/class-cdpsession.mdx "CDPSession"
[Clock]: /api/class-clock.mdx "Clock"
[ConsoleMessage]: /api/class-consolemessage.mdx "ConsoleMessage"
diff --git a/nodejs/docs/api/class-browsercontext.mdx b/nodejs/docs/api/class-browsercontext.mdx
index ff18e106ff..f7c28e01ad 100644
--- a/nodejs/docs/api/class-browsercontext.mdx
+++ b/nodejs/docs/api/class-browsercontext.mdx
@@ -1579,6 +1579,7 @@ await browserContext.setHTTPCredentials(httpCredentials);
[BrowserContext]: /api/class-browsercontext.mdx "BrowserContext"
[BrowserServer]: /api/class-browserserver.mdx "BrowserServer"
[BrowserType]: /api/class-browsertype.mdx "BrowserType"
+[By]: /api/class-by.mdx "By"
[CDPSession]: /api/class-cdpsession.mdx "CDPSession"
[Clock]: /api/class-clock.mdx "Clock"
[ConsoleMessage]: /api/class-consolemessage.mdx "ConsoleMessage"
diff --git a/nodejs/docs/api/class-browserserver.mdx b/nodejs/docs/api/class-browserserver.mdx
index e84cbf8b05..59ddeaf585 100644
--- a/nodejs/docs/api/class-browserserver.mdx
+++ b/nodejs/docs/api/class-browserserver.mdx
@@ -105,6 +105,7 @@ browserServer.on('close', data => {});
[BrowserContext]: /api/class-browsercontext.mdx "BrowserContext"
[BrowserServer]: /api/class-browserserver.mdx "BrowserServer"
[BrowserType]: /api/class-browsertype.mdx "BrowserType"
+[By]: /api/class-by.mdx "By"
[CDPSession]: /api/class-cdpsession.mdx "CDPSession"
[Clock]: /api/class-clock.mdx "Clock"
[ConsoleMessage]: /api/class-consolemessage.mdx "ConsoleMessage"
diff --git a/nodejs/docs/api/class-browsertype.mdx b/nodejs/docs/api/class-browsertype.mdx
index 5e0ff64663..d890b9f207 100644
--- a/nodejs/docs/api/class-browsertype.mdx
+++ b/nodejs/docs/api/class-browsertype.mdx
@@ -468,6 +468,9 @@ await browserType.launchPersistentContext(userDataDir, options);
- `permissions` [Array]<[string]> *(optional)*#
A list of permissions to grant to all pages in this context. See [browserContext.grantPermissions()](/api/class-browsercontext.mdx#browser-context-grant-permissions) for more details. Defaults to none.
+ - `pierceFrames` [boolean] *(optional)*#
+
+ If set to true, all selectors in this context will pierce frames by default, as if every locator was created through [page.pierceFrames()](/api/class-page.mdx#page-pierce-frames). Defaults to `false`.
- `proxy` [Object] *(optional)*#
- `server` [string]
@@ -732,6 +735,7 @@ browserType.name();
[BrowserContext]: /api/class-browsercontext.mdx "BrowserContext"
[BrowserServer]: /api/class-browserserver.mdx "BrowserServer"
[BrowserType]: /api/class-browsertype.mdx "BrowserType"
+[By]: /api/class-by.mdx "By"
[CDPSession]: /api/class-cdpsession.mdx "CDPSession"
[Clock]: /api/class-clock.mdx "Clock"
[ConsoleMessage]: /api/class-consolemessage.mdx "ConsoleMessage"
diff --git a/nodejs/docs/api/class-by.mdx b/nodejs/docs/api/class-by.mdx
new file mode 100644
index 0000000000..64adf1abc8
--- /dev/null
+++ b/nodejs/docs/api/class-by.mdx
@@ -0,0 +1,565 @@
+---
+id: class-by
+title: "By"
+---
+import Tabs from '@theme/Tabs';
+import TabItem from '@theme/TabItem';
+import HTMLCard from '@site/src/components/HTMLCard';
+
+
+[By] describes an element without being bound to a [Page] or a [Frame]. It is built with the top-level [playwright.by](/api/class-playwright.mdx#playwright-by) object and turned into a regular [Locator] with [page.get()](/api/class-page.mdx#page-get), [frame.get()](/api/class-frame.mdx#frame-get) or [locator.get()](/api/class-locator.mdx#locator-get).
+
+Since a [By] carries no page, it can be defined once at module scope and reused by every test, which makes it a natural fit for page objects.
+
+**Usage**
+
+```js
+import { by, expect, test } from '@playwright/test';
+
+const saveButton = by.role('button', { name: 'Save' });
+const todoItems = by.testId('todo-list').role('listitem');
+
+test('saves a todo', async ({ page }) => {
+ await page.get(saveButton).click();
+ await expect(page.get(todoItems)).toHaveCount(1);
+});
+```
+
+A [By] chain resolves to the same element as the matching [Locator] chain, so `page.get(by.testId('list').text('Row'))` and `page.getByTestId('list').getByText('Row')` are interchangeable. Chaining composes rather than replaces: `page.get(outer.get(inner))` and `page.get(outer).get(inner)` describe the same element.
+
+
+---
+
+## Methods
+
+### altText {/* #by-alt-text */}
+
+Added in: v1.63by.altText
+
+Matches a descendant element by its `alt` text.
+
+**Usage**
+
+```js
+by.altText(text);
+by.altText(text, options);
+```
+
+**Arguments**
+- `text` [string] | [RegExp] Added in: v1.27#
+
+ Text to locate the element for.
+- `options` [Object] *(optional)*
+ - `exact` [boolean] *(optional)* Added in: v1.27#
+
+ Whether to find an exact match: case-sensitive and whole-string. Default to false. Ignored when locating by a regular expression. Note that exact match still trims whitespace.
+
+**Returns**
+- [By]#
+
+---
+
+### and {/* #by-and */}
+
+Added in: v1.63by.and
+
+Narrows down the match to elements that match both this and the given [By].
+
+**Usage**
+
+```js
+const saveButton = by.role('button').and(by.title('Subscribe'));
+```
+
+**Arguments**
+- `by` [By]#
+
+ Additional locator to match.
+
+**Returns**
+- [By]#
+
+---
+
+### describe {/* #by-describe */}
+
+Added in: v1.63by.describe
+
+Describes the element, the description is used in the trace viewer and the reports.
+
+**Usage**
+
+```js
+by.describe(description);
+```
+
+**Arguments**
+- `description` [string]#
+
+ Locator description.
+
+**Returns**
+- [By]#
+
+---
+
+### filter {/* #by-filter */}
+
+Added in: v1.63by.filter
+
+Narrows down the match according to the options, for example filters by text. It can be chained to filter multiple times.
+
+**Usage**
+
+```js
+const rowWithButton = by.get('tr')
+ .filter({ hasText: 'text in column 1' })
+ .filter({ has: by.role('button', { name: 'column 2 button' }) });
+```
+
+**Arguments**
+- `options` [Object] *(optional)*
+ - `has` [By] *(optional)*#
+
+ Narrows down the results to those which contain elements matching this relative [By]. The inner [By] is queried starting with the outer match, not the document root.
+ - `hasNot` [By] *(optional)*#
+
+ Matches elements that do not contain an element matching this relative [By]. The inner [By] is queried starting with the outer match, not the document root.
+ - `hasNotText` [string] | [RegExp] *(optional)*#
+
+ Matches elements that do not contain specified text somewhere inside, possibly in a child or a descendant element. When passed a [string], matching is case-insensitive and searches for a substring.
+ - `hasText` [string] | [RegExp] *(optional)*#
+
+ Matches elements containing specified text somewhere inside, possibly in a child or a descendant element. When passed a [string], matching is case-insensitive and searches for a substring. For example, `"Playwright"` matches `
Playwright
`.
+ - `visible` [boolean] *(optional)*#
+
+ Only matches visible or invisible elements.
+
+**Returns**
+- [By]#
+
+---
+
+### first {/* #by-first */}
+
+Added in: v1.63by.first
+
+Matches the first matching element.
+
+**Usage**
+
+```js
+by.first();
+```
+
+**Returns**
+- [By]#
+
+---
+
+### get {/* #by-get */}
+
+Added in: v1.63by.get
+
+Matches a descendant element by a selector or by another [By].
+
+**Usage**
+
+```js
+const firstCell = by.get('table').get('td').first();
+
+const listItem = by.role('listitem');
+const unread = by.testId('inbox').get(listItem).filter({ hasText: 'Unread' });
+```
+
+**Arguments**
+- `selectorOrBy` [string] | [By]#
+
+ A selector or a [By] to match inside this one.
+
+**Returns**
+- [By]#
+
+**Details**
+
+Passing a [By] composes rather than replaces, so `outer.get(inner.get(innermost))` and `outer.get(inner).get(innermost)` describe the same element.
+
+---
+
+### label {/* #by-label */}
+
+Added in: v1.63by.label
+
+Matches an input element by the text of the associated `