From 8348707ae5a9c1678663e9664905a6d58676bbed Mon Sep 17 00:00:00 2001
From: "microsoft-playwright-automation[bot]"
<203992400+microsoft-playwright-automation[bot]@users.noreply.github.com>
Date: Mon, 8 Jun 2026 14:00:24 +0000
Subject: [PATCH] feat(roll): roll to 1.60 Playwright
---
.../api/class-browsercontext.mdx | 4 +-
.../api/class-elementhandle.mdx | 2 +-
.../version-stable/api/class-frame.mdx | 6 +-
.../version-stable/api/class-framelocator.mdx | 6 +-
.../version-stable/api/class-locator.mdx | 2 +-
.../version-stable/api/class-page.mdx | 6 +-
dotnet/versioned_docs/version-stable/ci.mdx | 10 +--
.../versioned_docs/version-stable/docker.mdx | 16 ++---
.../version-stable/release-notes.mdx | 71 +++++++++++++++++++
.../version-stable/webview2.mdx | 2 +
.../api/class-browsercontext.mdx | 4 +-
.../api/class-elementhandle.mdx | 2 +-
.../version-stable/api/class-frame.mdx | 4 +-
.../version-stable/api/class-framelocator.mdx | 6 +-
.../version-stable/api/class-locator.mdx | 2 +-
.../version-stable/api/class-page.mdx | 4 +-
java/versioned_docs/version-stable/ci.mdx | 12 ++--
java/versioned_docs/version-stable/docker.mdx | 16 ++---
java/versioned_docs/version-stable/intro.mdx | 2 +-
.../version-stable/release-notes.mdx | 64 +++++++++++++++++
.../version-stable/test-runners.mdx | 4 +-
.../version-stable/webview2.mdx | 2 +
.../api/class-browsercontext.mdx | 6 +-
.../api/class-elementhandle.mdx | 2 +-
.../version-stable/api/class-frame.mdx | 4 +-
.../version-stable/api/class-framelocator.mdx | 6 +-
.../version-stable/api/class-locator.mdx | 2 +-
.../version-stable/api/class-page.mdx | 4 +-
.../version-stable/webview2.mdx | 2 +
.../api/class-browsercontext.mdx | 4 +-
.../api/class-elementhandle.mdx | 2 +-
.../version-stable/api/class-frame.mdx | 4 +-
.../version-stable/api/class-framelocator.mdx | 6 +-
.../version-stable/api/class-locator.mdx | 2 +-
.../version-stable/api/class-page.mdx | 4 +-
python/versioned_docs/version-stable/ci.mdx | 12 ++--
.../versioned_docs/version-stable/docker.mdx | 18 ++---
.../version-stable/release-notes.mdx | 68 ++++++++++++++++++
.../version-stable/webview2.mdx | 2 +
39 files changed, 303 insertions(+), 92 deletions(-)
diff --git a/dotnet/versioned_docs/version-stable/api/class-browsercontext.mdx b/dotnet/versioned_docs/version-stable/api/class-browsercontext.mdx
index d56264ac7d..84044b8fff 100644
--- a/dotnet/versioned_docs/version-stable/api/class-browsercontext.mdx
+++ b/dotnet/versioned_docs/version-stable/api/class-browsercontext.mdx
@@ -1369,7 +1369,7 @@ BrowserContext.WebError += async (_, webError) => {};
Added in: v1.11browserContext.event BackgroundPage
-:::warning Deprecated
+:::warning[Deprecated]
Background pages have been removed from Chromium together with Manifest V2 extensions.
@@ -1393,7 +1393,7 @@ BrowserContext.BackgroundPage += async (_, page) => {};
Added in: v1.11browserContext.BackgroundPages
-:::warning Deprecated
+:::warning[Deprecated]
Background pages have been removed from Chromium together with Manifest V2 extensions.
diff --git a/dotnet/versioned_docs/version-stable/api/class-elementhandle.mdx b/dotnet/versioned_docs/version-stable/api/class-elementhandle.mdx
index f6a0f0556f..61efe9032f 100644
--- a/dotnet/versioned_docs/version-stable/api/class-elementhandle.mdx
+++ b/dotnet/versioned_docs/version-stable/api/class-elementhandle.mdx
@@ -1428,7 +1428,7 @@ await ElementHandle.TextContentAsync();
Added before v1.9elementHandle.TypeAsync
-:::warning Deprecated
+:::warning[Deprecated]
In most cases, you should use [Locator.FillAsync()](/api/class-locator.mdx#locator-fill) instead. You only need to press keys one by one if there is special keyboard handling on the page - in this case use [Locator.PressSequentiallyAsync()](/api/class-locator.mdx#locator-press-sequentially).
diff --git a/dotnet/versioned_docs/version-stable/api/class-frame.mdx b/dotnet/versioned_docs/version-stable/api/class-frame.mdx
index 58ea1bbb20..305e25b19c 100644
--- a/dotnet/versioned_docs/version-stable/api/class-frame.mdx
+++ b/dotnet/versioned_docs/version-stable/api/class-frame.mdx
@@ -2075,7 +2075,7 @@ await Frame.QuerySelectorAllAsync(selector);
Added before v1.9frame.RunAndWaitForNavigationAsync
-:::warning Deprecated
+:::warning[Deprecated]
This method is inherently racy, please use [Frame.WaitForURLAsync()](/api/class-frame.mdx#frame-wait-for-url) instead.
@@ -2130,7 +2130,7 @@ Usage of the [History API](https://developer.mozilla.org/en-US/docs/Web/API/Hist
Added before v1.9frame.WaitForNavigationAsync
-:::warning Deprecated
+:::warning[Deprecated]
This method is inherently racy, please use [Frame.WaitForURLAsync()](/api/class-frame.mdx#frame-wait-for-url) instead.
@@ -2486,7 +2486,7 @@ await Frame.TextContentAsync(selector, options);
Added before v1.9frame.TypeAsync
-:::warning Deprecated
+:::warning[Deprecated]
In most cases, you should use [Locator.FillAsync()](/api/class-locator.mdx#locator-fill) instead. You only need to press keys one by one if there is special keyboard handling on the page - in this case use [Locator.PressSequentiallyAsync()](/api/class-locator.mdx#locator-press-sequentially).
diff --git a/dotnet/versioned_docs/version-stable/api/class-framelocator.mdx b/dotnet/versioned_docs/version-stable/api/class-framelocator.mdx
index 1bba95c691..df81b42249 100644
--- a/dotnet/versioned_docs/version-stable/api/class-framelocator.mdx
+++ b/dotnet/versioned_docs/version-stable/api/class-framelocator.mdx
@@ -467,7 +467,7 @@ await Expect(locator).ToBeVisibleAsync();
Added in: v1.17frameLocator.First
-:::warning Deprecated
+:::warning[Deprecated]
Use [Locator.First](/api/class-locator.mdx#locator-first) followed by [Locator.ContentFrame](/api/class-locator.mdx#locator-content-frame) instead.
@@ -491,7 +491,7 @@ FrameLocator.First
Added in: v1.17frameLocator.Last
-:::warning Deprecated
+:::warning[Deprecated]
Use [Locator.Last](/api/class-locator.mdx#locator-last) followed by [Locator.ContentFrame](/api/class-locator.mdx#locator-content-frame) instead.
@@ -515,7 +515,7 @@ FrameLocator.Last
Added in: v1.17frameLocator.Nth
-:::warning Deprecated
+:::warning[Deprecated]
Use [Locator.Nth()](/api/class-locator.mdx#locator-nth) followed by [Locator.ContentFrame](/api/class-locator.mdx#locator-content-frame) instead.
diff --git a/dotnet/versioned_docs/version-stable/api/class-locator.mdx b/dotnet/versioned_docs/version-stable/api/class-locator.mdx
index 8c6705e831..b756064f03 100644
--- a/dotnet/versioned_docs/version-stable/api/class-locator.mdx
+++ b/dotnet/versioned_docs/version-stable/api/class-locator.mdx
@@ -2580,7 +2580,7 @@ await Locator.ElementHandlesAsync();
Added in: v1.14locator.TypeAsync
-:::warning Deprecated
+:::warning[Deprecated]
In most cases, you should use [Locator.FillAsync()](/api/class-locator.mdx#locator-fill) instead. You only need to press keys one by one if there is special keyboard handling on the page - in this case use [Locator.PressSequentiallyAsync()](/api/class-locator.mdx#locator-press-sequentially).
diff --git a/dotnet/versioned_docs/version-stable/api/class-page.mdx b/dotnet/versioned_docs/version-stable/api/class-page.mdx
index f90eb2b858..435044f70d 100644
--- a/dotnet/versioned_docs/version-stable/api/class-page.mdx
+++ b/dotnet/versioned_docs/version-stable/api/class-page.mdx
@@ -4413,7 +4413,7 @@ await Page.QuerySelectorAllAsync(selector);
Added before v1.9page.RunAndWaitForNavigationAsync
-:::warning Deprecated
+:::warning[Deprecated]
This method is inherently racy, please use [Page.WaitForURLAsync()](/api/class-page.mdx#page-wait-for-url) instead.
@@ -4468,7 +4468,7 @@ Usage of the [History API](https://developer.mozilla.org/en-US/docs/Web/API/Hist
Added before v1.9page.WaitForNavigationAsync
-:::warning Deprecated
+:::warning[Deprecated]
This method is inherently racy, please use [Page.WaitForURLAsync()](/api/class-page.mdx#page-wait-for-url) instead.
@@ -4824,7 +4824,7 @@ await Page.TextContentAsync(selector, options);
Added before v1.9page.TypeAsync
-:::warning Deprecated
+:::warning[Deprecated]
In most cases, you should use [Locator.FillAsync()](/api/class-locator.mdx#locator-fill) instead. You only need to press keys one by one if there is special keyboard handling on the page - in this case use [Locator.PressSequentiallyAsync()](/api/class-locator.mdx#locator-press-sequentially).
diff --git a/dotnet/versioned_docs/version-stable/ci.mdx b/dotnet/versioned_docs/version-stable/ci.mdx
index 60c1b37cc0..229bb5fd75 100644
--- a/dotnet/versioned_docs/version-stable/ci.mdx
+++ b/dotnet/versioned_docs/version-stable/ci.mdx
@@ -76,7 +76,7 @@ jobs:
name: 'Playwright Tests'
runs-on: ubuntu-latest
container:
- image: mcr.microsoft.com/playwright/dotnet:v1.59.0-noble
+ image: mcr.microsoft.com/playwright/dotnet:v1.60.0-noble
options: --user 1001
steps:
- uses: actions/checkout@v5
@@ -159,7 +159,7 @@ trigger:
pool:
vmImage: ubuntu-latest
-container: mcr.microsoft.com/playwright/dotnet:v1.59.0-noble
+container: mcr.microsoft.com/playwright/dotnet:v1.60.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.59.0-noble
+ - image: mcr.microsoft.com/playwright/dotnet:v1.60.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.59.0-noble' } }
+ agent { docker { image 'mcr.microsoft.com/playwright/dotnet:v1.60.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.59.0-noble
+image: mcr.microsoft.com/playwright/dotnet:v1.60.0-noble
```
### GitLab CI
diff --git a/dotnet/versioned_docs/version-stable/docker.mdx b/dotnet/versioned_docs/version-stable/docker.mdx
index f987fb51a0..62a5b4b450 100644
--- a/dotnet/versioned_docs/version-stable/docker.mdx
+++ b/dotnet/versioned_docs/version-stable/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.59.0-noble
+docker pull mcr.microsoft.com/playwright/dotnet:v1.60.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.59.0-noble /bin/bash
+docker run -it --rm --ipc=host mcr.microsoft.com/playwright/dotnet:v1.60.0-noble /bin/bash
```
#### Crawling and scraping
@@ -42,7 +42,7 @@ docker run -it --rm --ipc=host mcr.microsoft.com/playwright/dotnet:v1.59.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.59.0-noble /bin/bash
+docker run -it --rm --ipc=host --user pwuser --security-opt seccomp=seccomp_profile.json mcr.microsoft.com/playwright/dotnet:v1.60.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.59.0-noble /bin/sh -c "npx -y playwright@1.59.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.60.0-noble /bin/sh -c "npx -y playwright@1.60.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.59.0-noble /bin/sh -c "npx -y playwright@1.59.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.60.0-noble /bin/sh -c "npx -y playwright@1.60.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,9 +132,9 @@ 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.59.0` - Playwright v1.59.0 release docker image based on Ubuntu 24.04 LTS (Noble Numbat).
-- `:v1.59.0-noble` - Playwright v1.59.0 release docker image based on Ubuntu 24.04 LTS (Noble Numbat).
-- `:v1.59.0-jammy` - Playwright v1.59.0 release docker image based on Ubuntu 22.04 LTS (Jammy Jellyfish).
+- `:v1.60.0` - Playwright v1.60.0 release docker image based on Ubuntu 24.04 LTS (Noble Numbat).
+- `:v1.60.0-noble` - Playwright v1.60.0 release docker image based on Ubuntu 24.04 LTS (Noble Numbat).
+- `:v1.60.0-jammy` - Playwright v1.60.0 release docker image based on Ubuntu 22.04 LTS (Jammy Jellyfish).
:::note
diff --git a/dotnet/versioned_docs/version-stable/release-notes.mdx b/dotnet/versioned_docs/version-stable/release-notes.mdx
index a06395c519..b04da66bed 100644
--- a/dotnet/versioned_docs/version-stable/release-notes.mdx
+++ b/dotnet/versioned_docs/version-stable/release-notes.mdx
@@ -9,6 +9,77 @@ import HTMLCard from '@site/src/components/HTMLCard';
import LiteYouTube from '@site/src/components/LiteYouTube';
+## Version 1.60
+
+### 🌐 HAR recording on Tracing
+
+[Tracing.StartHarAsync()](/api/class-tracing.mdx#tracing-start-har) / [Tracing.StopHarAsync()](/api/class-tracing.mdx#tracing-stop-har) expose HAR recording as a first-class tracing API, with the same `Content`, `Mode` and `UrlFilter` options as `RecordHar`:
+
+```csharp
+await context.Tracing.StartHarAsync("trace.har");
+var page = await context.NewPageAsync();
+await page.GotoAsync("https://playwright.dev");
+await context.Tracing.StopHarAsync();
+```
+
+### 🪝 Drop API
+
+New [Locator.DropAsync()](/api/class-locator.mdx#locator-drop) simulates an external drag-and-drop of files or clipboard-like data onto an element. Playwright dispatches `dragenter`, `dragover`, and `drop` with a synthetic [DataTransfer] in the page context — works cross-browser and is great for testing upload zones:
+
+```csharp
+await page.Locator("#dropzone").DropAsync(new() {
+ Files = new FilePayload() {
+ Name = "note.txt",
+ MimeType = "text/plain",
+ Buffer = Encoding.UTF8.GetBytes("hello"),
+ },
+});
+
+await page.Locator("#dropzone").DropAsync(new() {
+ Data = new Dictionary {
+ ["text/plain"] = "hello world",
+ ["text/uri-list"] = "https://example.com",
+ },
+});
+```
+
+### 🎯 Aria snapshots
+- [Expect(Page).ToMatchAriaSnapshotAsync()](/api/class-pageassertions.mdx#page-assertions-to-match-aria-snapshot) now works on a [Page], in addition to a [Locator] — equivalent to asserting against `Page.Locator("body")`.
+- New `Boxes` option on [Locator.AriaSnapshotAsync()](/api/class-locator.mdx#locator-aria-snapshot) / [Page.AriaSnapshotAsync()](/api/class-page.mdx#page-aria-snapshot) appends each element's bounding box as `[box=x,y,width,height]`, useful for AI consumption.
+
+### New APIs
+
+#### Browser, Context and Page
+- Event [Browser.Context](/api/class-browser.mdx#browser-event-context) — fired when a new context is created on the browser.
+- [BrowserContext] now mirrors lifecycle events from its pages: [BrowserContext.Download](/api/class-browsercontext.mdx#browser-context-event-download), [BrowserContext.FrameAttached](/api/class-browsercontext.mdx#browser-context-event-frame-attached), [BrowserContext.FrameDetached](/api/class-browsercontext.mdx#browser-context-event-frame-detached), [BrowserContext.FrameNavigated](/api/class-browsercontext.mdx#browser-context-event-frame-navigated), [BrowserContext.PageClose](/api/class-browsercontext.mdx#browser-context-event-page-close), [BrowserContext.PageLoad](/api/class-browsercontext.mdx#browser-context-event-page-load).
+
+#### Locators and Assertions
+- New option `Description` in [Page.GetByRole()](/api/class-page.mdx#page-get-by-role) / [Locator.GetByRole()](/api/class-locator.mdx#locator-get-by-role) / [Frame.GetByRole()](/api/class-frame.mdx#frame-get-by-role) / [FrameLocator.GetByRole()](/api/class-framelocator.mdx#frame-locator-get-by-role) for matching the [accessible description](https://www.w3.org/TR/wai-aria-1.2/#dfn-accessible-description).
+- New option `Pseudo` in [Expect(Locator).ToHaveCSSAsync()](/api/class-locatorassertions.mdx#locator-assertions-to-have-css) reads computed styles from `::before` or `::after`.
+- New option `Style` in [Locator.HighlightAsync()](/api/class-locator.mdx#locator-highlight) applies extra inline CSS to the highlight overlay, plus new [Page.HideHighlightAsync()](/api/class-page.mdx#page-hide-highlight) to clear all highlights.
+
+#### Network
+- [WebSocketRoute.Protocols](/api/class-websocketroute.mdx#web-socket-route-protocols) returns the WebSocket subprotocols requested by the page.
+- New option `NoDefaults` in [BrowserType.ConnectOverCDPAsync()](/api/class-browsertype.mdx#browser-type-connect-over-cdp) disables Playwright's default overrides on the default context (download behavior, focus emulation, media emulation), so attaching to a user's daily-driver browser doesn't disturb its state.
+
+#### Errors
+- New [WebError.Location](/api/class-weberror.mdx#web-error-location) mirrors [ConsoleMessage.Location](/api/class-consolemessage.mdx#console-message-location).
+
+### 🛠️ Other improvements
+- Trace Viewer adds a pretty-print toggle for JSON / form request and response bodies in the network details panel.
+
+### Breaking Changes ⚠️
+- Removed long-deprecated `Handle` option on `BrowserContext.ExposeBindingAsync` and `Page.ExposeBindingAsync`.
+
+### Browser Versions
+- Chromium 148.0.7778.96
+- Mozilla Firefox 150.0.2
+- WebKit 26.4
+
+This version was also tested against the following stable channels:
+- Google Chrome 147
+- Microsoft Edge 147
+
## Version 1.59
### 🎬 Screencast
diff --git a/dotnet/versioned_docs/version-stable/webview2.mdx b/dotnet/versioned_docs/version-stable/webview2.mdx
index 5162f7f66c..d0465e3577 100644
--- a/dotnet/versioned_docs/version-stable/webview2.mdx
+++ b/dotnet/versioned_docs/version-stable/webview2.mdx
@@ -47,6 +47,8 @@ By default, the WebView2 control will use the same user data directory for all i
Using the following, Playwright will run your WebView2 application as a sub-process, assign a unique user data directory to it and provide the [Page] instance to your test:
+
+
```csharp
// WebView2Test.cs
using System.Diagnostics;
diff --git a/java/versioned_docs/version-stable/api/class-browsercontext.mdx b/java/versioned_docs/version-stable/api/class-browsercontext.mdx
index 11eeabd64e..0ea7ebed00 100644
--- a/java/versioned_docs/version-stable/api/class-browsercontext.mdx
+++ b/java/versioned_docs/version-stable/api/class-browsercontext.mdx
@@ -1351,7 +1351,7 @@ BrowserContext.onWebError(handler)
Added in: v1.11browserContext.onBackgroundPage(handler)
-:::warning Deprecated
+:::warning[Deprecated]
Background pages have been removed from Chromium together with Manifest V2 extensions.
@@ -1375,7 +1375,7 @@ BrowserContext.onBackgroundPage(handler)
Added in: v1.11browserContext.backgroundPages
-:::warning Deprecated
+:::warning[Deprecated]
Background pages have been removed from Chromium together with Manifest V2 extensions.
diff --git a/java/versioned_docs/version-stable/api/class-elementhandle.mdx b/java/versioned_docs/version-stable/api/class-elementhandle.mdx
index 10c38fd538..af90b5e653 100644
--- a/java/versioned_docs/version-stable/api/class-elementhandle.mdx
+++ b/java/versioned_docs/version-stable/api/class-elementhandle.mdx
@@ -1437,7 +1437,7 @@ ElementHandle.textContent();
Added before v1.9elementHandle.type
-:::warning Deprecated
+:::warning[Deprecated]
In most cases, you should use [Locator.fill()](/api/class-locator.mdx#locator-fill) instead. You only need to press keys one by one if there is special keyboard handling on the page - in this case use [Locator.pressSequentially()](/api/class-locator.mdx#locator-press-sequentially).
diff --git a/java/versioned_docs/version-stable/api/class-frame.mdx b/java/versioned_docs/version-stable/api/class-frame.mdx
index 3fc7092a09..2f5ec642bd 100644
--- a/java/versioned_docs/version-stable/api/class-frame.mdx
+++ b/java/versioned_docs/version-stable/api/class-frame.mdx
@@ -2406,7 +2406,7 @@ Frame.textContent(selector, options);
Added before v1.9frame.type
-:::warning Deprecated
+:::warning[Deprecated]
In most cases, you should use [Locator.fill()](/api/class-locator.mdx#locator-fill) instead. You only need to press keys one by one if there is special keyboard handling on the page - in this case use [Locator.pressSequentially()](/api/class-locator.mdx#locator-press-sequentially).
@@ -2521,7 +2521,7 @@ Frame.uncheck(selector, options);
Added before v1.9frame.waitForNavigation
-:::warning Deprecated
+:::warning[Deprecated]
This method is inherently racy, please use [Frame.waitForURL()](/api/class-frame.mdx#frame-wait-for-url) instead.
diff --git a/java/versioned_docs/version-stable/api/class-framelocator.mdx b/java/versioned_docs/version-stable/api/class-framelocator.mdx
index 0f5c5b3829..91c43ac526 100644
--- a/java/versioned_docs/version-stable/api/class-framelocator.mdx
+++ b/java/versioned_docs/version-stable/api/class-framelocator.mdx
@@ -466,7 +466,7 @@ assertThat(locator).isVisible();
Added in: v1.17frameLocator.first
-:::warning Deprecated
+:::warning[Deprecated]
Use [Locator.first()](/api/class-locator.mdx#locator-first) followed by [Locator.contentFrame()](/api/class-locator.mdx#locator-content-frame) instead.
@@ -490,7 +490,7 @@ FrameLocator.first();
Added in: v1.17frameLocator.last
-:::warning Deprecated
+:::warning[Deprecated]
Use [Locator.last()](/api/class-locator.mdx#locator-last) followed by [Locator.contentFrame()](/api/class-locator.mdx#locator-content-frame) instead.
@@ -514,7 +514,7 @@ FrameLocator.last();
Added in: v1.17frameLocator.nth
-:::warning Deprecated
+:::warning[Deprecated]
Use [Locator.nth()](/api/class-locator.mdx#locator-nth) followed by [Locator.contentFrame()](/api/class-locator.mdx#locator-content-frame) instead.
diff --git a/java/versioned_docs/version-stable/api/class-locator.mdx b/java/versioned_docs/version-stable/api/class-locator.mdx
index 72802866a9..07142f105b 100644
--- a/java/versioned_docs/version-stable/api/class-locator.mdx
+++ b/java/versioned_docs/version-stable/api/class-locator.mdx
@@ -2584,7 +2584,7 @@ Locator.elementHandles();
Added in: v1.14locator.type
-:::warning Deprecated
+:::warning[Deprecated]
In most cases, you should use [Locator.fill()](/api/class-locator.mdx#locator-fill) instead. You only need to press keys one by one if there is special keyboard handling on the page - in this case use [Locator.pressSequentially()](/api/class-locator.mdx#locator-press-sequentially).
diff --git a/java/versioned_docs/version-stable/api/class-page.mdx b/java/versioned_docs/version-stable/api/class-page.mdx
index e280c537f7..72b234bc1b 100644
--- a/java/versioned_docs/version-stable/api/class-page.mdx
+++ b/java/versioned_docs/version-stable/api/class-page.mdx
@@ -4608,7 +4608,7 @@ Page.textContent(selector, options);
Added before v1.9page.type
-:::warning Deprecated
+:::warning[Deprecated]
In most cases, you should use [Locator.fill()](/api/class-locator.mdx#locator-fill) instead. You only need to press keys one by one if there is special keyboard handling on the page - in this case use [Locator.pressSequentially()](/api/class-locator.mdx#locator-press-sequentially).
@@ -4723,7 +4723,7 @@ Page.uncheck(selector, options);
Added before v1.9page.waitForNavigation
-:::warning Deprecated
+:::warning[Deprecated]
This method is inherently racy, please use [Page.waitForURL()](/api/class-page.mdx#page-wait-for-url) instead.
diff --git a/java/versioned_docs/version-stable/ci.mdx b/java/versioned_docs/version-stable/ci.mdx
index ba5f47aa02..526e586e4b 100644
--- a/java/versioned_docs/version-stable/ci.mdx
+++ b/java/versioned_docs/version-stable/ci.mdx
@@ -75,7 +75,7 @@ jobs:
name: 'Playwright Tests'
runs-on: ubuntu-latest
container:
- image: mcr.microsoft.com/playwright/java:v1.59.0-noble
+ image: mcr.microsoft.com/playwright/java:v1.60.0-noble
options: --user 1001
steps:
- uses: actions/checkout@v5
@@ -160,7 +160,7 @@ trigger:
pool:
vmImage: ubuntu-latest
-container: mcr.microsoft.com/playwright/java:v1.59.0-noble
+container: mcr.microsoft.com/playwright/java:v1.60.0-noble
steps:
- task: JavaToolInstaller@1
@@ -183,7 +183,7 @@ Running Playwright on CircleCI is very similar to running on GitHub Actions. In
executors:
pw-noble-development:
docker:
- - image: mcr.microsoft.com/playwright/java:v1.59.0-noble
+ - image: mcr.microsoft.com/playwright/java:v1.60.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.
@@ -194,7 +194,7 @@ Jenkins supports Docker agents for pipelines. Use the [Playwright Docker image](
```groovy
pipeline {
- agent { docker { image 'mcr.microsoft.com/playwright/java:v1.59.0-noble' } }
+ agent { docker { image 'mcr.microsoft.com/playwright/java:v1.60.0-noble' } }
stages {
stage('e2e-tests') {
steps {
@@ -211,7 +211,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/java:v1.59.0-noble
+image: mcr.microsoft.com/playwright/java:v1.60.0-noble
```
### GitLab CI
@@ -224,7 +224,7 @@ stages:
tests:
stage: test
- image: mcr.microsoft.com/playwright/java:v1.59.0-noble
+ image: mcr.microsoft.com/playwright/java:v1.60.0-noble
script:
...
```
diff --git a/java/versioned_docs/version-stable/docker.mdx b/java/versioned_docs/version-stable/docker.mdx
index 7d2149cd3d..f1cbae2132 100644
--- a/java/versioned_docs/version-stable/docker.mdx
+++ b/java/versioned_docs/version-stable/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/java:v1.59.0-noble
+docker pull mcr.microsoft.com/playwright/java:v1.60.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/java:v1.59.0-noble /bin/bash
+docker run -it --rm --ipc=host mcr.microsoft.com/playwright/java:v1.60.0-noble /bin/bash
```
#### Crawling and scraping
@@ -42,7 +42,7 @@ docker run -it --rm --ipc=host mcr.microsoft.com/playwright/java:v1.59.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/java:v1.59.0-noble /bin/bash
+docker run -it --rm --ipc=host --user pwuser --security-opt seccomp=seccomp_profile.json mcr.microsoft.com/playwright/java:v1.60.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.59.0-noble /bin/sh -c "npx -y playwright@1.59.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.60.0-noble /bin/sh -c "npx -y playwright@1.60.0 run-server --port 3000 --host 0.0.0.0"
```
#### Connecting to the Server
@@ -107,7 +107,7 @@ public class App {
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.59.0-noble /bin/sh -c "npx -y playwright@1.59.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.60.0-noble /bin/sh -c "npx -y playwright@1.60.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.
@@ -140,9 +140,9 @@ 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.59.0` - Playwright v1.59.0 release docker image based on Ubuntu 24.04 LTS (Noble Numbat).
-- `:v1.59.0-noble` - Playwright v1.59.0 release docker image based on Ubuntu 24.04 LTS (Noble Numbat).
-- `:v1.59.0-jammy` - Playwright v1.59.0 release docker image based on Ubuntu 22.04 LTS (Jammy Jellyfish).
+- `:v1.60.0` - Playwright v1.60.0 release docker image based on Ubuntu 24.04 LTS (Noble Numbat).
+- `:v1.60.0-noble` - Playwright v1.60.0 release docker image based on Ubuntu 24.04 LTS (Noble Numbat).
+- `:v1.60.0-jammy` - Playwright v1.60.0 release docker image based on Ubuntu 22.04 LTS (Jammy Jellyfish).
:::note
diff --git a/java/versioned_docs/version-stable/intro.mdx b/java/versioned_docs/version-stable/intro.mdx
index 4891ca3823..cf90660e10 100644
--- a/java/versioned_docs/version-stable/intro.mdx
+++ b/java/versioned_docs/version-stable/intro.mdx
@@ -58,7 +58,7 @@ public class App {
com.microsoft.playwright
playwright
- 1.59.0
+ 1.60.0
diff --git a/java/versioned_docs/version-stable/release-notes.mdx b/java/versioned_docs/version-stable/release-notes.mdx
index 550e017cef..621ecd4c15 100644
--- a/java/versioned_docs/version-stable/release-notes.mdx
+++ b/java/versioned_docs/version-stable/release-notes.mdx
@@ -9,6 +9,70 @@ import HTMLCard from '@site/src/components/HTMLCard';
import LiteYouTube from '@site/src/components/LiteYouTube';
+## Version 1.60
+
+### 🌐 HAR recording on Tracing
+
+[Tracing.startHar()](/api/class-tracing.mdx#tracing-start-har) / [Tracing.stopHar()](/api/class-tracing.mdx#tracing-stop-har) expose HAR recording as a first-class tracing API, with the same `content`, `mode` and `urlFilter` options as `recordHar`:
+
+```java
+context.tracing().startHar(Paths.get("trace.har"));
+Page page = context.newPage();
+page.navigate("https://playwright.dev");
+context.tracing().stopHar();
+```
+
+### 🪝 Drop API
+
+New [Locator.drop()](/api/class-locator.mdx#locator-drop) simulates an external drag-and-drop of files or clipboard-like data onto an element. Playwright dispatches `dragenter`, `dragover`, and `drop` with a synthetic [DataTransfer] in the page context — works cross-browser and is great for testing upload zones:
+
+```java
+page.locator("#dropzone").drop(new Locator.DropPayload()
+ .setFiles(new FilePayload("note.txt", "text/plain", "hello".getBytes(StandardCharsets.UTF_8))));
+
+page.locator("#dropzone").drop(new Locator.DropPayload()
+ .setData(Map.of(
+ "text/plain", "hello world",
+ "text/uri-list", "https://example.com")));
+```
+
+### 🎯 Aria snapshots
+- [assertThat(page).matchesAriaSnapshot()](/api/class-pageassertions.mdx#page-assertions-to-match-aria-snapshot) now works on a [Page], in addition to a [Locator] — equivalent to asserting against `page.locator("body")`.
+- New `boxes` option on [Locator.ariaSnapshot()](/api/class-locator.mdx#locator-aria-snapshot) / [Page.ariaSnapshot()](/api/class-page.mdx#page-aria-snapshot) appends each element's bounding box as `[box=x,y,width,height]`, useful for AI consumption.
+
+### New APIs
+
+#### Browser, Context and Page
+- Event [Browser.onContext(handler)](/api/class-browser.mdx#browser-event-context) — fired when a new context is created on the browser.
+- [BrowserContext] now mirrors lifecycle events from its pages: [BrowserContext.onDownload(handler)](/api/class-browsercontext.mdx#browser-context-event-download), [BrowserContext.onFrameAttached(handler)](/api/class-browsercontext.mdx#browser-context-event-frame-attached), [BrowserContext.onFrameDetached(handler)](/api/class-browsercontext.mdx#browser-context-event-frame-detached), [BrowserContext.onFrameNavigated(handler)](/api/class-browsercontext.mdx#browser-context-event-frame-navigated), [BrowserContext.onPageClose(handler)](/api/class-browsercontext.mdx#browser-context-event-page-close), [BrowserContext.onPageLoad(handler)](/api/class-browsercontext.mdx#browser-context-event-page-load).
+
+#### Locators and Assertions
+- New option `description` in [Page.getByRole()](/api/class-page.mdx#page-get-by-role) / [Locator.getByRole()](/api/class-locator.mdx#locator-get-by-role) / [Frame.getByRole()](/api/class-frame.mdx#frame-get-by-role) / [FrameLocator.getByRole()](/api/class-framelocator.mdx#frame-locator-get-by-role) for matching the [accessible description](https://www.w3.org/TR/wai-aria-1.2/#dfn-accessible-description).
+- New option `pseudo` in [assertThat(locator).hasCSS()](/api/class-locatorassertions.mdx#locator-assertions-to-have-css) reads computed styles from `::before` or `::after`.
+- New option `style` in [Locator.highlight()](/api/class-locator.mdx#locator-highlight) applies extra inline CSS to the highlight overlay, plus new [Page.hideHighlight()](/api/class-page.mdx#page-hide-highlight) to clear all highlights.
+
+#### Network
+- [WebSocketRoute.protocols()](/api/class-websocketroute.mdx#web-socket-route-protocols) returns the WebSocket subprotocols requested by the page.
+- New option `noDefaults` in [BrowserType.connectOverCDP()](/api/class-browsertype.mdx#browser-type-connect-over-cdp) disables Playwright's default overrides on the default context (download behavior, focus emulation, media emulation), so attaching to a user's daily-driver browser doesn't disturb its state.
+
+#### Errors
+- New [WebError.location()](/api/class-weberror.mdx#web-error-location) mirrors [ConsoleMessage.location()](/api/class-consolemessage.mdx#console-message-location).
+
+### 🛠️ Other improvements
+- Trace Viewer adds a pretty-print toggle for JSON / form request and response bodies in the network details panel.
+
+### Breaking Changes ⚠️
+- Removed long-deprecated `handle` option on `BrowserContext.exposeBinding` and `Page.exposeBinding`.
+
+### Browser Versions
+- Chromium 148.0.7778.96
+- Mozilla Firefox 150.0.2
+- WebKit 26.4
+
+This version was also tested against the following stable channels:
+- Google Chrome 147
+- Microsoft Edge 147
+
## Version 1.59
### 🎬 Screencast
diff --git a/java/versioned_docs/version-stable/test-runners.mdx b/java/versioned_docs/version-stable/test-runners.mdx
index 457c4e4e0a..338044a292 100644
--- a/java/versioned_docs/version-stable/test-runners.mdx
+++ b/java/versioned_docs/version-stable/test-runners.mdx
@@ -198,7 +198,7 @@ repositories {
}
dependencies {
- implementation 'com.microsoft.playwright:playwright:1.59.0'
+ implementation 'com.microsoft.playwright:playwright:1.60.0'
}
application {
@@ -231,7 +231,7 @@ repositories {
}
dependencies {
- implementation("com.microsoft.playwright:playwright:1.59.0")
+ implementation("com.microsoft.playwright:playwright:1.60.0")
}
application {
diff --git a/java/versioned_docs/version-stable/webview2.mdx b/java/versioned_docs/version-stable/webview2.mdx
index 8d979f757d..30cdec7533 100644
--- a/java/versioned_docs/version-stable/webview2.mdx
+++ b/java/versioned_docs/version-stable/webview2.mdx
@@ -47,6 +47,8 @@ By default, the WebView2 control will use the same user data directory for all i
Using the following, Playwright will run your WebView2 application as a sub-process, assign a unique user data directory to it and provide the [Page] instance to your test:
+
+
```java title="WebView2Process.java"
package com.example;
diff --git a/nodejs/versioned_docs/version-stable/api/class-browsercontext.mdx b/nodejs/versioned_docs/version-stable/api/class-browsercontext.mdx
index 2cc96b2b95..22d938bc33 100644
--- a/nodejs/versioned_docs/version-stable/api/class-browsercontext.mdx
+++ b/nodejs/versioned_docs/version-stable/api/class-browsercontext.mdx
@@ -1448,7 +1448,7 @@ browserContext.on('weberror', data => {});
Added in: v1.11browserContext.on('backgroundpage')
-:::warning Deprecated
+:::warning[Deprecated]
Background pages have been removed from Chromium together with Manifest V2 extensions.
@@ -1472,7 +1472,7 @@ browserContext.on('backgroundpage', data => {});
Added in: v1.11browserContext.backgroundPages
-:::warning Deprecated
+:::warning[Deprecated]
Background pages have been removed from Chromium together with Manifest V2 extensions.
@@ -1496,7 +1496,7 @@ browserContext.backgroundPages();
Added before v1.9browserContext.setHTTPCredentials
-:::warning Deprecated
+:::warning[Deprecated]
Browsers may cache credentials after successful authentication. Create a new browser context instead.
diff --git a/nodejs/versioned_docs/version-stable/api/class-elementhandle.mdx b/nodejs/versioned_docs/version-stable/api/class-elementhandle.mdx
index ea3f35ac87..aec8e5d123 100644
--- a/nodejs/versioned_docs/version-stable/api/class-elementhandle.mdx
+++ b/nodejs/versioned_docs/version-stable/api/class-elementhandle.mdx
@@ -1441,7 +1441,7 @@ await elementHandle.textContent();
Added before v1.9elementHandle.type
-:::warning Deprecated
+:::warning[Deprecated]
In most cases, you should use [locator.fill()](/api/class-locator.mdx#locator-fill) instead. You only need to press keys one by one if there is special keyboard handling on the page - in this case use [locator.pressSequentially()](/api/class-locator.mdx#locator-press-sequentially).
diff --git a/nodejs/versioned_docs/version-stable/api/class-frame.mdx b/nodejs/versioned_docs/version-stable/api/class-frame.mdx
index ab93345d45..8e83649543 100644
--- a/nodejs/versioned_docs/version-stable/api/class-frame.mdx
+++ b/nodejs/versioned_docs/version-stable/api/class-frame.mdx
@@ -2406,7 +2406,7 @@ await frame.textContent(selector, options);
Added before v1.9frame.type
-:::warning Deprecated
+:::warning[Deprecated]
In most cases, you should use [locator.fill()](/api/class-locator.mdx#locator-fill) instead. You only need to press keys one by one if there is special keyboard handling on the page - in this case use [locator.pressSequentially()](/api/class-locator.mdx#locator-press-sequentially).
@@ -2521,7 +2521,7 @@ await frame.uncheck(selector, options);
Added before v1.9frame.waitForNavigation
-:::warning Deprecated
+:::warning[Deprecated]
This method is inherently racy, please use [frame.waitForURL()](/api/class-frame.mdx#frame-wait-for-url) instead.
diff --git a/nodejs/versioned_docs/version-stable/api/class-framelocator.mdx b/nodejs/versioned_docs/version-stable/api/class-framelocator.mdx
index 8f620582cc..00c648a7c4 100644
--- a/nodejs/versioned_docs/version-stable/api/class-framelocator.mdx
+++ b/nodejs/versioned_docs/version-stable/api/class-framelocator.mdx
@@ -471,7 +471,7 @@ await expect(locator).toBeVisible();
Added in: v1.17frameLocator.first
-:::warning Deprecated
+:::warning[Deprecated]
Use [locator.first()](/api/class-locator.mdx#locator-first) followed by [locator.contentFrame()](/api/class-locator.mdx#locator-content-frame) instead.
@@ -495,7 +495,7 @@ frameLocator.first();
Added in: v1.17frameLocator.last
-:::warning Deprecated
+:::warning[Deprecated]
Use [locator.last()](/api/class-locator.mdx#locator-last) followed by [locator.contentFrame()](/api/class-locator.mdx#locator-content-frame) instead.
@@ -519,7 +519,7 @@ frameLocator.last();
Added in: v1.17frameLocator.nth
-:::warning Deprecated
+:::warning[Deprecated]
Use [locator.nth()](/api/class-locator.mdx#locator-nth) followed by [locator.contentFrame()](/api/class-locator.mdx#locator-content-frame) instead.
diff --git a/nodejs/versioned_docs/version-stable/api/class-locator.mdx b/nodejs/versioned_docs/version-stable/api/class-locator.mdx
index cd7f112dc6..0eb0a3a790 100644
--- a/nodejs/versioned_docs/version-stable/api/class-locator.mdx
+++ b/nodejs/versioned_docs/version-stable/api/class-locator.mdx
@@ -2631,7 +2631,7 @@ await locator.elementHandles();
Added in: v1.14locator.type
-:::warning Deprecated
+:::warning[Deprecated]
In most cases, you should use [locator.fill()](/api/class-locator.mdx#locator-fill) instead. You only need to press keys one by one if there is special keyboard handling on the page - in this case use [locator.pressSequentially()](/api/class-locator.mdx#locator-press-sequentially).
diff --git a/nodejs/versioned_docs/version-stable/api/class-page.mdx b/nodejs/versioned_docs/version-stable/api/class-page.mdx
index 447ac269eb..2623181a36 100644
--- a/nodejs/versioned_docs/version-stable/api/class-page.mdx
+++ b/nodejs/versioned_docs/version-stable/api/class-page.mdx
@@ -4395,7 +4395,7 @@ await page.textContent(selector, options);
Added before v1.9page.type
-:::warning Deprecated
+:::warning[Deprecated]
In most cases, you should use [locator.fill()](/api/class-locator.mdx#locator-fill) instead. You only need to press keys one by one if there is special keyboard handling on the page - in this case use [locator.pressSequentially()](/api/class-locator.mdx#locator-press-sequentially).
@@ -4510,7 +4510,7 @@ await page.uncheck(selector, options);
Added before v1.9page.waitForNavigation
-:::warning Deprecated
+:::warning[Deprecated]
This method is inherently racy, please use [page.waitForURL()](/api/class-page.mdx#page-wait-for-url) instead.
diff --git a/nodejs/versioned_docs/version-stable/webview2.mdx b/nodejs/versioned_docs/version-stable/webview2.mdx
index 1d0e876ceb..c061ce43f3 100644
--- a/nodejs/versioned_docs/version-stable/webview2.mdx
+++ b/nodejs/versioned_docs/version-stable/webview2.mdx
@@ -47,6 +47,8 @@ By default, the WebView2 control will use the same user data directory for all i
Using the following, Playwright will run your WebView2 application as a sub-process, assign a unique user data directory to it and provide the [Page] instance to your test:
+
+
```js title="webView2Test.ts"
import { test as base } from '@playwright/test';
import fs from 'fs';
diff --git a/python/versioned_docs/version-stable/api/class-browsercontext.mdx b/python/versioned_docs/version-stable/api/class-browsercontext.mdx
index 95b8e58703..97734113c5 100644
--- a/python/versioned_docs/version-stable/api/class-browsercontext.mdx
+++ b/python/versioned_docs/version-stable/api/class-browsercontext.mdx
@@ -1920,7 +1920,7 @@ browser_context.on("weberror", handler)
Added in: v1.11browserContext.on("backgroundpage")
-:::warning Deprecated
+:::warning[Deprecated]
Background pages have been removed from Chromium together with Manifest V2 extensions.
@@ -1944,7 +1944,7 @@ browser_context.on("backgroundpage", handler)
Added in: v1.11browserContext.background_pages
-:::warning Deprecated
+:::warning[Deprecated]
Background pages have been removed from Chromium together with Manifest V2 extensions.
diff --git a/python/versioned_docs/version-stable/api/class-elementhandle.mdx b/python/versioned_docs/version-stable/api/class-elementhandle.mdx
index 73012ef084..f4af446d41 100644
--- a/python/versioned_docs/version-stable/api/class-elementhandle.mdx
+++ b/python/versioned_docs/version-stable/api/class-elementhandle.mdx
@@ -1616,7 +1616,7 @@ element_handle.text_content()
Added before v1.9elementHandle.type
-:::warning Deprecated
+:::warning[Deprecated]
In most cases, you should use [locator.fill()](/api/class-locator.mdx#locator-fill) instead. You only need to press keys one by one if there is special keyboard handling on the page - in this case use [locator.press_sequentially()](/api/class-locator.mdx#locator-press-sequentially).
diff --git a/python/versioned_docs/version-stable/api/class-frame.mdx b/python/versioned_docs/version-stable/api/class-frame.mdx
index d9b560b55f..588323bf75 100644
--- a/python/versioned_docs/version-stable/api/class-frame.mdx
+++ b/python/versioned_docs/version-stable/api/class-frame.mdx
@@ -1972,7 +1972,7 @@ divs_counts = await frame.eval_on_selector_all("div", "(divs, min) => divs.lengt
Added before v1.9frame.expect_navigation
-:::warning Deprecated
+:::warning[Deprecated]
This method is inherently racy, please use [frame.wait_for_url()](/api/class-frame.mdx#frame-wait-for-url) instead.
@@ -2998,7 +2998,7 @@ frame.text_content(selector, **kwargs)
Added before v1.9frame.type
-:::warning Deprecated
+:::warning[Deprecated]
In most cases, you should use [locator.fill()](/api/class-locator.mdx#locator-fill) instead. You only need to press keys one by one if there is special keyboard handling on the page - in this case use [locator.press_sequentially()](/api/class-locator.mdx#locator-press-sequentially).
diff --git a/python/versioned_docs/version-stable/api/class-framelocator.mdx b/python/versioned_docs/version-stable/api/class-framelocator.mdx
index 2fd130864b..24aefc0526 100644
--- a/python/versioned_docs/version-stable/api/class-framelocator.mdx
+++ b/python/versioned_docs/version-stable/api/class-framelocator.mdx
@@ -679,7 +679,7 @@ await expect(locator).to_be_visible()
Added in: v1.17frameLocator.first
-:::warning Deprecated
+:::warning[Deprecated]
Use [locator.first](/api/class-locator.mdx#locator-first) followed by [locator.content_frame](/api/class-locator.mdx#locator-content-frame) instead.
@@ -703,7 +703,7 @@ frame_locator.first
Added in: v1.17frameLocator.last
-:::warning Deprecated
+:::warning[Deprecated]
Use [locator.last](/api/class-locator.mdx#locator-last) followed by [locator.content_frame](/api/class-locator.mdx#locator-content-frame) instead.
@@ -727,7 +727,7 @@ frame_locator.last
Added in: v1.17frameLocator.nth
-:::warning Deprecated
+:::warning[Deprecated]
Use [locator.nth()](/api/class-locator.mdx#locator-nth) followed by [locator.content_frame](/api/class-locator.mdx#locator-content-frame) instead.
diff --git a/python/versioned_docs/version-stable/api/class-locator.mdx b/python/versioned_docs/version-stable/api/class-locator.mdx
index d5e37c0128..1bdbbfab40 100644
--- a/python/versioned_docs/version-stable/api/class-locator.mdx
+++ b/python/versioned_docs/version-stable/api/class-locator.mdx
@@ -3606,7 +3606,7 @@ locator.element_handles()
Added in: v1.14locator.type
-:::warning Deprecated
+:::warning[Deprecated]
In most cases, you should use [locator.fill()](/api/class-locator.mdx#locator-fill) instead. You only need to press keys one by one if there is special keyboard handling on the page - in this case use [locator.press_sequentially()](/api/class-locator.mdx#locator-press-sequentially).
diff --git a/python/versioned_docs/version-stable/api/class-page.mdx b/python/versioned_docs/version-stable/api/class-page.mdx
index 47ad69d582..9b02e85bd8 100644
--- a/python/versioned_docs/version-stable/api/class-page.mdx
+++ b/python/versioned_docs/version-stable/api/class-page.mdx
@@ -4702,7 +4702,7 @@ div_counts = await page.eval_on_selector_all("div", "(divs, min) => divs.length
Added before v1.9page.expect_navigation
-:::warning Deprecated
+:::warning[Deprecated]
This method is inherently racy, please use [page.wait_for_url()](/api/class-page.mdx#page-wait-for-url) instead.
@@ -5789,7 +5789,7 @@ page.text_content(selector, **kwargs)
Added before v1.9page.type
-:::warning Deprecated
+:::warning[Deprecated]
In most cases, you should use [locator.fill()](/api/class-locator.mdx#locator-fill) instead. You only need to press keys one by one if there is special keyboard handling on the page - in this case use [locator.press_sequentially()](/api/class-locator.mdx#locator-press-sequentially).
diff --git a/python/versioned_docs/version-stable/ci.mdx b/python/versioned_docs/version-stable/ci.mdx
index da419c80b2..1124a2915b 100644
--- a/python/versioned_docs/version-stable/ci.mdx
+++ b/python/versioned_docs/version-stable/ci.mdx
@@ -83,7 +83,7 @@ jobs:
name: 'Playwright Tests'
runs-on: ubuntu-latest
container:
- image: mcr.microsoft.com/playwright/python:v1.59.0-noble
+ image: mcr.microsoft.com/playwright/python:v1.60.0-noble
options: --user 1001
steps:
- uses: actions/checkout@v5
@@ -173,7 +173,7 @@ trigger:
pool:
vmImage: ubuntu-latest
-container: mcr.microsoft.com/playwright/python:v1.59.0-noble
+container: mcr.microsoft.com/playwright/python:v1.60.0-noble
steps:
- task: UsePythonVersion@0
@@ -197,7 +197,7 @@ Running Playwright on CircleCI is very similar to running on GitHub Actions. In
executors:
pw-noble-development:
docker:
- - image: mcr.microsoft.com/playwright/python:v1.59.0-noble
+ - image: mcr.microsoft.com/playwright/python:v1.60.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.
@@ -208,7 +208,7 @@ Jenkins supports Docker agents for pipelines. Use the [Playwright Docker image](
```groovy
pipeline {
- agent { docker { image 'mcr.microsoft.com/playwright/python:v1.59.0-noble' } }
+ agent { docker { image 'mcr.microsoft.com/playwright/python:v1.60.0-noble' } }
stages {
stage('e2e-tests') {
steps {
@@ -225,7 +225,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/python:v1.59.0-noble
+image: mcr.microsoft.com/playwright/python:v1.60.0-noble
```
### GitLab CI
@@ -238,7 +238,7 @@ stages:
tests:
stage: test
- image: mcr.microsoft.com/playwright/python:v1.59.0-noble
+ image: mcr.microsoft.com/playwright/python:v1.60.0-noble
script:
...
```
diff --git a/python/versioned_docs/version-stable/docker.mdx b/python/versioned_docs/version-stable/docker.mdx
index 1ba0a30b4c..e0bdd8e0a2 100644
--- a/python/versioned_docs/version-stable/docker.mdx
+++ b/python/versioned_docs/version-stable/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/python:v1.59.0-noble
+docker pull mcr.microsoft.com/playwright/python:v1.60.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/python:v1.59.0-noble /bin/bash
+docker run -it --rm --ipc=host mcr.microsoft.com/playwright/python:v1.60.0-noble /bin/bash
```
#### Crawling and scraping
@@ -42,7 +42,7 @@ docker run -it --rm --ipc=host mcr.microsoft.com/playwright/python:v1.59.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/python:v1.59.0-noble /bin/bash
+docker run -it --rm --ipc=host --user pwuser --security-opt seccomp=seccomp_profile.json mcr.microsoft.com/playwright/python:v1.60.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.59.0-noble /bin/sh -c "npx -y playwright@1.59.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.60.0-noble /bin/sh -c "npx -y playwright@1.60.0 run-server --port 3000 --host 0.0.0.0"
```
#### Connecting to the Server
@@ -122,7 +122,7 @@ async with async_playwright() as p:
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.59.0-noble /bin/sh -c "npx -y playwright@1.59.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.60.0-noble /bin/sh -c "npx -y playwright@1.60.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.
@@ -155,9 +155,9 @@ 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.59.0` - Playwright v1.59.0 release docker image based on Ubuntu 24.04 LTS (Noble Numbat).
-- `:v1.59.0-noble` - Playwright v1.59.0 release docker image based on Ubuntu 24.04 LTS (Noble Numbat).
-- `:v1.59.0-jammy` - Playwright v1.59.0 release docker image based on Ubuntu 22.04 LTS (Jammy Jellyfish).
+- `:v1.60.0` - Playwright v1.60.0 release docker image based on Ubuntu 24.04 LTS (Noble Numbat).
+- `:v1.60.0-noble` - Playwright v1.60.0 release docker image based on Ubuntu 24.04 LTS (Noble Numbat).
+- `:v1.60.0-jammy` - Playwright v1.60.0 release docker image based on Ubuntu 22.04 LTS (Jammy Jellyfish).
:::note
@@ -181,7 +181,7 @@ To run Playwright inside Docker, you need to have Python, [Playwright browsers](
```Dockerfile
FROM python:3.12-bookworm
-RUN pip install playwright==@1.59.0 && \
+RUN pip install playwright==@1.60.0 && \
playwright install --with-deps
```
diff --git a/python/versioned_docs/version-stable/release-notes.mdx b/python/versioned_docs/version-stable/release-notes.mdx
index 505a9fc696..653eb492b9 100644
--- a/python/versioned_docs/version-stable/release-notes.mdx
+++ b/python/versioned_docs/version-stable/release-notes.mdx
@@ -9,6 +9,74 @@ import HTMLCard from '@site/src/components/HTMLCard';
import LiteYouTube from '@site/src/components/LiteYouTube';
+## Version 1.60
+
+### 🌐 HAR recording on Tracing
+
+[tracing.start_har()](/api/class-tracing.mdx#tracing-start-har) / [tracing.stop_har()](/api/class-tracing.mdx#tracing-stop-har) expose HAR recording as a first-class tracing API, with the same `content`, `mode` and `url_filter` options as `record_har`:
+
+```python
+context.tracing.start_har("trace.har")
+page = context.new_page()
+page.goto("https://playwright.dev")
+context.tracing.stop_har()
+```
+
+### 🪝 Drop API
+
+New [locator.drop()](/api/class-locator.mdx#locator-drop) simulates an external drag-and-drop of files or clipboard-like data onto an element. Playwright dispatches `dragenter`, `dragover`, and `drop` with a synthetic [DataTransfer] in the page context — works cross-browser and is great for testing upload zones:
+
+```python
+page.locator("#dropzone").drop(
+ files={"name": "note.txt", "mime_type": "text/plain", "buffer": b"hello"},
+)
+
+page.locator("#dropzone").drop(
+ data={
+ "text/plain": "hello world",
+ "text/uri-list": "https://example.com",
+ },
+)
+```
+
+### 🎯 Aria snapshots
+- [expect(page).to_match_aria_snapshot()](/api/class-pageassertions.mdx#page-assertions-to-match-aria-snapshot) now works on a [Page], in addition to a [Locator] — equivalent to asserting against `page.locator("body")`.
+- New `boxes` option on [locator.aria_snapshot()](/api/class-locator.mdx#locator-aria-snapshot) / [page.aria_snapshot()](/api/class-page.mdx#page-aria-snapshot) appends each element's bounding box as `[box=x,y,width,height]`, useful for AI consumption.
+
+### New APIs
+
+#### Browser, Context and Page
+- Event [browser.on("context")](/api/class-browser.mdx#browser-event-context) — fired when a new context is created on the browser.
+- [BrowserContext] now mirrors lifecycle events from its pages: [browser_context.on("download")](/api/class-browsercontext.mdx#browser-context-event-download), [browser_context.on("frameattached")](/api/class-browsercontext.mdx#browser-context-event-frame-attached), [browser_context.on("framedetached")](/api/class-browsercontext.mdx#browser-context-event-frame-detached), [browser_context.on("framenavigated")](/api/class-browsercontext.mdx#browser-context-event-frame-navigated), [browser_context.on("pageclose")](/api/class-browsercontext.mdx#browser-context-event-page-close), [browser_context.on("pageload")](/api/class-browsercontext.mdx#browser-context-event-page-load).
+
+#### Locators and Assertions
+- New option `description` in [page.get_by_role()](/api/class-page.mdx#page-get-by-role) / [locator.get_by_role()](/api/class-locator.mdx#locator-get-by-role) / [frame.get_by_role()](/api/class-frame.mdx#frame-get-by-role) / [frame_locator.get_by_role()](/api/class-framelocator.mdx#frame-locator-get-by-role) for matching the [accessible description](https://www.w3.org/TR/wai-aria-1.2/#dfn-accessible-description).
+- New option `pseudo` in [expect(locator).to_have_css()](/api/class-locatorassertions.mdx#locator-assertions-to-have-css) reads computed styles from `::before` or `::after`.
+- New option `style` in [locator.highlight()](/api/class-locator.mdx#locator-highlight) applies extra inline CSS to the highlight overlay, plus new [page.hide_highlight()](/api/class-page.mdx#page-hide-highlight) to clear all highlights.
+
+#### Network
+- [web_socket_route.protocols](/api/class-websocketroute.mdx#web-socket-route-protocols) returns the WebSocket subprotocols requested by the page.
+- New option `no_defaults` in [browser_type.connect_over_cdp()](/api/class-browsertype.mdx#browser-type-connect-over-cdp) disables Playwright's default overrides on the default context (download behavior, focus emulation, media emulation), so attaching to a user's daily-driver browser doesn't disturb its state.
+
+#### Errors
+- New [web_error.location](/api/class-weberror.mdx#web-error-location) mirrors [console_message.location](/api/class-consolemessage.mdx#console-message-location).
+- [console_message.location](/api/class-consolemessage.mdx#console-message-location) now exposes `line` / `column` properties (`line_number` / `column_number` are deprecated).
+
+### 🛠️ Other improvements
+- Trace Viewer adds a pretty-print toggle for JSON / form request and response bodies in the network details panel.
+
+### Breaking Changes ⚠️
+- Removed long-deprecated `handle` option on `BrowserContext.expose_binding` and `Page.expose_binding`.
+
+### Browser Versions
+- Chromium 148.0.7778.96
+- Mozilla Firefox 150.0.2
+- WebKit 26.4
+
+This version was also tested against the following stable channels:
+- Google Chrome 147
+- Microsoft Edge 147
+
## Version 1.59
### 🎬 Screencast
diff --git a/python/versioned_docs/version-stable/webview2.mdx b/python/versioned_docs/version-stable/webview2.mdx
index 832ac46923..9fe3d09759 100644
--- a/python/versioned_docs/version-stable/webview2.mdx
+++ b/python/versioned_docs/version-stable/webview2.mdx
@@ -69,6 +69,8 @@ By default, the WebView2 control will use the same user data directory for all i
Using the following, Playwright will run your WebView2 application as a sub-process, assign a unique user data directory to it and provide the [Page] instance to your test:
+
+
```python title="conftest.py"
import os
import socket