From 341a15be52cadc697d15a87ad30ec6a10d60b668 Mon Sep 17 00:00:00 2001 From: "microsoft-playwright-automation[bot]" <203992400+microsoft-playwright-automation[bot]@users.noreply.github.com> Date: Wed, 27 May 2026 11:24:49 +0000 Subject: [PATCH] feat(roll): roll to ToT Playwright (27-05-26) --- dotnet/docs/api/class-apiresponse.mdx | 54 +++++++++++++++++++++++++++ dotnet/docs/api/class-frame.mdx | 2 +- dotnet/docs/api/class-page.mdx | 4 +- dotnet/docs/api/class-touchscreen.mdx | 2 +- dotnet/docs/ci.mdx | 10 ++--- dotnet/docs/docker.mdx | 16 ++++---- java/docs/api/class-apiresponse.mdx | 54 +++++++++++++++++++++++++++ java/docs/api/class-frame.mdx | 2 +- java/docs/api/class-page.mdx | 4 +- java/docs/api/class-touchscreen.mdx | 2 +- nodejs/docs/api/class-apiresponse.mdx | 54 +++++++++++++++++++++++++++ nodejs/docs/api/class-electron.mdx | 23 ++++++++++++ nodejs/docs/api/class-frame.mdx | 2 +- nodejs/docs/api/class-fullconfig.mdx | 17 +++++++++ nodejs/docs/api/class-page.mdx | 4 +- nodejs/docs/api/class-touchscreen.mdx | 2 +- nodejs/docs/release-notes.mdx | 1 + nodejs/docs/test-reporters.mdx | 16 +++++++- python/docs/api/class-apiresponse.mdx | 54 +++++++++++++++++++++++++++ python/docs/api/class-frame.mdx | 16 ++++---- python/docs/api/class-page.mdx | 6 +-- python/docs/api/class-touchscreen.mdx | 2 +- 22 files changed, 309 insertions(+), 38 deletions(-) diff --git a/dotnet/docs/api/class-apiresponse.mdx b/dotnet/docs/api/class-apiresponse.mdx index 11534cb98a..72eed3166e 100644 --- a/dotnet/docs/api/class-apiresponse.mdx +++ b/dotnet/docs/api/class-apiresponse.mdx @@ -122,6 +122,60 @@ ApiResponse.Ok **Returns** - [bool]# +--- + +### SecurityDetailsAsync {#api-response-security-details} + +Added in: v1.61apiResponse.SecurityDetailsAsync + +Returns SSL and other security information. Resolves to `null` for non-HTTPS responses. For redirected requests, returns the information for the last request in the redirect chain. + +**Usage** + +```csharp +await ApiResponse.SecurityDetailsAsync(); +``` + +**Returns** +- SecurityDetails?# + - `issuer` [string]? *(optional)* + + Common Name component of the Issuer field. from the certificate. This should only be used for informational purposes. Optional. + - `protocol` [string]? *(optional)* + + The specific TLS protocol used. (e.g. `TLS 1.3`). Optional. + - `subjectName` [string]? *(optional)* + + Common Name component of the Subject field from the certificate. This should only be used for informational purposes. Optional. + - `validFrom` [float]? *(optional)* + + Unix timestamp (in seconds) specifying when this cert becomes valid. Optional. + - `validTo` [float]? *(optional)* + + Unix timestamp (in seconds) specifying when this cert becomes invalid. Optional. + +--- + +### ServerAddrAsync {#api-response-server-addr} + +Added in: v1.61apiResponse.ServerAddrAsync + +Returns the IP address and port of the server. Resolves to `null` if the server address is not available. For redirected requests, returns the information for the last request in the redirect chain. + +**Usage** + +```csharp +await ApiResponse.ServerAddrAsync(); +``` + +**Returns** +- ServerAddr?# + - `ipAddress` [string] + + IPv4 or IPV6 address of the server. + - `port` [int] + + --- ### Status {#api-response-status} diff --git a/dotnet/docs/api/class-frame.mdx b/dotnet/docs/api/class-frame.mdx index 8e3d26b7a1..8200981b08 100644 --- a/dotnet/docs/api/class-frame.mdx +++ b/dotnet/docs/api/class-frame.mdx @@ -233,7 +233,7 @@ Console.WriteLine(await frame.EvaluateAsync("1 + 2")); // prints "3" [ElementHandle] instances can be passed as an argument to the [Frame.EvaluateAsync()](/api/class-frame.mdx#frame-evaluate): ```csharp -var bodyHandle = await frame.EvaluateAsync("document.body"); +var bodyHandle = await frame.EvaluateHandleAsync("document.body"); var html = await frame.EvaluateAsync("([body, suffix]) => body.innerHTML + suffix", new object [] { bodyHandle, "hello" }); await bodyHandle.DisposeAsync(); ``` diff --git a/dotnet/docs/api/class-page.mdx b/dotnet/docs/api/class-page.mdx index 750dd02efd..cecf701cbd 100644 --- a/dotnet/docs/api/class-page.mdx +++ b/dotnet/docs/api/class-page.mdx @@ -587,7 +587,7 @@ Console.WriteLine(await page.EvaluateAsync("1 + 2")); // prints "3" [ElementHandle] instances can be passed as an argument to the [Page.EvaluateAsync()](/api/class-page.mdx#page-evaluate): ```csharp -var bodyHandle = await page.EvaluateAsync("document.body"); +var bodyHandle = await page.EvaluateHandleAsync("document.body"); var html = await page.EvaluateAsync("([body, suffix]) => body.innerHTML + suffix", new object [] { bodyHandle, "hello" }); await bodyHandle.DisposeAsync(); ``` @@ -4767,7 +4767,7 @@ When all steps combined have not finished during the specified [Timeout](/api/cl :::note -[Page.TapAsync()](/api/class-page.mdx#page-tap) the method will throw if [HasTouch](/api/class-browser.mdx#browser-new-context-option-has-touch) option of the browser context is false. +[Page.TapAsync()](/api/class-page.mdx#page-tap) will throw if the [HasTouch](/api/class-browser.mdx#browser-new-context-option-has-touch) option of the browser context is false. ::: **Usage** diff --git a/dotnet/docs/api/class-touchscreen.mdx b/dotnet/docs/api/class-touchscreen.mdx index 39f4e805ba..203688059e 100644 --- a/dotnet/docs/api/class-touchscreen.mdx +++ b/dotnet/docs/api/class-touchscreen.mdx @@ -24,7 +24,7 @@ Dispatches a `touchstart` and `touchend` event with a single touch at the positi :::note -[Page.TapAsync()](/api/class-page.mdx#page-tap) the method will throw if [HasTouch](/api/class-browser.mdx#browser-new-context-option-has-touch) option of the browser context is false. +[Touchscreen.TapAsync()](/api/class-touchscreen.mdx#touchscreen-tap) will throw if the [HasTouch](/api/class-browser.mdx#browser-new-context-option-has-touch) option of the browser context is false. ::: **Usage** diff --git a/dotnet/docs/ci.mdx b/dotnet/docs/ci.mdx index bdd6afc587..862e37f0df 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.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/docs/docker.mdx b/dotnet/docs/docker.mdx index 6b3a367e80..8d6f27c123 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.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/java/docs/api/class-apiresponse.mdx b/java/docs/api/class-apiresponse.mdx index fcf8499f7e..b49ea32d4e 100644 --- a/java/docs/api/class-apiresponse.mdx +++ b/java/docs/api/class-apiresponse.mdx @@ -103,6 +103,60 @@ APIResponse.ok(); **Returns** - [boolean]# +--- + +### securityDetails {#api-response-security-details} + +Added in: v1.61apiResponse.securityDetails + +Returns SSL and other security information. Resolves to `null` for non-HTTPS responses. For redirected requests, returns the information for the last request in the redirect chain. + +**Usage** + +```java +APIResponse.securityDetails(); +``` + +**Returns** +- [null] | SecurityDetails# + - `issuer` [String] *(optional)* + + Common Name component of the Issuer field. from the certificate. This should only be used for informational purposes. Optional. + - `protocol` [String] *(optional)* + + The specific TLS protocol used. (e.g. `TLS 1.3`). Optional. + - `subjectName` [String] *(optional)* + + Common Name component of the Subject field from the certificate. This should only be used for informational purposes. Optional. + - `validFrom` [double] *(optional)* + + Unix timestamp (in seconds) specifying when this cert becomes valid. Optional. + - `validTo` [double] *(optional)* + + Unix timestamp (in seconds) specifying when this cert becomes invalid. Optional. + +--- + +### serverAddr {#api-response-server-addr} + +Added in: v1.61apiResponse.serverAddr + +Returns the IP address and port of the server. Resolves to `null` if the server address is not available. For redirected requests, returns the information for the last request in the redirect chain. + +**Usage** + +```java +APIResponse.serverAddr(); +``` + +**Returns** +- [null] | ServerAddr# + - `ipAddress` [String] + + IPv4 or IPV6 address of the server. + - `port` [int] + + --- ### status {#api-response-status} diff --git a/java/docs/api/class-frame.mdx b/java/docs/api/class-frame.mdx index 81bb349edf..e671762bd2 100644 --- a/java/docs/api/class-frame.mdx +++ b/java/docs/api/class-frame.mdx @@ -235,7 +235,7 @@ System.out.println(frame.evaluate("1 + 2")); // prints "3" [ElementHandle] instances can be passed as an argument to the [Frame.evaluate()](/api/class-frame.mdx#frame-evaluate): ```java -ElementHandle bodyHandle = frame.evaluate("document.body"); +ElementHandle bodyHandle = frame.evaluateHandle("document.body"); String html = (String) frame.evaluate("([body, suffix]) => body.innerHTML + suffix", Arrays.asList(bodyHandle, "hello")); bodyHandle.dispose(); ``` diff --git a/java/docs/api/class-page.mdx b/java/docs/api/class-page.mdx index cff2f45a6b..aa639734f6 100644 --- a/java/docs/api/class-page.mdx +++ b/java/docs/api/class-page.mdx @@ -596,7 +596,7 @@ System.out.println(page.evaluate("1 + 2")); // prints "3" [ElementHandle] instances can be passed as an argument to the [Page.evaluate()](/api/class-page.mdx#page-evaluate): ```java -ElementHandle bodyHandle = page.evaluate("document.body"); +ElementHandle bodyHandle = page.evaluateHandle("document.body"); String html = (String) page.evaluate("([body, suffix]) => body.innerHTML + suffix", Arrays.asList(bodyHandle, "hello")); bodyHandle.dispose(); ``` @@ -4549,7 +4549,7 @@ When all steps combined have not finished during the specified [setTimeout](/api :::note -[Page.tap()](/api/class-page.mdx#page-tap) the method will throw if [setHasTouch](/api/class-browser.mdx#browser-new-context-option-has-touch) option of the browser context is false. +[Page.tap()](/api/class-page.mdx#page-tap) will throw if the [setHasTouch](/api/class-browser.mdx#browser-new-context-option-has-touch) option of the browser context is false. ::: **Usage** diff --git a/java/docs/api/class-touchscreen.mdx b/java/docs/api/class-touchscreen.mdx index 59ad8251ff..656fd22795 100644 --- a/java/docs/api/class-touchscreen.mdx +++ b/java/docs/api/class-touchscreen.mdx @@ -24,7 +24,7 @@ Dispatches a `touchstart` and `touchend` event with a single touch at the positi :::note -[Page.tap()](/api/class-page.mdx#page-tap) the method will throw if [setHasTouch](/api/class-browser.mdx#browser-new-context-option-has-touch) option of the browser context is false. +[Touchscreen.tap()](/api/class-touchscreen.mdx#touchscreen-tap) will throw if the [setHasTouch](/api/class-browser.mdx#browser-new-context-option-has-touch) option of the browser context is false. ::: **Usage** diff --git a/nodejs/docs/api/class-apiresponse.mdx b/nodejs/docs/api/class-apiresponse.mdx index 94c1d09a04..2a7af4e160 100644 --- a/nodejs/docs/api/class-apiresponse.mdx +++ b/nodejs/docs/api/class-apiresponse.mdx @@ -122,6 +122,60 @@ apiResponse.ok(); **Returns** - [boolean]# +--- + +### securityDetails {#api-response-security-details} + +Added in: v1.61apiResponse.securityDetails + +Returns SSL and other security information. Resolves to `null` for non-HTTPS responses. For redirected requests, returns the information for the last request in the redirect chain. + +**Usage** + +```js +await apiResponse.securityDetails(); +``` + +**Returns** +- [Promise]<[null] | [Object]># + - `issuer` [string] *(optional)* + + Common Name component of the Issuer field. from the certificate. This should only be used for informational purposes. Optional. + - `protocol` [string] *(optional)* + + The specific TLS protocol used. (e.g. `TLS 1.3`). Optional. + - `subjectName` [string] *(optional)* + + Common Name component of the Subject field from the certificate. This should only be used for informational purposes. Optional. + - `validFrom` [number] *(optional)* + + Unix timestamp (in seconds) specifying when this cert becomes valid. Optional. + - `validTo` [number] *(optional)* + + Unix timestamp (in seconds) specifying when this cert becomes invalid. Optional. + +--- + +### serverAddr {#api-response-server-addr} + +Added in: v1.61apiResponse.serverAddr + +Returns the IP address and port of the server. Resolves to `null` if the server address is not available. For redirected requests, returns the information for the last request in the redirect chain. + +**Usage** + +```js +await apiResponse.serverAddr(); +``` + +**Returns** +- [Promise]<[null] | [Object]># + - `ipAddress` [string] + + IPv4 or IPV6 address of the server. + - `port` [number] + + --- ### status {#api-response-status} diff --git a/nodejs/docs/api/class-electron.mdx b/nodejs/docs/api/class-electron.mdx index a6efe70472..8456d77e02 100644 --- a/nodejs/docs/api/class-electron.mdx +++ b/nodejs/docs/api/class-electron.mdx @@ -55,6 +55,29 @@ const { _electron: electron } = require('playwright'); If you are not able to launch Electron and it will end up in timeouts during launch, try the following: * Ensure that `nodeCliInspect` ([FuseV1Options.EnableNodeCliInspectArguments](https://www.electronjs.org/docs/latest/tutorial/fuses#nodecliinspect)) fuse is **not** set to `false`. +**Mocking native dialogs:** + +Playwright does not intercept the native Electron [dialog](https://www.electronjs.org/docs/latest/api/dialog) API (`dialog.showOpenDialog`, `dialog.showSaveDialog`, `dialog.showMessageBox`, etc.) because those calls happen in the Electron main process and go straight to OS APIs. Use [electronApplication.evaluate()](/api/class-electronapplication.mdx#electron-application-evaluate) to replace the relevant methods in the main process so tests run deterministically without any OS-level UI: + +```js +// Stub the open dialog to always return a fixed path. +await electronApp.evaluate(({ dialog }, filePaths) => { + dialog.showOpenDialog = () => Promise.resolve({ canceled: false, filePaths }); +}, ['/path/to/file.txt']); + +// Stub the save dialog. +await electronApp.evaluate(({ dialog }, filePath) => { + dialog.showSaveDialog = () => Promise.resolve({ canceled: false, filePath }); +}, '/path/to/saved.txt'); + +// Stub showMessageBox to click the first button. +await electronApp.evaluate(({ dialog }) => { + dialog.showMessageBox = () => Promise.resolve({ response: 0, checkboxChecked: false }); +}); +``` + +The replacement persists until the application is closed. Synchronous variants (`showOpenDialogSync`, `showSaveDialogSync`, `showMessageBoxSync`) can be stubbed the same way — just return the value directly instead of a `Promise`. + --- diff --git a/nodejs/docs/api/class-frame.mdx b/nodejs/docs/api/class-frame.mdx index 1297c908d7..3c6a94a24f 100644 --- a/nodejs/docs/api/class-frame.mdx +++ b/nodejs/docs/api/class-frame.mdx @@ -230,7 +230,7 @@ console.log(await frame.evaluate('1 + 2')); // prints "3" [ElementHandle] instances can be passed as an argument to the [frame.evaluate()](/api/class-frame.mdx#frame-evaluate): ```js -const bodyHandle = await frame.evaluate('document.body'); +const bodyHandle = await frame.evaluateHandle('document.body'); const html = await frame.evaluate(([body, suffix]) => body.innerHTML + suffix, [bodyHandle, 'hello'], ); diff --git a/nodejs/docs/api/class-fullconfig.mdx b/nodejs/docs/api/class-fullconfig.mdx index 329c43ed39..d93eb647ef 100644 --- a/nodejs/docs/api/class-fullconfig.mdx +++ b/nodejs/docs/api/class-fullconfig.mdx @@ -48,6 +48,23 @@ fullConfig.configFile --- +### failOnFlakyTests {#full-config-fail-on-flaky-tests} + +Added in: v1.61fullConfig.failOnFlakyTests + +See [testConfig.failOnFlakyTests](/api/class-testconfig.mdx#test-config-fail-on-flaky-tests). + +**Usage** + +```js +fullConfig.failOnFlakyTests +``` + +**Type** +- [boolean] + +--- + ### forbidOnly {#full-config-forbid-only} Added in: v1.10fullConfig.forbidOnly diff --git a/nodejs/docs/api/class-page.mdx b/nodejs/docs/api/class-page.mdx index 76f1c9923a..3907caa3de 100644 --- a/nodejs/docs/api/class-page.mdx +++ b/nodejs/docs/api/class-page.mdx @@ -610,7 +610,7 @@ console.log(await page.evaluate(`1 + ${x}`)); // prints "11" [ElementHandle] instances can be passed as an argument to the [page.evaluate()](/api/class-page.mdx#page-evaluate): ```js -const bodyHandle = await page.evaluate('document.body'); +const bodyHandle = await page.evaluateHandle('document.body'); const html = await page.evaluate(([body, suffix]) => body.innerHTML + suffix, [bodyHandle, 'hello'] ); @@ -4346,7 +4346,7 @@ When all steps combined have not finished during the specified [timeout](/api/cl :::note -[page.tap()](/api/class-page.mdx#page-tap) the method will throw if [hasTouch](/api/class-browser.mdx#browser-new-context-option-has-touch) option of the browser context is false. +[page.tap()](/api/class-page.mdx#page-tap) will throw if the [hasTouch](/api/class-browser.mdx#browser-new-context-option-has-touch) option of the browser context is false. ::: **Usage** diff --git a/nodejs/docs/api/class-touchscreen.mdx b/nodejs/docs/api/class-touchscreen.mdx index 20ddcfb884..96f9b7510c 100644 --- a/nodejs/docs/api/class-touchscreen.mdx +++ b/nodejs/docs/api/class-touchscreen.mdx @@ -24,7 +24,7 @@ Dispatches a `touchstart` and `touchend` event with a single touch at the positi :::note -[page.tap()](/api/class-page.mdx#page-tap) the method will throw if [hasTouch](/api/class-browser.mdx#browser-new-context-option-has-touch) option of the browser context is false. +[touchscreen.tap()](/api/class-touchscreen.mdx#touchscreen-tap) will throw if the [hasTouch](/api/class-browser.mdx#browser-new-context-option-has-touch) option of the browser context is false. ::: **Usage** diff --git a/nodejs/docs/release-notes.mdx b/nodejs/docs/release-notes.mdx index bcd7a4035d..c0530ca55a 100644 --- a/nodejs/docs/release-notes.mdx +++ b/nodejs/docs/release-notes.mdx @@ -365,6 +365,7 @@ await using page = await context.newPage(); ### Breaking Changes ⚠️ - Removed macOS 14 support for WebKit. We recommend upgrading your macOS version, or keeping an older Playwright version. - Removed `@playwright/experimental-ct-svelte` package. +- `junit` test reporter now differentiates between types of errors, so some of the previous ``s are now reported as ``s. ### Browser Versions - Chromium 147.0.7727.15 diff --git a/nodejs/docs/test-reporters.mdx b/nodejs/docs/test-reporters.mdx index ca3d4de2dc..754d35773a 100644 --- a/nodejs/docs/test-reporters.mdx +++ b/nodejs/docs/test-reporters.mdx @@ -72,7 +72,7 @@ export default defineConfig({ }); ``` -Here is an example output in the middle of a test run. Failures will be listed at the end. +Here is an example output in the middle of a test run. Failures will be listed at the end by default. ```bash npx playwright test --reporter=list @@ -100,13 +100,25 @@ export default defineConfig({ }); ``` +You can print failures inline as soon as they are available instead of waiting until the end of the run: + +```js title="playwright.config.ts" +import { defineConfig } from '@playwright/test'; + +export default defineConfig({ + reporter: [['list', { printFailuresInline: true }]], +}); +``` + List report supports the following configuration options and environment variables: | Environment Variable Name | Reporter Config Option| Description | Default |---|---|---|---| | `PLAYWRIGHT_LIST_PRINT_STEPS` | `printSteps` | Whether to print each step on its own line. | `false` +| `PLAYWRIGHT_LIST_PRINT_FAILURES_INLINE` | `printFailuresInline` | Whether to print failure details immediately after a failed test instead of at the end. | `false` | `PLAYWRIGHT_FORCE_TTY` | | Whether to produce output suitable for a live terminal. Supports `true`, `1`, `false`, `0`, `[WIDTH]`, and `[WIDTH]x[HEIGHT]`. `[WIDTH]` and `[WIDTH]x[HEIGHT]` specifies the TTY dimensions. | `true` when terminal is in TTY mode, `false` otherwise. | `FORCE_COLOR` | | Whether to produce colored output. | `true` when terminal is in TTY mode, `false` otherwise. +| `NO_COLOR` | | Whether to disable colored output ([no-color.org](https://no-color.org/)). Any non-empty value disables colors. | unset ### Line reporter @@ -145,6 +157,7 @@ Line report supports the following configuration options and environment variabl |---|---|---|---| | `PLAYWRIGHT_FORCE_TTY` | | Whether to produce output suitable for a live terminal. Supports `true`, `1`, `false`, `0`, `[WIDTH]`, and `[WIDTH]x[HEIGHT]`. `[WIDTH]` and `[WIDTH]x[HEIGHT]` specifies the TTY dimensions. | `true` when terminal is in TTY mode, `false` otherwise. | `FORCE_COLOR` | | Whether to produce colored output. | `true` when terminal is in TTY mode, `false` otherwise. +| `NO_COLOR` | | Whether to disable colored output ([no-color.org](https://no-color.org/)). Any non-empty value disables colors. | unset ### Dot reporter @@ -187,6 +200,7 @@ Dot report supports the following configuration options and environment variable |---|---|---|---| | `PLAYWRIGHT_FORCE_TTY` | | Whether to produce output suitable for a live terminal. Supports `true`, `1`, `false`, `0`, `[WIDTH]`, and `[WIDTH]x[HEIGHT]`. `[WIDTH]` and `[WIDTH]x[HEIGHT]` specifies the TTY dimensions. | `true` when terminal is in TTY mode, `false` otherwise. | `FORCE_COLOR` | | Whether to produce colored output. | `true` when terminal is in TTY mode, `false` otherwise. +| `NO_COLOR` | | Whether to disable colored output ([no-color.org](https://no-color.org/)). Any non-empty value disables colors. | unset ### HTML reporter diff --git a/python/docs/api/class-apiresponse.mdx b/python/docs/api/class-apiresponse.mdx index 0702e74a52..afda02b7cd 100644 --- a/python/docs/api/class-apiresponse.mdx +++ b/python/docs/api/class-apiresponse.mdx @@ -116,6 +116,60 @@ api_response.json() **Returns** - [Dict]# +--- + +### security_details {#api-response-security-details} + +Added in: v1.61apiResponse.security_details + +Returns SSL and other security information. Resolves to `null` for non-HTTPS responses. For redirected requests, returns the information for the last request in the redirect chain. + +**Usage** + +```python +api_response.security_details() +``` + +**Returns** +- [NoneType] | [Dict]# + - `issuer` [str] *(optional)* + + Common Name component of the Issuer field. from the certificate. This should only be used for informational purposes. Optional. + - `protocol` [str] *(optional)* + + The specific TLS protocol used. (e.g. `TLS 1.3`). Optional. + - `subjectName` [str] *(optional)* + + Common Name component of the Subject field from the certificate. This should only be used for informational purposes. Optional. + - `validFrom` [float] *(optional)* + + Unix timestamp (in seconds) specifying when this cert becomes valid. Optional. + - `validTo` [float] *(optional)* + + Unix timestamp (in seconds) specifying when this cert becomes invalid. Optional. + +--- + +### server_addr {#api-response-server-addr} + +Added in: v1.61apiResponse.server_addr + +Returns the IP address and port of the server. Resolves to `null` if the server address is not available. For redirected requests, returns the information for the last request in the redirect chain. + +**Usage** + +```python +api_response.server_addr() +``` + +**Returns** +- [NoneType] | [Dict]# + - `ipAddress` [str] + + IPv4 or IPV6 address of the server. + - `port` [int] + + --- ### text {#api-response-text} diff --git a/python/docs/api/class-frame.mdx b/python/docs/api/class-frame.mdx index a4c967d9ca..e7a3773efe 100644 --- a/python/docs/api/class-frame.mdx +++ b/python/docs/api/class-frame.mdx @@ -306,7 +306,7 @@ print(await frame.evaluate(f"1 + {x}")) # prints "11" ```py -body_handle = frame.evaluate("document.body") +body_handle = frame.evaluate_handle("document.body") html = frame.evaluate("([body, suffix]) => body.innerHTML + suffix", [body_handle, "hello"]) body_handle.dispose() ``` @@ -315,7 +315,7 @@ body_handle.dispose() ```py -body_handle = await frame.evaluate("document.body") +body_handle = await frame.evaluate_handle("document.body") html = await frame.evaluate("([body, suffix]) => body.innerHTML + suffix", [body_handle, "hello"]) await body_handle.dispose() ``` @@ -387,14 +387,14 @@ A string can also be passed in instead of a function. ```py -a_handle = page.evaluate_handle("document") # handle for the "document" +a_handle = frame.evaluate_handle("document") # handle for the "document" ``` ```py -a_handle = await page.evaluate_handle("document") # handle for the "document" +a_handle = await frame.evaluate_handle("document") # handle for the "document" ``` @@ -413,8 +413,8 @@ a_handle = await page.evaluate_handle("document") # handle for the "document" ```py -a_handle = page.evaluate_handle("document.body") -result_handle = page.evaluate_handle("body => body.innerHTML", a_handle) +a_handle = frame.evaluate_handle("document.body") +result_handle = frame.evaluate_handle("body => body.innerHTML", a_handle) print(result_handle.json_value()) result_handle.dispose() ``` @@ -423,8 +423,8 @@ result_handle.dispose() ```py -a_handle = await page.evaluate_handle("document.body") -result_handle = await page.evaluate_handle("body => body.innerHTML", a_handle) +a_handle = await frame.evaluate_handle("document.body") +result_handle = await frame.evaluate_handle("body => body.innerHTML", a_handle) print(await result_handle.json_value()) await result_handle.dispose() ``` diff --git a/python/docs/api/class-page.mdx b/python/docs/api/class-page.mdx index 2d84d3cd1d..0930a2810b 100644 --- a/python/docs/api/class-page.mdx +++ b/python/docs/api/class-page.mdx @@ -870,7 +870,7 @@ print(await page.evaluate(f"1 + {x}")) # prints "11" ```py -body_handle = page.evaluate("document.body") +body_handle = page.evaluate_handle("document.body") html = page.evaluate("([body, suffix]) => body.innerHTML + suffix", [body_handle, "hello"]) body_handle.dispose() ``` @@ -879,7 +879,7 @@ body_handle.dispose() ```py -body_handle = await page.evaluate("document.body") +body_handle = await page.evaluate_handle("document.body") html = await page.evaluate("([body, suffix]) => body.innerHTML + suffix", [body_handle, "hello"]) await body_handle.dispose() ``` @@ -5732,7 +5732,7 @@ When all steps combined have not finished during the specified [timeout](/api/cl :::note -[page.tap()](/api/class-page.mdx#page-tap) the method will throw if [has_touch](/api/class-browser.mdx#browser-new-context-option-has-touch) option of the browser context is false. +[page.tap()](/api/class-page.mdx#page-tap) will throw if the [has_touch](/api/class-browser.mdx#browser-new-context-option-has-touch) option of the browser context is false. ::: **Usage** diff --git a/python/docs/api/class-touchscreen.mdx b/python/docs/api/class-touchscreen.mdx index b7675c4a2f..efad651094 100644 --- a/python/docs/api/class-touchscreen.mdx +++ b/python/docs/api/class-touchscreen.mdx @@ -24,7 +24,7 @@ Dispatches a `touchstart` and `touchend` event with a single touch at the positi :::note -[page.tap()](/api/class-page.mdx#page-tap) the method will throw if [has_touch](/api/class-browser.mdx#browser-new-context-option-has-touch) option of the browser context is false. +[touchscreen.tap()](/api/class-touchscreen.mdx#touchscreen-tap) will throw if the [has_touch](/api/class-browser.mdx#browser-new-context-option-has-touch) option of the browser context is false. ::: **Usage**