From 0e3b273fbfad8ea90831d6ceb48d571d4094cee1 Mon Sep 17 00:00:00 2001 From: Yury Semikhatsky Date: Fri, 12 Jun 2026 12:25:16 -0700 Subject: [PATCH 1/4] chore: roll driver to 1.61.0-beta-1781285686000 Ported upstream changes: - #40843 page.localStorage()/sessionStorage() (WebStorage API) - #40849 context.credentials() WebAuthn virtual authenticator - #40932 APIResponse.securityDetails()/serverAddr() - #41162 ScreencastFrame.timestamp() - #40916 screencast cursor and size options - #40844 comma-separated testIdAttribute (getByTestId now uses internal:testid) - #40718 waitForEventInfo replaced with fire-and-forget __waitInfo__ - #40780 protocol Page.close split into close and runBeforeUnload - #40801 Frame.expect failures are now protocol errors with errorDetails - #41014 connectOverCDP allowed for WebKit, artifactsDir option --- README.md | 6 +- examples/pom.xml | 2 +- .../com/microsoft/playwright/APIResponse.java | 14 ++ .../microsoft/playwright/BrowserContext.java | 7 + .../com/microsoft/playwright/BrowserType.java | 11 + .../com/microsoft/playwright/Credentials.java | 238 ++++++++++++++++++ .../java/com/microsoft/playwright/Frame.java | 4 +- .../java/com/microsoft/playwright/Page.java | 24 +- .../com/microsoft/playwright/Screencast.java | 39 +++ .../microsoft/playwright/ScreencastFrame.java | 5 + .../com/microsoft/playwright/Selectors.java | 3 +- .../com/microsoft/playwright/Touchscreen.java | 4 +- .../com/microsoft/playwright/WebStorage.java | 73 ++++++ .../playwright/impl/APIResponseImpl.java | 18 ++ .../playwright/impl/BrowserContextImpl.java | 7 + .../playwright/impl/BrowserTypeImpl.java | 4 +- .../playwright/impl/ChannelOwner.java | 9 + .../microsoft/playwright/impl/Connection.java | 32 ++- .../playwright/impl/CredentialsImpl.java | 62 +++++ .../microsoft/playwright/impl/FrameImpl.java | 13 +- .../playwright/impl/LocatorUtils.java | 8 +- .../microsoft/playwright/impl/PageImpl.java | 21 +- .../microsoft/playwright/impl/Protocol.java | 7 + .../playwright/impl/ScreencastFrameImpl.java | 9 +- .../playwright/impl/ScreencastImpl.java | 3 +- .../impl/ServerErrorWithDetails.java | 58 +++++ .../playwright/impl/WaitForEventLogger.java | 18 +- .../playwright/impl/WaitableResult.java | 2 + .../playwright/impl/WebStorageImpl.java | 77 ++++++ .../playwright/options/ScreencastCursor.java | 22 ++ .../microsoft/playwright/options/Size.java | 4 +- .../playwright/options/VirtualCredential.java | 41 +++ .../playwright/options/WebStorageItem.java | 23 ++ .../playwright/TestBrowserContextFetch.java | 6 +- .../TestBrowserContextWebAuthn.java | 179 +++++++++++++ .../playwright/TestBrowserTypeConnect.java | 2 +- .../microsoft/playwright/TestGlobalFetch.java | 20 ++ .../microsoft/playwright/TestScreencast.java | 5 +- .../playwright/TestSelectorsGetBy.java | 14 ++ .../microsoft/playwright/TestWebStorage.java | 132 ++++++++++ scripts/DRIVER_VERSION | 2 +- .../playwright/tools/ApiGenerator.java | 7 +- 42 files changed, 1184 insertions(+), 51 deletions(-) create mode 100644 playwright/src/main/java/com/microsoft/playwright/Credentials.java create mode 100644 playwright/src/main/java/com/microsoft/playwright/WebStorage.java create mode 100644 playwright/src/main/java/com/microsoft/playwright/impl/CredentialsImpl.java create mode 100644 playwright/src/main/java/com/microsoft/playwright/impl/ServerErrorWithDetails.java create mode 100644 playwright/src/main/java/com/microsoft/playwright/impl/WebStorageImpl.java create mode 100644 playwright/src/main/java/com/microsoft/playwright/options/ScreencastCursor.java create mode 100644 playwright/src/main/java/com/microsoft/playwright/options/VirtualCredential.java create mode 100644 playwright/src/main/java/com/microsoft/playwright/options/WebStorageItem.java create mode 100644 playwright/src/test/java/com/microsoft/playwright/TestBrowserContextWebAuthn.java create mode 100644 playwright/src/test/java/com/microsoft/playwright/TestWebStorage.java diff --git a/README.md b/README.md index a6d4a38d7..e3e411c3b 100644 --- a/README.md +++ b/README.md @@ -10,9 +10,9 @@ Playwright is a Java library to automate [Chromium](https://www.chromium.org/Hom | | Linux | macOS | Windows | | :--- | :---: | :---: | :---: | -| Chromium 148.0.7778.96 | :white_check_mark: | :white_check_mark: | :white_check_mark: | -| WebKit 26.4 | ✅ | ✅ | ✅ | -| Firefox 150.0.2 | :white_check_mark: | :white_check_mark: | :white_check_mark: | +| Chromium 149.0.7827.55 | :white_check_mark: | :white_check_mark: | :white_check_mark: | +| WebKit 26.5 | ✅ | ✅ | ✅ | +| Firefox 151.0 | :white_check_mark: | :white_check_mark: | :white_check_mark: | ## Documentation diff --git a/examples/pom.xml b/examples/pom.xml index dd612f2c6..3c2db93f1 100644 --- a/examples/pom.xml +++ b/examples/pom.xml @@ -10,7 +10,7 @@ Playwright Client Examples UTF-8 - 1.60.0 + 1.61.0 diff --git a/playwright/src/main/java/com/microsoft/playwright/APIResponse.java b/playwright/src/main/java/com/microsoft/playwright/APIResponse.java index f9409166b..13bd81064 100644 --- a/playwright/src/main/java/com/microsoft/playwright/APIResponse.java +++ b/playwright/src/main/java/com/microsoft/playwright/APIResponse.java @@ -55,6 +55,20 @@ public interface APIResponse { * @since v1.16 */ boolean ok(); + /** + * Returns SSL and other security information. Resolves to {@code null} for non-HTTPS responses. For redirected requests, + * returns the information for the last request in the redirect chain. + * + * @since v1.61 + */ + SecurityDetails securityDetails(); + /** + * Returns the IP address and port of the server. Resolves to {@code null} if the server address is not available. For + * redirected requests, returns the information for the last request in the redirect chain. + * + * @since v1.61 + */ + ServerAddr serverAddr(); /** * Contains the status code of the response (e.g., 200 for a success). * diff --git a/playwright/src/main/java/com/microsoft/playwright/BrowserContext.java b/playwright/src/main/java/com/microsoft/playwright/BrowserContext.java index 02f76f61b..b254cf5c2 100644 --- a/playwright/src/main/java/com/microsoft/playwright/BrowserContext.java +++ b/playwright/src/main/java/com/microsoft/playwright/BrowserContext.java @@ -563,6 +563,13 @@ public WaitForPageOptions setTimeout(double timeout) { * @since v1.45 */ Clock clock(); + /** + * Virtual WebAuthn authenticator for this context. Lets tests seed credentials and intercept {@code + * navigator.credentials.create()} / {@code navigator.credentials.get()} ceremonies. + * + * @since v1.61 + */ + Credentials credentials(); /** * Debugger allows to pause and resume the execution. * diff --git a/playwright/src/main/java/com/microsoft/playwright/BrowserType.java b/playwright/src/main/java/com/microsoft/playwright/BrowserType.java index c57fd7cd2..2fa39586d 100644 --- a/playwright/src/main/java/com/microsoft/playwright/BrowserType.java +++ b/playwright/src/main/java/com/microsoft/playwright/BrowserType.java @@ -124,6 +124,10 @@ public ConnectOptions setTimeout(double timeout) { } } class ConnectOverCDPOptions { + /** + * If specified, browser artifacts (such as traces and downloads) are saved into this directory. + */ + public Path artifactsDir; /** * Additional HTTP headers to be sent with connect request. Optional. */ @@ -153,6 +157,13 @@ class ConnectOverCDPOptions { */ public Double timeout; + /** + * If specified, browser artifacts (such as traces and downloads) are saved into this directory. + */ + public ConnectOverCDPOptions setArtifactsDir(Path artifactsDir) { + this.artifactsDir = artifactsDir; + return this; + } /** * Additional HTTP headers to be sent with connect request. Optional. */ diff --git a/playwright/src/main/java/com/microsoft/playwright/Credentials.java b/playwright/src/main/java/com/microsoft/playwright/Credentials.java new file mode 100644 index 000000000..a3a180095 --- /dev/null +++ b/playwright/src/main/java/com/microsoft/playwright/Credentials.java @@ -0,0 +1,238 @@ +/* + * Copyright (c) Microsoft Corporation. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.microsoft.playwright; + +import com.microsoft.playwright.options.*; +import java.util.*; + +/** + * {@code Credentials} is a virtual WebAuthn authenticator scoped to a {@code BrowserContext}. It lets tests register + * passkeys and answer {@code navigator.credentials.create()} / {@code navigator.credentials.get()} ceremonies in the page, + * without a real authenticator or hardware security key. + * + *

There are two common ways to use it: + * + *

Usage: seed a known credential + *

{@code
+ * BrowserContext context = browser.newContext();
+ *
+ * // A passkey your backend already provisioned for a test user.
+ * context.credentials().create("example.com", new Credentials.CreateOptions()
+ *     .setId(knownCredentialId) // base64url
+ *     .setUserHandle(knownUserHandle) // base64url
+ *     .setPrivateKey(knownPrivateKey) // base64url PKCS#8 (DER)
+ *     .setPublicKey(knownPublicKey)); // base64url SPKI (DER)
+ * context.credentials().install();
+ *
+ * Page page = context.newPage();
+ * page.navigate("https://example.com/login");
+ * // The page's navigator.credentials.get() is answered with the seeded passkey.
+ * }
+ * + *

Usage: capture a passkey, then reuse it + *

{@code
+ * // setup test: let the app register a passkey, then save it.
+ * BrowserContext context = browser.newContext();
+ * context.credentials().install();
+ *
+ * Page page = context.newPage();
+ * page.navigate("https://example.com/register");
+ * page.getByRole(AriaRole.BUTTON, new Page.GetByRoleOptions().setName("Create a passkey")).click();
+ *
+ * // Read back the passkey the page registered — it includes the private key.
+ * VirtualCredential credential = context.credentials().get(
+ *     new Credentials.GetOptions().setRpId("example.com")).get(0);
+ * Files.writeString(Paths.get("playwright/.auth/passkey.json"), new Gson().toJson(credential));
+ * }
+ *
{@code
+ * // later test: seed the captured passkey so the app starts already enrolled.
+ * VirtualCredential credential = new Gson().fromJson(
+ *     Files.readString(Paths.get("playwright/.auth/passkey.json")), VirtualCredential.class);
+ * BrowserContext context = browser.newContext();
+ * context.credentials().create(credential.rpId, new Credentials.CreateOptions()
+ *     .setId(credential.id)
+ *     .setUserHandle(credential.userHandle)
+ *     .setPrivateKey(credential.privateKey)
+ *     .setPublicKey(credential.publicKey));
+ * context.credentials().install();
+ *
+ * Page page = context.newPage();
+ * page.navigate("https://example.com/login");
+ * // navigator.credentials.get() resolves the captured passkey — already signed in.
+ * }
+ * + *

Defaults + */ +public interface Credentials { + class CreateOptions { + /** + * Base64url-encoded credential id. Auto-generated if omitted. + */ + public String id; + /** + * Base64url-encoded PKCS#8 (DER) private key. Auto-generated if omitted. + */ + public String privateKey; + /** + * Base64url-encoded SPKI (DER) public key. Auto-generated if omitted. + */ + public String publicKey; + /** + * Base64url-encoded user handle. Auto-generated if omitted. + */ + public String userHandle; + + /** + * Base64url-encoded credential id. Auto-generated if omitted. + */ + public CreateOptions setId(String id) { + this.id = id; + return this; + } + /** + * Base64url-encoded PKCS#8 (DER) private key. Auto-generated if omitted. + */ + public CreateOptions setPrivateKey(String privateKey) { + this.privateKey = privateKey; + return this; + } + /** + * Base64url-encoded SPKI (DER) public key. Auto-generated if omitted. + */ + public CreateOptions setPublicKey(String publicKey) { + this.publicKey = publicKey; + return this; + } + /** + * Base64url-encoded user handle. Auto-generated if omitted. + */ + public CreateOptions setUserHandle(String userHandle) { + this.userHandle = userHandle; + return this; + } + } + class GetOptions { + /** + * Only return the credential with this base64url-encoded id. + */ + public String id; + /** + * Only return credentials for this relying party id. + */ + public String rpId; + + /** + * Only return the credential with this base64url-encoded id. + */ + public GetOptions setId(String id) { + this.id = id; + return this; + } + /** + * Only return credentials for this relying party id. + */ + public GetOptions setRpId(String rpId) { + this.rpId = rpId; + return this; + } + } + /** + * Installs the virtual WebAuthn authenticator into the context, overriding {@code navigator.credentials.create()} and + * {@code navigator.credentials.get()} in all current and future pages. Call this before the page first touches {@code + * navigator.credentials}. + * + *

Required: until {@link com.microsoft.playwright.Credentials#install Credentials.install()} is called, no interception is + * in place and the page sees the platform's native (or absent) WebAuthn behaviour. Seeding credentials with {@link + * com.microsoft.playwright.Credentials#create Credentials.create()} without installing populates the authenticator, but + * the page will never see those credentials. + * + * @since v1.61 + */ + void install(); + /** + * Seeds a virtual WebAuthn credential and returns it. + * + *

With only {@code rpId}, generates a fresh **ECDSA P-256** keypair, credential id and user handle. The seeded credential + * is discoverable (resident), so the page can resolve it from both username-then-passkey and usernameless passkey flows. + * The returned object carries the private and public keys, so it can be persisted to disk and re-seeded in a later test. + * + *

To **import a known credential**, supply all four of {@code id}, {@code userHandle}, {@code privateKey} and {@code + * publicKey} together. + * + *

Call {@link com.microsoft.playwright.Credentials#install Credentials.install()} before navigating to a page that uses + * WebAuthn. + * + * @param rpId Relying party id (typically the site's effective domain). + * @since v1.61 + */ + default VirtualCredential create(String rpId) { + return create(rpId, null); + } + /** + * Seeds a virtual WebAuthn credential and returns it. + * + *

With only {@code rpId}, generates a fresh **ECDSA P-256** keypair, credential id and user handle. The seeded credential + * is discoverable (resident), so the page can resolve it from both username-then-passkey and usernameless passkey flows. + * The returned object carries the private and public keys, so it can be persisted to disk and re-seeded in a later test. + * + *

To **import a known credential**, supply all four of {@code id}, {@code userHandle}, {@code privateKey} and {@code + * publicKey} together. + * + *

Call {@link com.microsoft.playwright.Credentials#install Credentials.install()} before navigating to a page that uses + * WebAuthn. + * + * @param rpId Relying party id (typically the site's effective domain). + * @since v1.61 + */ + VirtualCredential create(String rpId, CreateOptions options); + /** + * Removes a credential from the authenticator by its id. Works for any credential currently held — both those seeded with + * {@link com.microsoft.playwright.Credentials#create Credentials.create()} and those the page registered itself by calling + * {@code navigator.credentials.create()}. + * + * @param id Base64url-encoded credential id. + * @since v1.61 + */ + void delete(String id); + /** + * Returns every credential currently held by the authenticator, optionally filtered by {@code rpId} or {@code id}. This + * includes both credentials seeded with {@link com.microsoft.playwright.Credentials#create Credentials.create()} and + * credentials the page registered itself by calling {@code navigator.credentials.create()}. + * + *

Each returned credential includes its private and public keys, so a passkey the app just registered can be saved and + * re-seeded into a later test with {@link com.microsoft.playwright.Credentials#create Credentials.create()} — see the + * second example in the class overview. + * + * @since v1.61 + */ + default List get() { + return get(null); + } + /** + * Returns every credential currently held by the authenticator, optionally filtered by {@code rpId} or {@code id}. This + * includes both credentials seeded with {@link com.microsoft.playwright.Credentials#create Credentials.create()} and + * credentials the page registered itself by calling {@code navigator.credentials.create()}. + * + *

Each returned credential includes its private and public keys, so a passkey the app just registered can be saved and + * re-seeded into a later test with {@link com.microsoft.playwright.Credentials#create Credentials.create()} — see the + * second example in the class overview. + * + * @since v1.61 + */ + List get(GetOptions options); +} + diff --git a/playwright/src/main/java/com/microsoft/playwright/Frame.java b/playwright/src/main/java/com/microsoft/playwright/Frame.java index 343a4a5ef..b00258a6b 100644 --- a/playwright/src/main/java/com/microsoft/playwright/Frame.java +++ b/playwright/src/main/java/com/microsoft/playwright/Frame.java @@ -2965,7 +2965,7 @@ default Object evalOnSelectorAll(String selector, String expression) { *

{@code ElementHandle} instances can be passed as an argument to the {@link com.microsoft.playwright.Frame#evaluate * Frame.evaluate()}: *

{@code
-   * 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();
    * }
@@ -3005,7 +3005,7 @@ default Object evaluate(String expression) { *

{@code ElementHandle} instances can be passed as an argument to the {@link com.microsoft.playwright.Frame#evaluate * Frame.evaluate()}: *

{@code
-   * 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/playwright/src/main/java/com/microsoft/playwright/Page.java b/playwright/src/main/java/com/microsoft/playwright/Page.java index da5f4e865..db240171f 100644 --- a/playwright/src/main/java/com/microsoft/playwright/Page.java +++ b/playwright/src/main/java/com/microsoft/playwright/Page.java @@ -4529,7 +4529,7 @@ default Object evalOnSelectorAll(String selector, String expression) { *

{@code ElementHandle} instances can be passed as an argument to the {@link com.microsoft.playwright.Page#evaluate * Page.evaluate()}: *

{@code
-   * 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();
    * }
@@ -4571,7 +4571,7 @@ default Object evaluate(String expression) { *

{@code ElementHandle} instances can be passed as an argument to the {@link com.microsoft.playwright.Page#evaluate * Page.evaluate()}: *

{@code
-   * 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();
    * }
@@ -5808,6 +5808,18 @@ default boolean isVisible(String selector) { * @since v1.59 */ void clearPageErrors(); + /** + * Provides access to the page's {@code localStorage} for the current origin. See {@code WebStorage}. + * + * @since v1.61 + */ + WebStorage localStorage(); + /** + * Provides access to the page's {@code sessionStorage} for the current origin. See {@code WebStorage}. + * + * @since v1.61 + */ + WebStorage sessionStorage(); /** * Returns up to (currently) 200 last console messages from this page. See {@link * com.microsoft.playwright.Page#onConsoleMessage Page.onConsoleMessage()} for more details. @@ -7552,8 +7564,8 @@ default String ariaSnapshot() { *

When all steps combined have not finished during the specified {@code timeout}, this method throws a {@code * TimeoutError}. Passing zero timeout disables this. * - *

NOTE: {@link com.microsoft.playwright.Page#tap Page.tap()} the method will throw if {@code hasTouch} option of the browser - * context is false. + *

NOTE: {@link com.microsoft.playwright.Page#tap Page.tap()} will throw if the {@code hasTouch} option of the browser context is + * false. * * @param selector A selector to search for an element. If there are multiple elements satisfying the selector, the first will be used. * @since v1.8 @@ -7575,8 +7587,8 @@ default void tap(String selector) { *

When all steps combined have not finished during the specified {@code timeout}, this method throws a {@code * TimeoutError}. Passing zero timeout disables this. * - *

NOTE: {@link com.microsoft.playwright.Page#tap Page.tap()} the method will throw if {@code hasTouch} option of the browser - * context is false. + *

NOTE: {@link com.microsoft.playwright.Page#tap Page.tap()} will throw if the {@code hasTouch} option of the browser context is + * false. * * @param selector A selector to search for an element. If there are multiple elements satisfying the selector, the first will be used. * @since v1.8 diff --git a/playwright/src/main/java/com/microsoft/playwright/Screencast.java b/playwright/src/main/java/com/microsoft/playwright/Screencast.java index 0c0122ccd..ea545e1a9 100644 --- a/playwright/src/main/java/com/microsoft/playwright/Screencast.java +++ b/playwright/src/main/java/com/microsoft/playwright/Screencast.java @@ -38,6 +38,13 @@ class StartOptions { * The quality of the image, between 0-100. */ public Integer quality; + /** + * Specifies the dimensions of screencast frames. The actual frame is scaled to preserve the page's aspect ratio and may be + * smaller than these bounds. If a screencast is already active (e.g. started by tracing or video recording), the existing + * configuration takes precedence and the frame size may exceed these bounds or this option may be ignored. If not + * specified the size will be equal to page viewport scaled down to fit into 800×800. + */ + public Size size; /** * Callback that receives JPEG-encoded frame data along with the page viewport size at the time of capture. @@ -60,6 +67,25 @@ public StartOptions setQuality(int quality) { this.quality = quality; return this; } + /** + * Specifies the dimensions of screencast frames. The actual frame is scaled to preserve the page's aspect ratio and may be + * smaller than these bounds. If a screencast is already active (e.g. started by tracing or video recording), the existing + * configuration takes precedence and the frame size may exceed these bounds or this option may be ignored. If not + * specified the size will be equal to page viewport scaled down to fit into 800×800. + */ + public StartOptions setSize(int width, int height) { + return setSize(new Size(width, height)); + } + /** + * Specifies the dimensions of screencast frames. The actual frame is scaled to preserve the page's aspect ratio and may be + * smaller than these bounds. If a screencast is already active (e.g. started by tracing or video recording), the existing + * configuration takes precedence and the frame size may exceed these bounds or this option may be ignored. If not + * specified the size will be equal to page viewport scaled down to fit into 800×800. + */ + public StartOptions setSize(Size size) { + this.size = size; + return this; + } } class ShowOverlayOptions { /** @@ -103,6 +129,11 @@ public ShowChapterOptions setDuration(double duration) { } } class ShowActionsOptions { + /** + * Cursor decoration shown for pointer actions. {@code "pointer"} (the default) renders a mouse pointer that animates from + * the previous action point to the next one. {@code "none"} disables the cursor decoration. + */ + public ScreencastCursor cursor; /** * How long each annotation is displayed in milliseconds. Defaults to {@code 500}. */ @@ -116,6 +147,14 @@ class ShowActionsOptions { */ public AnnotatePosition position; + /** + * Cursor decoration shown for pointer actions. {@code "pointer"} (the default) renders a mouse pointer that animates from + * the previous action point to the next one. {@code "none"} disables the cursor decoration. + */ + public ShowActionsOptions setCursor(ScreencastCursor cursor) { + this.cursor = cursor; + return this; + } /** * How long each annotation is displayed in milliseconds. Defaults to {@code 500}. */ diff --git a/playwright/src/main/java/com/microsoft/playwright/ScreencastFrame.java b/playwright/src/main/java/com/microsoft/playwright/ScreencastFrame.java index ee4056ca5..8a690792b 100644 --- a/playwright/src/main/java/com/microsoft/playwright/ScreencastFrame.java +++ b/playwright/src/main/java/com/microsoft/playwright/ScreencastFrame.java @@ -22,6 +22,11 @@ public interface ScreencastFrame { */ byte[] data(); + /** + * The timestamp of when the frame was presented by the browser, in milliseconds since the Unix epoch. + */ + double timestamp(); + /** * Width of the page viewport at the time the frame was captured. */ diff --git a/playwright/src/main/java/com/microsoft/playwright/Selectors.java b/playwright/src/main/java/com/microsoft/playwright/Selectors.java index 1bc0fe47a..465de6f37 100644 --- a/playwright/src/main/java/com/microsoft/playwright/Selectors.java +++ b/playwright/src/main/java/com/microsoft/playwright/Selectors.java @@ -201,7 +201,8 @@ default void register(String name, Path script) { * Defines custom attribute name to be used in {@link com.microsoft.playwright.Page#getByTestId Page.getByTestId()}. {@code * data-testid} is used by default. * - * @param attributeName Test id attribute name. + * @param attributeName Test id attribute name. To match elements with any of several attributes, pass them as a comma-separated list, e.g. + * {@code "data-pw,data-ti"}. * @since v1.27 */ void setTestIdAttribute(String attributeName); diff --git a/playwright/src/main/java/com/microsoft/playwright/Touchscreen.java b/playwright/src/main/java/com/microsoft/playwright/Touchscreen.java index 2024016c1..c90dbb435 100644 --- a/playwright/src/main/java/com/microsoft/playwright/Touchscreen.java +++ b/playwright/src/main/java/com/microsoft/playwright/Touchscreen.java @@ -28,8 +28,8 @@ public interface Touchscreen { /** * Dispatches a {@code touchstart} and {@code touchend} event with a single touch at the position ({@code x},{@code y}). * - *

NOTE: {@link com.microsoft.playwright.Page#tap Page.tap()} the method will throw if {@code hasTouch} option of the browser - * context is false. + *

NOTE: {@link com.microsoft.playwright.Touchscreen#tap Touchscreen.tap()} will throw if the {@code hasTouch} option of the + * browser context is false. * * @param x X coordinate relative to the main frame's viewport in CSS pixels. * @param y Y coordinate relative to the main frame's viewport in CSS pixels. diff --git a/playwright/src/main/java/com/microsoft/playwright/WebStorage.java b/playwright/src/main/java/com/microsoft/playwright/WebStorage.java new file mode 100644 index 000000000..d141c09c0 --- /dev/null +++ b/playwright/src/main/java/com/microsoft/playwright/WebStorage.java @@ -0,0 +1,73 @@ +/* + * Copyright (c) Microsoft Corporation. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.microsoft.playwright; + +import com.microsoft.playwright.options.*; +import java.util.*; + +/** + * WebStorage exposes the page's {@code localStorage} or {@code sessionStorage} for the current origin via an async, browser-consistent API. + * + *

Instances are accessed through {@link com.microsoft.playwright.Page#localStorage Page.localStorage()} and {@link + * com.microsoft.playwright.Page#sessionStorage Page.sessionStorage()}. + *

{@code
+ * page.navigate("https://example.com");
+ * page.localStorage().setItem("token", "abc");
+ * String token = page.localStorage().getItem("token");
+ * List all = page.localStorage().items();
+ * page.localStorage().removeItem("token");
+ * page.localStorage().clear();
+ * }
+ */ +public interface WebStorage { + /** + * Returns all items in the storage as name/value pairs. + * + * @since v1.61 + */ + List items(); + /** + * Returns the value for the given {@code name} if present. + * + * @param name Name of the item to retrieve. + * @since v1.61 + */ + String getItem(String name); + /** + * Sets the value for the given {@code name}. Overwrites any existing value for that name. + * + * @param name Name of the item to set. + * @param value New value for the item. + * @since v1.61 + */ + void setItem(String name, String value); + /** + * Removes the item with the given {@code name}. No-op if the item is absent. + * + * @param name Name of the item to remove. + * @since v1.61 + */ + void removeItem(String name); + /** + * Removes all items from the storage. + * + * @since v1.61 + */ + void clear(); +} + diff --git a/playwright/src/main/java/com/microsoft/playwright/impl/APIResponseImpl.java b/playwright/src/main/java/com/microsoft/playwright/impl/APIResponseImpl.java index 771fb3658..385aca2c8 100644 --- a/playwright/src/main/java/com/microsoft/playwright/impl/APIResponseImpl.java +++ b/playwright/src/main/java/com/microsoft/playwright/impl/APIResponseImpl.java @@ -22,6 +22,8 @@ import com.microsoft.playwright.APIResponse; import com.microsoft.playwright.PlaywrightException; import com.microsoft.playwright.options.HttpHeader; +import com.microsoft.playwright.options.SecurityDetails; +import com.microsoft.playwright.options.ServerAddr; import java.nio.charset.StandardCharsets; import java.util.Base64; @@ -85,6 +87,22 @@ public boolean ok() { return status == 0 || (status >= 200 && status <= 299); } + @Override + public SecurityDetails securityDetails() { + if (!initializer.has("securityDetails")) { + return null; + } + return gson().fromJson(initializer.get("securityDetails"), SecurityDetails.class); + } + + @Override + public ServerAddr serverAddr() { + if (!initializer.has("serverAddr")) { + return null; + } + return gson().fromJson(initializer.get("serverAddr"), ServerAddr.class); + } + @Override public int status() { return initializer.get("status").getAsInt(); diff --git a/playwright/src/main/java/com/microsoft/playwright/impl/BrowserContextImpl.java b/playwright/src/main/java/com/microsoft/playwright/impl/BrowserContextImpl.java index daaed20bd..78c63f897 100644 --- a/playwright/src/main/java/com/microsoft/playwright/impl/BrowserContextImpl.java +++ b/playwright/src/main/java/com/microsoft/playwright/impl/BrowserContextImpl.java @@ -46,6 +46,7 @@ class BrowserContextImpl extends ChannelOwner implements BrowserContext { private final DebuggerImpl debugger; private final APIRequestContextImpl request; private final ClockImpl clock; + private final CredentialsImpl credentials; final List pages = new ArrayList<>(); final Router routes = new Router(); @@ -94,6 +95,7 @@ enum EventType { request = connection.getExistingObject(initializer.getAsJsonObject("requestContext").get("guid").getAsString()); request.timeoutSettings = timeoutSettings; clock = new ClockImpl(this); + credentials = new CredentialsImpl(this); closePromise = new WaitableEvent<>(listeners, EventType.CLOSE); } @@ -313,6 +315,11 @@ public ClockImpl clock() { return clock; } + @Override + public Credentials credentials() { + return credentials; + } + private T waitForEventWithTimeout(EventType eventType, Runnable code, Predicate predicate, Double timeout) { List> waitables = new ArrayList<>(); waitables.add(new WaitableEvent<>(listeners, eventType, predicate)); diff --git a/playwright/src/main/java/com/microsoft/playwright/impl/BrowserTypeImpl.java b/playwright/src/main/java/com/microsoft/playwright/impl/BrowserTypeImpl.java index d68d80cac..03efeab7c 100644 --- a/playwright/src/main/java/com/microsoft/playwright/impl/BrowserTypeImpl.java +++ b/playwright/src/main/java/com/microsoft/playwright/impl/BrowserTypeImpl.java @@ -112,8 +112,8 @@ public Browser connect(String wsEndpoint, ConnectOptions options) { @Override public Browser connectOverCDP(String endpointURL, ConnectOverCDPOptions options) { - if (!"chromium".equals(name())) { - throw new PlaywrightException("Connecting over CDP is only supported in Chromium."); + if (!"chromium".equals(name()) && !"webkit".equals(name())) { + throw new PlaywrightException("Connecting over CDP is only supported in Chromium and WebKit."); } if (options == null) { options = new ConnectOverCDPOptions(); diff --git a/playwright/src/main/java/com/microsoft/playwright/impl/ChannelOwner.java b/playwright/src/main/java/com/microsoft/playwright/impl/ChannelOwner.java index ce68ad523..8d7973227 100644 --- a/playwright/src/main/java/com/microsoft/playwright/impl/ChannelOwner.java +++ b/playwright/src/main/java/com/microsoft/playwright/impl/ChannelOwner.java @@ -110,6 +110,15 @@ WaitableResult sendMessageAsync(String method, JsonObject params) { return connection.sendMessageAsync(guid, method, params); } + // Fire-and-forget: the server intentionally never replies to this message, + // so silently drop it if the object was collected. + void sendMessageNoReply(String method, JsonObject params) { + if (wasCollected) { + return; + } + connection.sendMessageNoReply(guid, method, params); + } + JsonElement sendMessage(String method) { return sendMessage(method, new JsonObject(), NO_TIMEOUT); } diff --git a/playwright/src/main/java/com/microsoft/playwright/impl/Connection.java b/playwright/src/main/java/com/microsoft/playwright/impl/Connection.java index 0a7cbe540..369daf68a 100644 --- a/playwright/src/main/java/com/microsoft/playwright/impl/Connection.java +++ b/playwright/src/main/java/com/microsoft/playwright/impl/Connection.java @@ -39,6 +39,7 @@ class Message { JsonObject params; JsonElement result; SerializedError error; + JsonObject errorDetails; JsonArray log; @Override @@ -132,13 +133,20 @@ public JsonElement sendMessage(String guid, String method, JsonObject params) { } public WaitableResult sendMessageAsync(String guid, String method, JsonObject params) { - return internalSendMessage(guid, method, params, true); + return internalSendMessage(guid, method, params, true, true); } - private WaitableResult internalSendMessage(String guid, String method, JsonObject params, boolean sendStack) { + // Fire-and-forget: the server intentionally never replies to this message. + public void sendMessageNoReply(String guid, String method, JsonObject params) { + internalSendMessage(guid, method, params, false, false); + } + + private WaitableResult internalSendMessage(String guid, String method, JsonObject params, boolean sendStack, boolean expectsReply) { int id = ++lastId; WaitableResult result = new WaitableResult<>(); - callbacks.put(id, result); + if (expectsReply) { + callbacks.put(id, result); + } JsonObject message = new JsonObject(); message.addProperty("id", id); message.addProperty("guid", guid); @@ -175,7 +183,7 @@ private WaitableResult internalSendMessage(String guid, String meth callData.add("stack", stack); JsonObject stackParams = new JsonObject(); stackParams.add("callData", callData); - internalSendMessage(localUtils.guid,"addStackToTracingNoReply", stackParams, false); + internalSendMessage(localUtils.guid,"addStackToTracingNoReply", stackParams, false, true); } return result; } @@ -251,16 +259,22 @@ private void dispatch(Message message) { callback.complete(message.result); } else { String callLog = formatCallLog(message.log); + PlaywrightException exception; if (message.error.error == null) { - callback.completeExceptionally(new PlaywrightException(message.error + callLog)); + exception = new PlaywrightException(message.error + callLog); } else if ("TimeoutError".equals(message.error.error.name)) { - callback.completeExceptionally(new TimeoutError(message.error.error + callLog)); + exception = new TimeoutError(message.error.error + callLog); } else if ("TargetClosedError".equals(message.error.error.name)) { - callback.completeExceptionally(new TargetClosedError(message.error.error + callLog)); - + exception = new TargetClosedError(message.error.error + callLog); } else { - callback.completeExceptionally(new DriverException(message.error.error + callLog)); + exception = new DriverException(message.error.error + callLog); + } + // The server attaches errorDetails to errors of the methods that declare them + // in the protocol (currently only Frame.expect and Page.expectScreenshot). + if (message.errorDetails != null) { + exception = new ServerErrorWithDetails(exception, message.errorDetails, message.log); } + callback.completeExceptionally(exception); } return; } diff --git a/playwright/src/main/java/com/microsoft/playwright/impl/CredentialsImpl.java b/playwright/src/main/java/com/microsoft/playwright/impl/CredentialsImpl.java new file mode 100644 index 000000000..aa68f4a7d --- /dev/null +++ b/playwright/src/main/java/com/microsoft/playwright/impl/CredentialsImpl.java @@ -0,0 +1,62 @@ +/* + * Copyright (c) Microsoft Corporation. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.microsoft.playwright.impl; + +import com.google.gson.JsonObject; +import com.microsoft.playwright.Credentials; +import com.microsoft.playwright.options.VirtualCredential; + +import java.util.List; + +import static com.microsoft.playwright.impl.ChannelOwner.NO_TIMEOUT; +import static com.microsoft.playwright.impl.Serialization.gson; +import static java.util.Arrays.asList; + +class CredentialsImpl implements Credentials { + private final BrowserContextImpl context; + + CredentialsImpl(BrowserContextImpl context) { + this.context = context; + } + + @Override + public void install() { + context.sendMessage("credentialsInstall", new JsonObject(), NO_TIMEOUT); + } + + @Override + public VirtualCredential create(String rpId, CreateOptions options) { + JsonObject params = options == null ? new JsonObject() : gson().toJsonTree(options).getAsJsonObject(); + params.addProperty("rpId", rpId); + JsonObject json = context.sendMessage("credentialsCreate", params, NO_TIMEOUT).getAsJsonObject(); + return gson().fromJson(json.get("credential"), VirtualCredential.class); + } + + @Override + public void delete(String id) { + JsonObject params = new JsonObject(); + params.addProperty("id", id); + context.sendMessage("credentialsDelete", params, NO_TIMEOUT); + } + + @Override + public List get(GetOptions options) { + JsonObject params = options == null ? new JsonObject() : gson().toJsonTree(options).getAsJsonObject(); + JsonObject json = context.sendMessage("credentialsGet", params, NO_TIMEOUT).getAsJsonObject(); + return asList(gson().fromJson(json.getAsJsonArray("credentials"), VirtualCredential[].class)); + } +} diff --git a/playwright/src/main/java/com/microsoft/playwright/impl/FrameImpl.java b/playwright/src/main/java/com/microsoft/playwright/impl/FrameImpl.java index 25f45bba9..9a94fdf86 100644 --- a/playwright/src/main/java/com/microsoft/playwright/impl/FrameImpl.java +++ b/playwright/src/main/java/com/microsoft/playwright/impl/FrameImpl.java @@ -1154,8 +1154,17 @@ FrameExpectResult expect(String expression, FrameExpectOptions options, String t FrameExpectResult expect(String expression, FrameExpectOptions options) { JsonObject params = gson().toJsonTree(options).getAsJsonObject(); params.addProperty("expression", expression); - JsonElement json = sendMessage("expect", params, options.timeout); - FrameExpectResult result = gson().fromJson(json, FrameExpectResult.class); + FrameExpectResult result = new FrameExpectResult(); + try { + sendMessage("expect", params, options.timeout); + result.matches = !options.isNot; + } catch (ServerErrorWithDetails e) { + FrameExpectErrorDetails details = gson().fromJson(e.errorDetails(), FrameExpectErrorDetails.class); + result.matches = options.isNot; + result.received = details.received; + result.errorMessage = details.customErrorMessage == null ? null : "Error: " + details.customErrorMessage; + result.log = e.log(); + } return result; } } diff --git a/playwright/src/main/java/com/microsoft/playwright/impl/LocatorUtils.java b/playwright/src/main/java/com/microsoft/playwright/impl/LocatorUtils.java index 1bbe68a5c..8d9c025cd 100644 --- a/playwright/src/main/java/com/microsoft/playwright/impl/LocatorUtils.java +++ b/playwright/src/main/java/com/microsoft/playwright/impl/LocatorUtils.java @@ -43,8 +43,14 @@ static String describeSelector(String description) { return "internal:describe=" + gson().toJson(description); } + // Multiple test id attribute names can be joined with a comma. Attribute names cannot contain commas. + private static String encodeTestIdAttributeName(String testIdAttributeName) { + return testIdAttributeName.contains(",") ? gson().toJson(testIdAttributeName) : testIdAttributeName; + } + static String getByTestIdSelector(Object testId, PlaywrightImpl playwright) { - return getByAttributeTextSelector(playwright.selectors.testIdAttributeName, testId, true); + String attributeName = encodeTestIdAttributeName(playwright.selectors.testIdAttributeName); + return "internal:testid=[" + attributeName + "=" + escapeForAttributeSelector(testId, true) + "]"; } static String getByAltTextSelector(Object text, Locator.GetByAltTextOptions options) { diff --git a/playwright/src/main/java/com/microsoft/playwright/impl/PageImpl.java b/playwright/src/main/java/com/microsoft/playwright/impl/PageImpl.java index 19d7b3839..4956ea623 100644 --- a/playwright/src/main/java/com/microsoft/playwright/impl/PageImpl.java +++ b/playwright/src/main/java/com/microsoft/playwright/impl/PageImpl.java @@ -47,6 +47,8 @@ public class PageImpl extends ChannelOwner implements Page { private final MouseImpl mouse; private final TouchscreenImpl touchscreen; private final ScreencastImpl screencast; + private final WebStorageImpl localStorage; + private final WebStorageImpl sessionStorage; final Waitable waitableClosedOrCrashed; private ViewportSize viewport; private final Router routes = new Router(); @@ -137,6 +139,8 @@ enum EventType { mouse = new MouseImpl(this); touchscreen = new TouchscreenImpl(this); screencast = new ScreencastImpl(this); + localStorage = new WebStorageImpl(this, "local"); + sessionStorage = new WebStorageImpl(this, "session"); frames.add(mainFrame); timeoutSettings = new TimeoutSettings(browserContext.timeoutSettings); waitableClosedOrCrashed = createWaitForCloseHelper(); @@ -555,8 +559,13 @@ public void close(CloseOptions options) { try { if (ownedContext != null) { ownedContext.close(); + } else if (options.runBeforeUnload != null && options.runBeforeUnload) { + sendMessage("runBeforeUnload", new JsonObject(), NO_TIMEOUT); } else { - JsonObject params = gson().toJsonTree(options).getAsJsonObject(); + JsonObject params = new JsonObject(); + if (options.reason != null) { + params.addProperty("reason", options.reason); + } sendMessage("close", params, NO_TIMEOUT); } } catch (PlaywrightException exception) { @@ -1362,6 +1371,16 @@ public Screencast screencast() { return screencast; } + @Override + public WebStorage localStorage() { + return localStorage; + } + + @Override + public WebStorage sessionStorage() { + return sessionStorage; + } + @Override public void type(String selector, String text, TypeOptions options) { mainFrame.type(selector, text, convertType(options, Frame.TypeOptions.class)); diff --git a/playwright/src/main/java/com/microsoft/playwright/impl/Protocol.java b/playwright/src/main/java/com/microsoft/playwright/impl/Protocol.java index 2983d1cfe..02d93bb2f 100644 --- a/playwright/src/main/java/com/microsoft/playwright/impl/Protocol.java +++ b/playwright/src/main/java/com/microsoft/playwright/impl/Protocol.java @@ -122,4 +122,11 @@ static class Received { List log; } +// Sent by the server as `errorDetails` when Frame.expect fails. +class FrameExpectErrorDetails { + FrameExpectResult.Received received; + Boolean timedOut; + String customErrorMessage; +} + diff --git a/playwright/src/main/java/com/microsoft/playwright/impl/ScreencastFrameImpl.java b/playwright/src/main/java/com/microsoft/playwright/impl/ScreencastFrameImpl.java index d12513dbf..e70b5d51a 100644 --- a/playwright/src/main/java/com/microsoft/playwright/impl/ScreencastFrameImpl.java +++ b/playwright/src/main/java/com/microsoft/playwright/impl/ScreencastFrameImpl.java @@ -20,11 +20,13 @@ class ScreencastFrameImpl implements ScreencastFrame { private final byte[] data; + private final double timestamp; private final int viewportWidth; private final int viewportHeight; - ScreencastFrameImpl(byte[] data, int viewportWidth, int viewportHeight) { + ScreencastFrameImpl(byte[] data, double timestamp, int viewportWidth, int viewportHeight) { this.data = data; + this.timestamp = timestamp; this.viewportWidth = viewportWidth; this.viewportHeight = viewportHeight; } @@ -34,6 +36,11 @@ public byte[] data() { return data; } + @Override + public double timestamp() { + return timestamp; + } + @Override public int viewportWidth() { return viewportWidth; diff --git a/playwright/src/main/java/com/microsoft/playwright/impl/ScreencastImpl.java b/playwright/src/main/java/com/microsoft/playwright/impl/ScreencastImpl.java index 2e3a9cb56..a9d80aab0 100644 --- a/playwright/src/main/java/com/microsoft/playwright/impl/ScreencastImpl.java +++ b/playwright/src/main/java/com/microsoft/playwright/impl/ScreencastImpl.java @@ -44,9 +44,10 @@ void handleScreencastFrame(JsonObject params) { } String dataBase64 = params.get("data").getAsString(); byte[] data = java.util.Base64.getDecoder().decode(dataBase64); + double timestamp = params.get("timestamp").getAsDouble(); int viewportWidth = params.get("viewportWidth").getAsInt(); int viewportHeight = params.get("viewportHeight").getAsInt(); - onFrame.accept(new ScreencastFrameImpl(data, viewportWidth, viewportHeight)); + onFrame.accept(new ScreencastFrameImpl(data, timestamp, viewportWidth, viewportHeight)); } @Override diff --git a/playwright/src/main/java/com/microsoft/playwright/impl/ServerErrorWithDetails.java b/playwright/src/main/java/com/microsoft/playwright/impl/ServerErrorWithDetails.java new file mode 100644 index 000000000..edaa64b70 --- /dev/null +++ b/playwright/src/main/java/com/microsoft/playwright/impl/ServerErrorWithDetails.java @@ -0,0 +1,58 @@ +/* + * Copyright (c) Microsoft Corporation. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.microsoft.playwright.impl; + +import com.google.gson.JsonArray; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import com.microsoft.playwright.PlaywrightException; + +import java.util.ArrayList; +import java.util.List; + +// Server error with the structured details declared in the protocol for the failed method. +class ServerErrorWithDetails extends PlaywrightException { + private final JsonObject errorDetails; + private final JsonArray log; + + ServerErrorWithDetails(PlaywrightException cause, JsonObject errorDetails, JsonArray log) { + super(cause.getMessage(), cause); + this.errorDetails = errorDetails; + this.log = log; + } + + // Used to rethrow with the stack trace of the calling thread, see WaitableResult.get(). + ServerErrorWithDetails(ServerErrorWithDetails cause) { + super(cause.getMessage(), cause); + this.errorDetails = cause.errorDetails; + this.log = cause.log; + } + + JsonObject errorDetails() { + return errorDetails; + } + + List log() { + List result = new ArrayList<>(); + if (log != null) { + for (JsonElement e : log) { + result.add(e.getAsString()); + } + } + return result; + } +} diff --git a/playwright/src/main/java/com/microsoft/playwright/impl/WaitForEventLogger.java b/playwright/src/main/java/com/microsoft/playwright/impl/WaitForEventLogger.java index 26216d5fa..125af1a51 100644 --- a/playwright/src/main/java/com/microsoft/playwright/impl/WaitForEventLogger.java +++ b/playwright/src/main/java/com/microsoft/playwright/impl/WaitForEventLogger.java @@ -41,7 +41,8 @@ public T get() { { JsonObject info = new JsonObject(); info.addProperty("phase", "before"); - sendWaitForEventInfo(info); + info.addProperty("event", ""); + sendWaitInfo(info); } JsonObject info = new JsonObject(); info.addProperty("phase", "after"); @@ -51,7 +52,7 @@ public T get() { info.addProperty("error", e.getMessage()); throw e; } finally { - sendWaitForEventInfo(info); + sendWaitInfo(info); } } @@ -61,14 +62,15 @@ public void log(String message) { JsonObject info = new JsonObject(); info.addProperty("phase", "log"); info.addProperty("message", message); - sendWaitForEventInfo(info); + sendWaitInfo(info); } - private void sendWaitForEventInfo(JsonObject info) { - info.addProperty("event", ""); + private void sendWaitInfo(JsonObject info) { info.addProperty("waitId", waitId); - JsonObject params = new JsonObject(); - params.add("info", info); - channel.sendMessageAsync("waitForEventInfo", params); + try { + channel.sendMessageNoReply("__waitInfo__", info); + } catch (RuntimeException e) { + // Fire-and-forget: never throw to the caller. + } } } diff --git a/playwright/src/main/java/com/microsoft/playwright/impl/WaitableResult.java b/playwright/src/main/java/com/microsoft/playwright/impl/WaitableResult.java index 831874dbf..76cf50034 100644 --- a/playwright/src/main/java/com/microsoft/playwright/impl/WaitableResult.java +++ b/playwright/src/main/java/com/microsoft/playwright/impl/WaitableResult.java @@ -52,6 +52,8 @@ public T get() { throw new TimeoutError(exception.getMessage(), exception); } if (exception instanceof TargetClosedError) { throw new TargetClosedError(exception.getMessage(), exception); + } if (exception instanceof ServerErrorWithDetails) { + throw new ServerErrorWithDetails((ServerErrorWithDetails) exception); } throw new PlaywrightException(exception.getMessage(), exception); } diff --git a/playwright/src/main/java/com/microsoft/playwright/impl/WebStorageImpl.java b/playwright/src/main/java/com/microsoft/playwright/impl/WebStorageImpl.java new file mode 100644 index 000000000..96d507d6e --- /dev/null +++ b/playwright/src/main/java/com/microsoft/playwright/impl/WebStorageImpl.java @@ -0,0 +1,77 @@ +/* + * Copyright (c) Microsoft Corporation. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.microsoft.playwright.impl; + +import com.google.gson.JsonObject; +import com.microsoft.playwright.WebStorage; +import com.microsoft.playwright.options.WebStorageItem; + +import java.util.List; + +import static com.microsoft.playwright.impl.ChannelOwner.NO_TIMEOUT; +import static com.microsoft.playwright.impl.Serialization.gson; +import static java.util.Arrays.asList; + +class WebStorageImpl implements WebStorage { + private final PageImpl page; + private final String kind; + + WebStorageImpl(PageImpl page, String kind) { + this.page = page; + this.kind = kind; + } + + private JsonObject createParams() { + JsonObject params = new JsonObject(); + params.addProperty("kind", kind); + return params; + } + + @Override + public List items() { + JsonObject json = page.sendMessage("webStorageItems", createParams(), NO_TIMEOUT).getAsJsonObject(); + return asList(gson().fromJson(json.getAsJsonArray("items"), WebStorageItem[].class)); + } + + @Override + public String getItem(String name) { + JsonObject params = createParams(); + params.addProperty("name", name); + JsonObject json = page.sendMessage("webStorageGetItem", params, NO_TIMEOUT).getAsJsonObject(); + return json.has("value") ? json.get("value").getAsString() : null; + } + + @Override + public void setItem(String name, String value) { + JsonObject params = createParams(); + params.addProperty("name", name); + params.addProperty("value", value); + page.sendMessage("webStorageSetItem", params, NO_TIMEOUT); + } + + @Override + public void removeItem(String name) { + JsonObject params = createParams(); + params.addProperty("name", name); + page.sendMessage("webStorageRemoveItem", params, NO_TIMEOUT); + } + + @Override + public void clear() { + page.sendMessage("webStorageClear", createParams(), NO_TIMEOUT); + } +} diff --git a/playwright/src/main/java/com/microsoft/playwright/options/ScreencastCursor.java b/playwright/src/main/java/com/microsoft/playwright/options/ScreencastCursor.java new file mode 100644 index 000000000..0e09c1ef0 --- /dev/null +++ b/playwright/src/main/java/com/microsoft/playwright/options/ScreencastCursor.java @@ -0,0 +1,22 @@ +/* + * Copyright (c) Microsoft Corporation. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.microsoft.playwright.options; + +public enum ScreencastCursor { + NONE, + POINTER +} \ No newline at end of file diff --git a/playwright/src/main/java/com/microsoft/playwright/options/Size.java b/playwright/src/main/java/com/microsoft/playwright/options/Size.java index 6955e1686..fb9ac7d8a 100644 --- a/playwright/src/main/java/com/microsoft/playwright/options/Size.java +++ b/playwright/src/main/java/com/microsoft/playwright/options/Size.java @@ -18,11 +18,11 @@ public class Size { /** - * Video frame width. + * Max frame width in pixels. */ public int width; /** - * Video frame height. + * Max frame height in pixels. */ public int height; diff --git a/playwright/src/main/java/com/microsoft/playwright/options/VirtualCredential.java b/playwright/src/main/java/com/microsoft/playwright/options/VirtualCredential.java new file mode 100644 index 000000000..06a7f74ca --- /dev/null +++ b/playwright/src/main/java/com/microsoft/playwright/options/VirtualCredential.java @@ -0,0 +1,41 @@ +/* + * Copyright (c) Microsoft Corporation. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.microsoft.playwright.options; + +public class VirtualCredential { + /** + * Base64url-encoded credential id. + */ + public String id; + /** + * Relying party id. + */ + public String rpId; + /** + * Base64url-encoded user handle. + */ + public String userHandle; + /** + * Base64url-encoded PKCS#8 (DER) private key. + */ + public String privateKey; + /** + * Base64url-encoded SPKI (DER) public key. + */ + public String publicKey; + +} \ No newline at end of file diff --git a/playwright/src/main/java/com/microsoft/playwright/options/WebStorageItem.java b/playwright/src/main/java/com/microsoft/playwright/options/WebStorageItem.java new file mode 100644 index 000000000..0b95002fc --- /dev/null +++ b/playwright/src/main/java/com/microsoft/playwright/options/WebStorageItem.java @@ -0,0 +1,23 @@ +/* + * Copyright (c) Microsoft Corporation. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.microsoft.playwright.options; + +public class WebStorageItem { + public String name; + public String value; + +} \ No newline at end of file diff --git a/playwright/src/test/java/com/microsoft/playwright/TestBrowserContextFetch.java b/playwright/src/test/java/com/microsoft/playwright/TestBrowserContextFetch.java index d7352c748..9f487a2f3 100644 --- a/playwright/src/test/java/com/microsoft/playwright/TestBrowserContextFetch.java +++ b/playwright/src/test/java/com/microsoft/playwright/TestBrowserContextFetch.java @@ -741,10 +741,12 @@ void shouldAbortRequestsWhenBrowserContextCloses() { }); page.evaluate("() => setTimeout(closeContext, 1000);"); PlaywrightException e = assertThrows(PlaywrightException.class, () -> context.request().get(server.EMPTY_PAGE)); - assertTrue(e.getMessage().contains("Target page, context or browser has been closed"), e.getMessage()); + assertTrue(e.getMessage().contains("Request context disposed") || + e.getMessage().contains("Target page, context or browser has been closed"), e.getMessage()); e = assertThrows(PlaywrightException.class, () -> context.request().post(server.EMPTY_PAGE)); - assertTrue(e.getMessage().contains("Target page, context or browser has been closed"), e.getMessage()); + assertTrue(e.getMessage().contains("Request context disposed") || + e.getMessage().contains("Target page, context or browser has been closed"), e.getMessage()); } @Test diff --git a/playwright/src/test/java/com/microsoft/playwright/TestBrowserContextWebAuthn.java b/playwright/src/test/java/com/microsoft/playwright/TestBrowserContextWebAuthn.java new file mode 100644 index 000000000..20b0a39e3 --- /dev/null +++ b/playwright/src/test/java/com/microsoft/playwright/TestBrowserContextWebAuthn.java @@ -0,0 +1,179 @@ +/* + * Copyright (c) Microsoft Corporation. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.microsoft.playwright; + +import com.microsoft.playwright.options.VirtualCredential; +import org.junit.jupiter.api.Test; + +import java.util.List; +import java.util.Map; + +import static com.microsoft.playwright.Utils.mapOf; +import static org.junit.jupiter.api.Assertions.*; + +public class TestBrowserContextWebAuthn extends TestBase { + private static final String B64URL_TO_BYTES_JS = + " const b64UrlToBytes = s => {\n" + + " let str = s.replace(/-/g, '+').replace(/_/g, '/');\n" + + " while (str.length % 4)\n" + + " str += '=';\n" + + " const bin = atob(str);\n" + + " const u8 = new Uint8Array(bin.length);\n" + + " for (let i = 0; i < bin.length; i++)\n" + + " u8[i] = bin.charCodeAt(i);\n" + + " return u8;\n" + + " };\n"; + + @Test + void shouldNotInterceptNavigatorCredentialsWithoutInstall() { + // Seed a credential, but do not install the interceptor. + context.credentials().create("localhost"); + page.navigate(server.EMPTY_PAGE); + + Object intercepted = page.evaluate("() => globalThis.__pwWebAuthnInstalled === true"); + assertEquals(false, intercepted); + } + + @Test + void shouldSeedKnownCredentialAndAuthenticate() { + // This is the easiest way to create credentials. In practice, this + // probably comes from environment. + VirtualCredential known; + try (BrowserContext source = browser.newContext()) { + known = source.credentials().create("localhost"); + } + + // A fresh context imports the known credential and signs in with it. + context.credentials().create(known.rpId, new Credentials.CreateOptions() + .setId(known.id) + .setUserHandle(known.userHandle) + .setPrivateKey(known.privateKey) + .setPublicKey(known.publicKey)); + context.credentials().install(); + page.navigate(server.EMPTY_PAGE); + + Map result = (Map) page.evaluate( + "async ({ rpId, credentialId }) => {\n" + + B64URL_TO_BYTES_JS + + " const challenge = crypto.getRandomValues(new Uint8Array(32));\n" + + " const cred = await navigator.credentials.get({\n" + + " publicKey: {\n" + + " challenge,\n" + + " rpId,\n" + + " allowCredentials: [{ type: 'public-key', id: b64UrlToBytes(credentialId) }],\n" + + " userVerification: 'preferred',\n" + + " },\n" + + " });\n" + + " const resp = cred.response;\n" + + " return {\n" + + " id: cred.id,\n" + + " type: cred.type,\n" + + " hasClientData: resp.clientDataJSON.byteLength > 0,\n" + + " hasAuthData: resp.authenticatorData.byteLength > 0,\n" + + " hasSignature: resp.signature.byteLength > 0,\n" + + " authDataFlags: new Uint8Array(resp.authenticatorData)[32],\n" + + " };\n" + + "}", mapOf("rpId", "localhost", "credentialId", known.id)); + + assertEquals(known.id, result.get("id")); + assertEquals("public-key", result.get("type")); + assertEquals(true, result.get("hasClientData")); + assertEquals(true, result.get("hasAuthData")); + assertEquals(true, result.get("hasSignature")); + // UP (0x01) | UV (0x04) = 0x05 + assertEquals(0x05, ((Number) result.get("authDataFlags")).intValue() & 0x05); + + // After the credential is deleted, the page can no longer authenticate with it. + context.credentials().delete(known.id); + assertEquals(0, context.credentials().get().size()); + + Object error = page.evaluate( + "async ({ rpId, credentialId }) => {\n" + + B64URL_TO_BYTES_JS + + " const challenge = crypto.getRandomValues(new Uint8Array(32));\n" + + " try {\n" + + " await navigator.credentials.get({\n" + + " publicKey: {\n" + + " challenge,\n" + + " rpId,\n" + + " allowCredentials: [{ type: 'public-key', id: b64UrlToBytes(credentialId) }],\n" + + " },\n" + + " });\n" + + " return 'no-error';\n" + + " } catch (e) {\n" + + " return e.name;\n" + + " }\n" + + "}", mapOf("rpId", "localhost", "credentialId", known.id)); + assertEquals("NotAllowedError", error); + } + + @Test + void shouldCapturePageCreatedCredentialAndReuseItInAnotherContext() { + // Setup context: the app registers a passkey via navigator.credentials.create(). + String createdId; + VirtualCredential captured; + try (BrowserContext setupContext = browser.newContext()) { + setupContext.credentials().install(); + Page setupPage = setupContext.newPage(); + setupPage.navigate(server.EMPTY_PAGE); + + createdId = (String) setupPage.evaluate( + "async ({ rpId }) => {\n" + + " const challenge = crypto.getRandomValues(new Uint8Array(32));\n" + + " const created = await navigator.credentials.create({\n" + + " publicKey: {\n" + + " challenge,\n" + + " rp: { id: rpId, name: 'Test RP' },\n" + + " user: { id: new Uint8Array([1, 2, 3, 4]), name: 'u', displayName: 'User' },\n" + + " pubKeyCredParams: [{ type: 'public-key', alg: -7 }],\n" + + " authenticatorSelection: { residentKey: 'required', userVerification: 'preferred' },\n" + + " },\n" + + " });\n" + + " return created.id;\n" + + "}", mapOf("rpId", "localhost")); + + List credentials = setupContext.credentials().get( + new Credentials.GetOptions().setRpId("localhost")); + assertEquals(1, credentials.size()); + captured = credentials.get(0); + assertEquals(createdId, captured.id); + assertTrue(captured.privateKey.matches("^[A-Za-z0-9_-]+$"), captured.privateKey); + assertTrue(captured.publicKey.matches("^[A-Za-z0-9_-]+$"), captured.publicKey); + } + + // Reuse the captured passkey in a fresh context and sign in with it. + context.credentials().create(captured.rpId, new Credentials.CreateOptions() + .setId(captured.id) + .setUserHandle(captured.userHandle) + .setPrivateKey(captured.privateKey) + .setPublicKey(captured.publicKey)); + context.credentials().install(); + page.navigate(server.EMPTY_PAGE); + + Object gotId = page.evaluate( + "async ({ rpId }) => {\n" + + " const challenge = crypto.getRandomValues(new Uint8Array(32));\n" + + " // No allowCredentials — relies on the re-seeded credential being discoverable.\n" + + " const cred = await navigator.credentials.get({\n" + + " publicKey: { challenge, rpId, userVerification: 'preferred' },\n" + + " });\n" + + " return cred.id;\n" + + "}", mapOf("rpId", "localhost")); + + assertEquals(createdId, gotId); + } +} diff --git a/playwright/src/test/java/com/microsoft/playwright/TestBrowserTypeConnect.java b/playwright/src/test/java/com/microsoft/playwright/TestBrowserTypeConnect.java index 618a36604..098dea19d 100644 --- a/playwright/src/test/java/com/microsoft/playwright/TestBrowserTypeConnect.java +++ b/playwright/src/test/java/com/microsoft/playwright/TestBrowserTypeConnect.java @@ -259,7 +259,7 @@ void shouldThrowWhenCallingWaitForNavigationAfterDisconnect() throws Interrupted } assertFalse(browser.isConnected()); PlaywrightException e = assertThrows(PlaywrightException.class, () -> page.waitForNavigation(() -> {})); - assertTrue(e.getMessage().contains("Browser closed") || e.getMessage().contains("Page closed") || e.getMessage().contains("Browser has been closed"), e.getMessage()); + assertTrue(e.getMessage().contains("Target page, context or browser has been closed"), e.getMessage()); } @Test diff --git a/playwright/src/test/java/com/microsoft/playwright/TestGlobalFetch.java b/playwright/src/test/java/com/microsoft/playwright/TestGlobalFetch.java index ce9e21f48..37fc6e59f 100644 --- a/playwright/src/test/java/com/microsoft/playwright/TestGlobalFetch.java +++ b/playwright/src/test/java/com/microsoft/playwright/TestGlobalFetch.java @@ -22,6 +22,7 @@ import com.microsoft.playwright.options.HttpCredentialsSend; import com.microsoft.playwright.options.HttpHeader; import com.microsoft.playwright.options.RequestOptions; +import com.microsoft.playwright.options.ServerAddr; import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; @@ -252,6 +253,25 @@ void shouldPropagateIgnoreHTTPSErrorsOnRedirects() { assertEquals(200, response.status()); } + @Test + void shouldReturnServerAddressFromResponse() { + APIRequestContext request = playwright.request().newContext(); + APIResponse response = request.get(server.EMPTY_PAGE); + ServerAddr address = response.serverAddr(); + assertNotNull(address); + assertEquals(server.PORT, address.port); + assertTrue(asList("127.0.0.1", "::1").contains(address.ipAddress), address.ipAddress); + request.dispose(); + } + + @Test + void shouldReturnNullSecurityDetailsForHttpResponse() { + APIRequestContext request = playwright.request().newContext(); + APIResponse response = request.get(server.EMPTY_PAGE); + assertNull(response.securityDetails()); + request.dispose(); + } + @Test void shouldResolveUrlRelativeToGobalBaseURLOption() { APIRequestContext request = playwright.request().newContext(new APIRequest.NewContextOptions().setBaseURL(server.PREFIX)); diff --git a/playwright/src/test/java/com/microsoft/playwright/TestScreencast.java b/playwright/src/test/java/com/microsoft/playwright/TestScreencast.java index ecf0cce7c..2d81b3d47 100644 --- a/playwright/src/test/java/com/microsoft/playwright/TestScreencast.java +++ b/playwright/src/test/java/com/microsoft/playwright/TestScreencast.java @@ -122,12 +122,12 @@ void screencastStartShouldDeliverFramesViaOnFrame() throws Exception { } @Test - void onFrameShouldReceiveViewportSize() { + void onFrameShouldReceiveViewportSizeAndTimestamp() { BrowserContext context = browser.newContext(new Browser.NewContextOptions().setViewportSize(1000, 400)); Page page = context.newPage(); try { List frames = new ArrayList<>(); - page.screencast().start(new Screencast.StartOptions().setOnFrame(frames::add)); + page.screencast().start(new Screencast.StartOptions().setOnFrame(frames::add).setSize(500, 400)); page.navigate(server.EMPTY_PAGE); page.evaluate("() => document.body.style.backgroundColor = 'red'"); page.waitForTimeout(500); @@ -136,6 +136,7 @@ void onFrameShouldReceiveViewportSize() { for (ScreencastFrame frame : frames) { assertEquals(1000, frame.viewportWidth()); assertEquals(400, frame.viewportHeight()); + assertTrue(frame.timestamp() > 0, "expected a positive timestamp, got " + frame.timestamp()); } } finally { context.close(); diff --git a/playwright/src/test/java/com/microsoft/playwright/TestSelectorsGetBy.java b/playwright/src/test/java/com/microsoft/playwright/TestSelectorsGetBy.java index a04ace027..da1f729cf 100644 --- a/playwright/src/test/java/com/microsoft/playwright/TestSelectorsGetBy.java +++ b/playwright/src/test/java/com/microsoft/playwright/TestSelectorsGetBy.java @@ -51,6 +51,20 @@ void getByTestIdWithCustomTestIdShouldWork() { assertThat(page.locator("div").getByTestId("Hello")).hasText("Hello world"); } + @Test + void getByTestIdWithCommaSeparatedTestIdAttributesShouldMatchAny() { + page.setContent("
\n" + + "
first
\n" + + "
second
\n" + + "
third
\n" + + "
"); + playwright.selectors().setTestIdAttribute("data-pw,data-ti"); + assertThat(page.getByTestId("Hello")).hasCount(2); + assertThat(page.getByTestId("Hello")).hasText(new String[]{"first", "second"}); + assertThat(page.mainFrame().getByTestId("Hello")).hasCount(2); + assertThat(page.locator("section").getByTestId("Hello")).hasCount(2); + } + @Test void shouldUseDataTestidInStrictErrors() { playwright.selectors().setTestIdAttribute("data-custom-id"); diff --git a/playwright/src/test/java/com/microsoft/playwright/TestWebStorage.java b/playwright/src/test/java/com/microsoft/playwright/TestWebStorage.java new file mode 100644 index 000000000..98d1c6e17 --- /dev/null +++ b/playwright/src/test/java/com/microsoft/playwright/TestWebStorage.java @@ -0,0 +1,132 @@ +/* + * Copyright (c) Microsoft Corporation. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.microsoft.playwright; + +import com.microsoft.playwright.options.WebStorageItem; +import org.junit.jupiter.api.Test; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import static com.microsoft.playwright.Utils.mapOf; +import static org.junit.jupiter.api.Assertions.*; + +public class TestWebStorage extends TestBase { + private static Map asMap(List items) { + Map map = new HashMap<>(); + for (WebStorageItem item : items) { + map.put(item.name, item.value); + } + return map; + } + + @Test + void localStorageItemsReturnsEmptyListOnFreshOrigin() { + page.navigate(server.EMPTY_PAGE); + assertEquals(0, page.localStorage().items().size()); + } + + @Test + void localStorageGetItemReturnsNullForMissingKey() { + page.navigate(server.EMPTY_PAGE); + assertNull(page.localStorage().getItem("absent")); + } + + @Test + void localStorageSetItemPersistsAndSurfacesInItemsAndGetItem() { + page.navigate(server.EMPTY_PAGE); + page.localStorage().setItem("alpha", "1"); + page.localStorage().setItem("beta", "2"); + + assertEquals(mapOf("alpha", "1", "beta", "2"), asMap(page.localStorage().items())); + assertEquals("1", page.localStorage().getItem("alpha")); + assertEquals("1", page.evaluate("() => localStorage.getItem('alpha')")); + } + + @Test + void localStorageSetItemOverwritesExistingValue() { + page.navigate(server.EMPTY_PAGE); + page.localStorage().setItem("k", "first"); + page.localStorage().setItem("k", "second"); + assertEquals("second", page.localStorage().getItem("k")); + } + + @Test + void localStorageRemoveItemRemovesSingleItem() { + page.navigate(server.EMPTY_PAGE); + page.localStorage().setItem("a", "1"); + page.localStorage().setItem("b", "2"); + + page.localStorage().removeItem("a"); + assertEquals(mapOf("b", "2"), asMap(page.localStorage().items())); + } + + @Test + void localStorageClearEmptiesStorage() { + page.navigate(server.EMPTY_PAGE); + page.localStorage().setItem("a", "1"); + page.localStorage().setItem("b", "2"); + + page.localStorage().clear(); + assertEquals(0, page.localStorage().items().size()); + } + + @Test + void sessionStorageRoundTrip() { + page.navigate(server.EMPTY_PAGE); + assertEquals(0, page.sessionStorage().items().size()); + + page.sessionStorage().setItem("s1", "v1"); + page.sessionStorage().setItem("s2", "v2"); + assertEquals(mapOf("s1", "v1", "s2", "v2"), asMap(page.sessionStorage().items())); + assertEquals("v1", page.sessionStorage().getItem("s1")); + + page.sessionStorage().removeItem("s1"); + assertEquals(mapOf("s2", "v2"), asMap(page.sessionStorage().items())); + + page.sessionStorage().clear(); + assertEquals(0, page.sessionStorage().items().size()); + } + + @Test + void localStorageAndSessionStorageAreIndependent() { + page.navigate(server.EMPTY_PAGE); + page.localStorage().setItem("shared", "local"); + page.sessionStorage().setItem("shared", "session"); + + assertEquals("local", page.localStorage().getItem("shared")); + assertEquals("session", page.sessionStorage().getItem("shared")); + + page.localStorage().clear(); + assertEquals(0, page.localStorage().items().size()); + assertEquals("session", page.sessionStorage().getItem("shared")); + } + + @Test + void storageMethodsAreScopedToTheCurrentOrigin() { + page.navigate(server.PREFIX + "/empty.html"); + page.localStorage().setItem("k", "origin-1"); + + page.navigate(server.CROSS_PROCESS_PREFIX + "/empty.html"); + assertEquals(0, page.localStorage().items().size()); + page.localStorage().setItem("k", "origin-2"); + + page.navigate(server.PREFIX + "/empty.html"); + assertEquals("origin-1", page.localStorage().getItem("k")); + } +} diff --git a/scripts/DRIVER_VERSION b/scripts/DRIVER_VERSION index 4d5fde5bd..96023ba38 100644 --- a/scripts/DRIVER_VERSION +++ b/scripts/DRIVER_VERSION @@ -1 +1 @@ -1.60.0 +1.61.0-beta-1781285686000 diff --git a/tools/api-generator/src/main/java/com/microsoft/playwright/tools/ApiGenerator.java b/tools/api-generator/src/main/java/com/microsoft/playwright/tools/ApiGenerator.java index a640897d4..ad4418160 100644 --- a/tools/api-generator/src/main/java/com/microsoft/playwright/tools/ApiGenerator.java +++ b/tools/api-generator/src/main/java/com/microsoft/playwright/tools/ApiGenerator.java @@ -997,10 +997,11 @@ Map topLevelTypes() { } void writeTo(List output, String offset) { - if (methods.stream().anyMatch(m -> "create".equals(m.jsonName))) { + // Interfaces with a static factory method delegating to the Impl class, see Method.writeTo. + if (asList("Playwright", "FormData", "RequestOptions").contains(jsonName) && methods.stream().anyMatch(m -> "create".equals(m.jsonName))) { output.add("import com.microsoft.playwright.impl." + jsonName + "Impl;"); } - if (asList("Page", "Request", "Response", "APIRequestContext", "APIRequest", "APIResponse", "FileChooser", "Frame", "FrameLocator", "ElementHandle", "Locator", "Browser", "BrowserContext", "BrowserType", "Mouse", "Keyboard", "Tracing", "Video", "Debugger", "Screencast", "WebError").contains(jsonName)) { + if (asList("Page", "Request", "Response", "APIRequestContext", "APIRequest", "APIResponse", "FileChooser", "Frame", "FrameLocator", "ElementHandle", "Locator", "Browser", "BrowserContext", "BrowserType", "Mouse", "Keyboard", "Tracing", "Video", "Debugger", "Screencast", "WebError", "Credentials", "WebStorage").contains(jsonName)) { output.add("import com.microsoft.playwright.options.*;"); } if ("Download".equals(jsonName)) { @@ -1012,7 +1013,7 @@ void writeTo(List output, String offset) { if ("Clock".equals(jsonName)) { output.add("import java.util.Date;"); } - if (asList("Page", "Frame", "ElementHandle", "Locator", "LocatorAssertions", "APIRequest", "Browser", "BrowserContext", "BrowserType", "Route", "Request", "Response", "JSHandle", "ConsoleMessage", "APIResponse", "Playwright", "Debugger", "Screencast", "WebSocketRoute").contains(jsonName)) { + if (asList("Page", "Frame", "ElementHandle", "Locator", "LocatorAssertions", "APIRequest", "Browser", "BrowserContext", "BrowserType", "Route", "Request", "Response", "JSHandle", "ConsoleMessage", "APIResponse", "Playwright", "Debugger", "Screencast", "WebSocketRoute", "Credentials", "WebStorage").contains(jsonName)) { output.add("import java.util.*;"); } if (asList("WebSocketRoute").contains(jsonName)) { From 1d06a096511cd9868f411e863254ffe3ee5cfd12 Mon Sep 17 00:00:00 2001 From: Yury Semikhatsky Date: Fri, 12 Jun 2026 12:56:46 -0700 Subject: [PATCH 2/4] test: fix failures on firefox, webkit and windows bots - connectOverCDP is now supported in WebKit: skip the not-chromium test there and expect the new error message - accept all close-time messages in waitForNavigation-after-disconnect - wait 2s for page errors to accumulate, mirrors upstream #38378 - regenerate firefox screenshot expectations for Firefox 151 --- .../playwright/TestBrowserTypeBasic.java | 8 ++++++-- .../playwright/TestBrowserTypeConnect.java | 4 +++- .../playwright/TestPageEventPageError.java | 2 +- .../expectations/hide-should-work-firefox.png | Bin 45962 -> 39532 bytes .../remove-should-work-firefox.png | Bin 46454 -> 39872 bytes 5 files changed, 10 insertions(+), 4 deletions(-) diff --git a/playwright/src/test/java/com/microsoft/playwright/TestBrowserTypeBasic.java b/playwright/src/test/java/com/microsoft/playwright/TestBrowserTypeBasic.java index 08522ffee..1d81dd6b1 100644 --- a/playwright/src/test/java/com/microsoft/playwright/TestBrowserTypeBasic.java +++ b/playwright/src/test/java/com/microsoft/playwright/TestBrowserTypeBasic.java @@ -40,10 +40,14 @@ void browserTypeNameShouldWork() { assertEquals(getBrowserNameFromEnv(), browserType.name()); } + static boolean isChromiumOrWebKit() { + return isChromium() || isWebKit(); + } + @Test - @DisabledIf(value="com.microsoft.playwright.TestBase#isChromium", disabledReason="Non-chromium behavior") + @DisabledIf(value="isChromiumOrWebKit", disabledReason="Connecting over CDP is supported in Chromium and WebKit") void shouldThrowWhenTryingToConnectWithNotChromium() { PlaywrightException e = assertThrows(PlaywrightException.class, () -> browserType.connectOverCDP("foo")); - assertTrue(e.getMessage().contains("Connecting over CDP is only supported in Chromium.")); + assertTrue(e.getMessage().contains("Connecting over CDP is only supported in Chromium and WebKit.")); } } diff --git a/playwright/src/test/java/com/microsoft/playwright/TestBrowserTypeConnect.java b/playwright/src/test/java/com/microsoft/playwright/TestBrowserTypeConnect.java index 098dea19d..2b7db6c38 100644 --- a/playwright/src/test/java/com/microsoft/playwright/TestBrowserTypeConnect.java +++ b/playwright/src/test/java/com/microsoft/playwright/TestBrowserTypeConnect.java @@ -259,7 +259,9 @@ void shouldThrowWhenCallingWaitForNavigationAfterDisconnect() throws Interrupted } assertFalse(browser.isConnected()); PlaywrightException e = assertThrows(PlaywrightException.class, () -> page.waitForNavigation(() -> {})); - assertTrue(e.getMessage().contains("Target page, context or browser has been closed"), e.getMessage()); + assertTrue(e.getMessage().contains("Browser closed") || + e.getMessage().contains("Page closed") || + e.getMessage().contains("Target page, context or browser has been closed"), e.getMessage()); } @Test diff --git a/playwright/src/test/java/com/microsoft/playwright/TestPageEventPageError.java b/playwright/src/test/java/com/microsoft/playwright/TestPageEventPageError.java index f70e2cbd5..f90f895f7 100644 --- a/playwright/src/test/java/com/microsoft/playwright/TestPageEventPageError.java +++ b/playwright/src/test/java/com/microsoft/playwright/TestPageEventPageError.java @@ -30,7 +30,7 @@ void pageErrorsShouldWork() { page.evaluate("async () => {\n" + " for (let i = 0; i < 301; i++)\n" + " window.setTimeout(() => { throw new Error('error' + i); }, 0);\n" + - " await new Promise(f => window.setTimeout(f, 100));\n" + + " await new Promise(f => window.setTimeout(f, 2000));\n" + " }"); List errors = page.pageErrors(); diff --git a/playwright/src/test/resources/expectations/hide-should-work-firefox.png b/playwright/src/test/resources/expectations/hide-should-work-firefox.png index 7af4f1af7002a3b0596c683b54a0ce3d678a36a4..ac1e22e22c1fbd82456bd551ca36406dde88d40a 100644 GIT binary patch literal 39532 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 I;!fcI0;=>YA^-pY literal 45962 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 -yKcUnkwT0&I;}x?b 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 diff --git a/playwright/src/test/resources/expectations/remove-should-work-firefox.png b/playwright/src/test/resources/expectations/remove-should-work-firefox.png index cbae7f34d0284fca2c129df15618fc2c0a0c5e03..e4ee20d9e6dd80f29c1f51b91b3d83a141b1caf3 100644 GIT binary patch literal 39872 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

{?6L2uk>9PAd`GNaEb`6 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 literal 46454 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�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℘ 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 OK0aQ4p4UD0Wc>lR$F(Z} From 4fb8a9517863877ce6af03ae14e1ba5e42cb5fd1 Mon Sep 17 00:00:00 2001 From: Yury Semikhatsky Date: Fri, 12 Jun 2026 12:56:46 -0700 Subject: [PATCH 3/4] chore: trim comments --- .../main/java/com/microsoft/playwright/impl/ChannelOwner.java | 3 +-- .../main/java/com/microsoft/playwright/impl/Connection.java | 4 +--- .../src/main/java/com/microsoft/playwright/impl/Protocol.java | 1 - .../com/microsoft/playwright/impl/ServerErrorWithDetails.java | 3 +-- .../java/com/microsoft/playwright/tools/ApiGenerator.java | 2 +- 5 files changed, 4 insertions(+), 9 deletions(-) diff --git a/playwright/src/main/java/com/microsoft/playwright/impl/ChannelOwner.java b/playwright/src/main/java/com/microsoft/playwright/impl/ChannelOwner.java index 8d7973227..729c300f3 100644 --- a/playwright/src/main/java/com/microsoft/playwright/impl/ChannelOwner.java +++ b/playwright/src/main/java/com/microsoft/playwright/impl/ChannelOwner.java @@ -110,8 +110,7 @@ WaitableResult sendMessageAsync(String method, JsonObject params) { return connection.sendMessageAsync(guid, method, params); } - // Fire-and-forget: the server intentionally never replies to this message, - // so silently drop it if the object was collected. + // Fire-and-forget: silently drop if the object was collected. void sendMessageNoReply(String method, JsonObject params) { if (wasCollected) { return; diff --git a/playwright/src/main/java/com/microsoft/playwright/impl/Connection.java b/playwright/src/main/java/com/microsoft/playwright/impl/Connection.java index 369daf68a..46354abf2 100644 --- a/playwright/src/main/java/com/microsoft/playwright/impl/Connection.java +++ b/playwright/src/main/java/com/microsoft/playwright/impl/Connection.java @@ -136,7 +136,7 @@ public WaitableResult sendMessageAsync(String guid, String method, return internalSendMessage(guid, method, params, true, true); } - // Fire-and-forget: the server intentionally never replies to this message. + // Fire-and-forget: the server never replies. public void sendMessageNoReply(String guid, String method, JsonObject params) { internalSendMessage(guid, method, params, false, false); } @@ -269,8 +269,6 @@ private void dispatch(Message message) { } else { exception = new DriverException(message.error.error + callLog); } - // The server attaches errorDetails to errors of the methods that declare them - // in the protocol (currently only Frame.expect and Page.expectScreenshot). if (message.errorDetails != null) { exception = new ServerErrorWithDetails(exception, message.errorDetails, message.log); } diff --git a/playwright/src/main/java/com/microsoft/playwright/impl/Protocol.java b/playwright/src/main/java/com/microsoft/playwright/impl/Protocol.java index 02d93bb2f..b7e02eed2 100644 --- a/playwright/src/main/java/com/microsoft/playwright/impl/Protocol.java +++ b/playwright/src/main/java/com/microsoft/playwright/impl/Protocol.java @@ -122,7 +122,6 @@ static class Received { List log; } -// Sent by the server as `errorDetails` when Frame.expect fails. class FrameExpectErrorDetails { FrameExpectResult.Received received; Boolean timedOut; diff --git a/playwright/src/main/java/com/microsoft/playwright/impl/ServerErrorWithDetails.java b/playwright/src/main/java/com/microsoft/playwright/impl/ServerErrorWithDetails.java index edaa64b70..64bc19179 100644 --- a/playwright/src/main/java/com/microsoft/playwright/impl/ServerErrorWithDetails.java +++ b/playwright/src/main/java/com/microsoft/playwright/impl/ServerErrorWithDetails.java @@ -24,7 +24,6 @@ import java.util.ArrayList; import java.util.List; -// Server error with the structured details declared in the protocol for the failed method. class ServerErrorWithDetails extends PlaywrightException { private final JsonObject errorDetails; private final JsonArray log; @@ -35,7 +34,7 @@ class ServerErrorWithDetails extends PlaywrightException { this.log = log; } - // Used to rethrow with the stack trace of the calling thread, see WaitableResult.get(). + // Rethrown with the calling thread's stack trace, see WaitableResult.get(). ServerErrorWithDetails(ServerErrorWithDetails cause) { super(cause.getMessage(), cause); this.errorDetails = cause.errorDetails; diff --git a/tools/api-generator/src/main/java/com/microsoft/playwright/tools/ApiGenerator.java b/tools/api-generator/src/main/java/com/microsoft/playwright/tools/ApiGenerator.java index ad4418160..a41df3f87 100644 --- a/tools/api-generator/src/main/java/com/microsoft/playwright/tools/ApiGenerator.java +++ b/tools/api-generator/src/main/java/com/microsoft/playwright/tools/ApiGenerator.java @@ -997,7 +997,7 @@ Map topLevelTypes() { } void writeTo(List output, String offset) { - // Interfaces with a static factory method delegating to the Impl class, see Method.writeTo. + // Interfaces with a static factory method, see Method.writeTo. if (asList("Playwright", "FormData", "RequestOptions").contains(jsonName) && methods.stream().anyMatch(m -> "create".equals(m.jsonName))) { output.add("import com.microsoft.playwright.impl." + jsonName + "Impl;"); } From 9d712e6f8c212fb4a5af80804d041af692c25839 Mon Sep 17 00:00:00 2001 From: Yury Semikhatsky Date: Fri, 12 Jun 2026 13:20:30 -0700 Subject: [PATCH 4/4] test: fix remaining windows bot failures - accept all close-time error message variants in waitForNavigation-after-disconnect, the surfaced message depends on which call hits the closed connection first - shouldDetachWhenPageCloses: only check that detach throws, like the upstream test - skip @TempDir cleanup for user data dirs: on Windows Chromium 149 keeps chrome_debug.log locked briefly after close --- .../microsoft/playwright/TestBrowserContextCDPSession.java | 5 +++-- .../com/microsoft/playwright/TestBrowserTypeConnect.java | 2 ++ .../com/microsoft/playwright/TestClientCertificates.java | 5 ++++- .../com/microsoft/playwright/TestDefaultBrowserContext2.java | 5 ++++- 4 files changed, 13 insertions(+), 4 deletions(-) diff --git a/playwright/src/test/java/com/microsoft/playwright/TestBrowserContextCDPSession.java b/playwright/src/test/java/com/microsoft/playwright/TestBrowserContextCDPSession.java index 14e586917..bf0ef7d5a 100644 --- a/playwright/src/test/java/com/microsoft/playwright/TestBrowserContextCDPSession.java +++ b/playwright/src/test/java/com/microsoft/playwright/TestBrowserContextCDPSession.java @@ -131,8 +131,9 @@ void shouldDetachWhenPageCloses() { CDPSession session = page.context().newCDPSession(page); page.close(); - PlaywrightException exception = assertThrows(PlaywrightException.class, session::detach); - assertTrue(exception.getMessage().contains("Target page, context or browser has been closed"), exception.getMessage()); + // Like the upstream test, only check that detach fails — the error depends on + // whether the session detached before or after the page closed. + assertThrows(PlaywrightException.class, session::detach); context.close(); } diff --git a/playwright/src/test/java/com/microsoft/playwright/TestBrowserTypeConnect.java b/playwright/src/test/java/com/microsoft/playwright/TestBrowserTypeConnect.java index 2b7db6c38..191d98da7 100644 --- a/playwright/src/test/java/com/microsoft/playwright/TestBrowserTypeConnect.java +++ b/playwright/src/test/java/com/microsoft/playwright/TestBrowserTypeConnect.java @@ -259,8 +259,10 @@ void shouldThrowWhenCallingWaitForNavigationAfterDisconnect() throws Interrupted } assertFalse(browser.isConnected()); PlaywrightException e = assertThrows(PlaywrightException.class, () -> page.waitForNavigation(() -> {})); + // The surfaced message depends on which call hits the closed connection first. assertTrue(e.getMessage().contains("Browser closed") || e.getMessage().contains("Page closed") || + e.getMessage().contains("Browser has been closed") || e.getMessage().contains("Target page, context or browser has been closed"), e.getMessage()); } diff --git a/playwright/src/test/java/com/microsoft/playwright/TestClientCertificates.java b/playwright/src/test/java/com/microsoft/playwright/TestClientCertificates.java index f6028c6ee..90c6336ca 100644 --- a/playwright/src/test/java/com/microsoft/playwright/TestClientCertificates.java +++ b/playwright/src/test/java/com/microsoft/playwright/TestClientCertificates.java @@ -5,6 +5,7 @@ import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.condition.DisabledIf; +import org.junit.jupiter.api.io.CleanupMode; import org.junit.jupiter.api.io.TempDir; import java.io.IOException; @@ -223,7 +224,9 @@ public void shouldWorkWithBrowserNewPageWhenPassingAsContent() throws IOExceptio @Test @DisabledIf(value="com.microsoft.playwright.TestClientCertificates#isWebKitMacOS", disabledReason="The network connection was lost.") - public void shouldWorkWithBrowserLaunchPersistentContext(@TempDir Path tmpDir) { + // No cleanup: on Windows Chromium may keep chrome_debug.log in the user data dir + // locked briefly after close, failing the deletion. + public void shouldWorkWithBrowserLaunchPersistentContext(@TempDir(cleanup = CleanupMode.NEVER) Path tmpDir) { BrowserType.LaunchPersistentContextOptions options = new BrowserType.LaunchPersistentContextOptions() .setIgnoreHTTPSErrors(true) // TODO: remove once we can pass a custom CA. .setClientCertificates(asList( diff --git a/playwright/src/test/java/com/microsoft/playwright/TestDefaultBrowserContext2.java b/playwright/src/test/java/com/microsoft/playwright/TestDefaultBrowserContext2.java index 527e63e35..458738b37 100644 --- a/playwright/src/test/java/com/microsoft/playwright/TestDefaultBrowserContext2.java +++ b/playwright/src/test/java/com/microsoft/playwright/TestDefaultBrowserContext2.java @@ -22,6 +22,7 @@ import org.junit.jupiter.api.Assumptions; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.condition.DisabledIf; +import org.junit.jupiter.api.io.CleanupMode; import org.junit.jupiter.api.io.TempDir; import java.io.IOException; @@ -46,7 +47,9 @@ public class TestDefaultBrowserContext2 extends TestBase { private BrowserContext persistentContext; - @TempDir Path tempDir; + // No cleanup: on Windows Chromium may keep chrome_debug.log in the user data dir + // locked briefly after close, failing the deletion. + @TempDir(cleanup = CleanupMode.NEVER) Path tempDir; @AfterEach void closePersistentContext() {