Usage *
{@code
diff --git a/playwright/src/main/java/com/microsoft/playwright/BrowserType.java b/playwright/src/main/java/com/microsoft/playwright/BrowserType.java
index 2fa39586d..305dd7fc5 100644
--- a/playwright/src/main/java/com/microsoft/playwright/BrowserType.java
+++ b/playwright/src/main/java/com/microsoft/playwright/BrowserType.java
@@ -1314,6 +1314,9 @@ default Browser connect(String endpoint) {
* advanced functionality, you probably want to use {@link com.microsoft.playwright.BrowserType#connect
* BrowserType.connect()}.
*
+ * NOTE: Playwright maintains a curated list of arguments for launching the browser. If you launch the browser without Playwright
+ * and do not pass the exact same arguments, some of Playwright functionality may be broken upon connecting to the browser.
+ *
*
Usage
*
{@code
* Browser browser = playwright.chromium().connectOverCDP("http://localhost:9222");
@@ -1340,6 +1343,9 @@ default Browser connectOverCDP(String endpointURL) {
* advanced functionality, you probably want to use {@link com.microsoft.playwright.BrowserType#connect
* BrowserType.connect()}.
*
+ * NOTE: Playwright maintains a curated list of arguments for launching the browser. If you launch the browser without Playwright
+ * and do not pass the exact same arguments, some of Playwright functionality may be broken upon connecting to the browser.
+ *
*
Usage
*
{@code
* Browser browser = playwright.chromium().connectOverCDP("http://localhost:9222");
diff --git a/playwright/src/main/java/com/microsoft/playwright/Credentials.java b/playwright/src/main/java/com/microsoft/playwright/Credentials.java
index a3a180095..5c3eb6d40 100644
--- a/playwright/src/main/java/com/microsoft/playwright/Credentials.java
+++ b/playwright/src/main/java/com/microsoft/playwright/Credentials.java
@@ -24,7 +24,7 @@
* 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:
+ *
There are three common ways to use it:
*
*
Usage: seed a known credential
*
{@code
@@ -43,7 +43,7 @@
* // The page's navigator.credentials.get() is answered with the seeded passkey.
* }
*
- * Usage: capture a passkey, then reuse it
+ *
Usage: capture a credential, then reuse it
*
{@code
* // setup test: let the app register a passkey, then save it.
* BrowserContext context = browser.newContext();
@@ -75,6 +75,11 @@
* // navigator.credentials.get() resolves the captured passkey — already signed in.
* }
*
+ * Usage: save credentials in the storage state, restore later
+ *
+ *
See authentication guide for examples of using saving and resotring
+ * the storage state.
+ *
*
Defaults
*/
public interface Credentials {
diff --git a/playwright/src/main/java/com/microsoft/playwright/ElementHandle.java b/playwright/src/main/java/com/microsoft/playwright/ElementHandle.java
index 6d7c4621c..9fb77bcfa 100644
--- a/playwright/src/main/java/com/microsoft/playwright/ElementHandle.java
+++ b/playwright/src/main/java/com/microsoft/playwright/ElementHandle.java
@@ -73,6 +73,13 @@ class CheckOptions {
* element.
*/
public Position position;
+ /**
+ * Controls whether Playwright scrolls the element into view before performing the action. Defaults to {@code "auto"},
+ * which scrolls the element into view when necessary, including scrolling nested scrollable containers. When set to {@code
+ * "none"}, Playwright does not scroll the element and the action fails if the element is not already in the viewport. This
+ * is useful to assert that an element is reachable by the user without additional scrolling.
+ */
+ public ScrollMode scroll;
/**
* Maximum time in milliseconds. Defaults to {@code 30000} (30 seconds). Pass {@code 0} to disable timeout. The default
* value can be changed by using the {@link com.microsoft.playwright.BrowserContext#setDefaultTimeout
@@ -117,6 +124,16 @@ public CheckOptions setPosition(Position position) {
this.position = position;
return this;
}
+ /**
+ * Controls whether Playwright scrolls the element into view before performing the action. Defaults to {@code "auto"},
+ * which scrolls the element into view when necessary, including scrolling nested scrollable containers. When set to {@code
+ * "none"}, Playwright does not scroll the element and the action fails if the element is not already in the viewport. This
+ * is useful to assert that an element is reachable by the user without additional scrolling.
+ */
+ public CheckOptions setScroll(ScrollMode scroll) {
+ this.scroll = scroll;
+ return this;
+ }
/**
* Maximum time in milliseconds. Defaults to {@code 30000} (30 seconds). Pass {@code 0} to disable timeout. The default
* value can be changed by using the {@link com.microsoft.playwright.BrowserContext#setDefaultTimeout
@@ -170,6 +187,13 @@ class ClickOptions {
* element.
*/
public Position position;
+ /**
+ * Controls whether Playwright scrolls the element into view before performing the action. Defaults to {@code "auto"},
+ * which scrolls the element into view when necessary, including scrolling nested scrollable containers. When set to {@code
+ * "none"}, Playwright does not scroll the element and the action fails if the element is not already in the viewport. This
+ * is useful to assert that an element is reachable by the user without additional scrolling.
+ */
+ public ScrollMode scroll;
/**
* Defaults to 1. Sends {@code n} interpolated {@code mousemove} events to represent travel between Playwright's current
* cursor position and the provided destination. When set to 1, emits a single {@code mousemove} event at the destination
@@ -250,6 +274,16 @@ public ClickOptions setPosition(Position position) {
this.position = position;
return this;
}
+ /**
+ * Controls whether Playwright scrolls the element into view before performing the action. Defaults to {@code "auto"},
+ * which scrolls the element into view when necessary, including scrolling nested scrollable containers. When set to {@code
+ * "none"}, Playwright does not scroll the element and the action fails if the element is not already in the viewport. This
+ * is useful to assert that an element is reachable by the user without additional scrolling.
+ */
+ public ClickOptions setScroll(ScrollMode scroll) {
+ this.scroll = scroll;
+ return this;
+ }
/**
* Defaults to 1. Sends {@code n} interpolated {@code mousemove} events to represent travel between Playwright's current
* cursor position and the provided destination. When set to 1, emits a single {@code mousemove} event at the destination
@@ -308,6 +342,13 @@ class DblclickOptions {
* element.
*/
public Position position;
+ /**
+ * Controls whether Playwright scrolls the element into view before performing the action. Defaults to {@code "auto"},
+ * which scrolls the element into view when necessary, including scrolling nested scrollable containers. When set to {@code
+ * "none"}, Playwright does not scroll the element and the action fails if the element is not already in the viewport. This
+ * is useful to assert that an element is reachable by the user without additional scrolling.
+ */
+ public ScrollMode scroll;
/**
* Defaults to 1. Sends {@code n} interpolated {@code mousemove} events to represent travel between Playwright's current
* cursor position and the provided destination. When set to 1, emits a single {@code mousemove} event at the destination
@@ -381,6 +422,16 @@ public DblclickOptions setPosition(Position position) {
this.position = position;
return this;
}
+ /**
+ * Controls whether Playwright scrolls the element into view before performing the action. Defaults to {@code "auto"},
+ * which scrolls the element into view when necessary, including scrolling nested scrollable containers. When set to {@code
+ * "none"}, Playwright does not scroll the element and the action fails if the element is not already in the viewport. This
+ * is useful to assert that an element is reachable by the user without additional scrolling.
+ */
+ public DblclickOptions setScroll(ScrollMode scroll) {
+ this.scroll = scroll;
+ return this;
+ }
/**
* Defaults to 1. Sends {@code n} interpolated {@code mousemove} events to represent travel between Playwright's current
* cursor position and the provided destination. When set to 1, emits a single {@code mousemove} event at the destination
@@ -475,6 +526,13 @@ class HoverOptions {
* element.
*/
public Position position;
+ /**
+ * Controls whether Playwright scrolls the element into view before performing the action. Defaults to {@code "auto"},
+ * which scrolls the element into view when necessary, including scrolling nested scrollable containers. When set to {@code
+ * "none"}, Playwright does not scroll the element and the action fails if the element is not already in the viewport. This
+ * is useful to assert that an element is reachable by the user without additional scrolling.
+ */
+ public ScrollMode scroll;
/**
* Maximum time in milliseconds. Defaults to {@code 30000} (30 seconds). Pass {@code 0} to disable timeout. The default
* value can be changed by using the {@link com.microsoft.playwright.BrowserContext#setDefaultTimeout
@@ -528,6 +586,16 @@ public HoverOptions setPosition(Position position) {
this.position = position;
return this;
}
+ /**
+ * Controls whether Playwright scrolls the element into view before performing the action. Defaults to {@code "auto"},
+ * which scrolls the element into view when necessary, including scrolling nested scrollable containers. When set to {@code
+ * "none"}, Playwright does not scroll the element and the action fails if the element is not already in the viewport. This
+ * is useful to assert that an element is reachable by the user without additional scrolling.
+ */
+ public HoverOptions setScroll(ScrollMode scroll) {
+ this.scroll = scroll;
+ return this;
+ }
/**
* Maximum time in milliseconds. Defaults to {@code 30000} (30 seconds). Pass {@code 0} to disable timeout. The default
* value can be changed by using the {@link com.microsoft.playwright.BrowserContext#setDefaultTimeout
@@ -550,18 +618,12 @@ public HoverOptions setTrial(boolean trial) {
}
class InputValueOptions {
/**
- * Maximum time in milliseconds. Defaults to {@code 30000} (30 seconds). Pass {@code 0} to disable timeout. The default
- * value can be changed by using the {@link com.microsoft.playwright.BrowserContext#setDefaultTimeout
- * BrowserContext.setDefaultTimeout()} or {@link com.microsoft.playwright.Page#setDefaultTimeout Page.setDefaultTimeout()}
- * methods.
+ * @deprecated This option is ignored. The value is returned immediately.
*/
public Double timeout;
/**
- * Maximum time in milliseconds. Defaults to {@code 30000} (30 seconds). Pass {@code 0} to disable timeout. The default
- * value can be changed by using the {@link com.microsoft.playwright.BrowserContext#setDefaultTimeout
- * BrowserContext.setDefaultTimeout()} or {@link com.microsoft.playwright.Page#setDefaultTimeout Page.setDefaultTimeout()}
- * methods.
+ * @deprecated This option is ignored. The value is returned immediately.
*/
public InputValueOptions setTimeout(double timeout) {
this.timeout = timeout;
@@ -652,7 +714,9 @@ class ScreenshotOptions {
*/
public Path path;
/**
- * The quality of the image, between 0-100. Not applicable to {@code png} images.
+ * The quality of the image, between 0-100. Not applicable to {@code png} images. For {@code jpeg} the default is {@code
+ * 80}. For {@code webp}, a quality of {@code 100} (the default) produces a lossless image, while lower values use lossy
+ * compression.
*/
public Integer quality;
/**
@@ -740,7 +804,9 @@ public ScreenshotOptions setPath(Path path) {
return this;
}
/**
- * The quality of the image, between 0-100. Not applicable to {@code png} images.
+ * The quality of the image, between 0-100. Not applicable to {@code png} images. For {@code jpeg} the default is {@code
+ * 80}. For {@code webp}, a quality of {@code 100} (the default) produces a lossless image, while lower values use lossy
+ * compression.
*/
public ScreenshotOptions setQuality(int quality) {
this.quality = quality;
@@ -896,6 +962,13 @@ class SetCheckedOptions {
* element.
*/
public Position position;
+ /**
+ * Controls whether Playwright scrolls the element into view before performing the action. Defaults to {@code "auto"},
+ * which scrolls the element into view when necessary, including scrolling nested scrollable containers. When set to {@code
+ * "none"}, Playwright does not scroll the element and the action fails if the element is not already in the viewport. This
+ * is useful to assert that an element is reachable by the user without additional scrolling.
+ */
+ public ScrollMode scroll;
/**
* Maximum time in milliseconds. Defaults to {@code 30000} (30 seconds). Pass {@code 0} to disable timeout. The default
* value can be changed by using the {@link com.microsoft.playwright.BrowserContext#setDefaultTimeout
@@ -940,6 +1013,16 @@ public SetCheckedOptions setPosition(Position position) {
this.position = position;
return this;
}
+ /**
+ * Controls whether Playwright scrolls the element into view before performing the action. Defaults to {@code "auto"},
+ * which scrolls the element into view when necessary, including scrolling nested scrollable containers. When set to {@code
+ * "none"}, Playwright does not scroll the element and the action fails if the element is not already in the viewport. This
+ * is useful to assert that an element is reachable by the user without additional scrolling.
+ */
+ public SetCheckedOptions setScroll(ScrollMode scroll) {
+ this.scroll = scroll;
+ return this;
+ }
/**
* Maximum time in milliseconds. Defaults to {@code 30000} (30 seconds). Pass {@code 0} to disable timeout. The default
* value can be changed by using the {@link com.microsoft.playwright.BrowserContext#setDefaultTimeout
@@ -1012,6 +1095,13 @@ class TapOptions {
* element.
*/
public Position position;
+ /**
+ * Controls whether Playwright scrolls the element into view before performing the action. Defaults to {@code "auto"},
+ * which scrolls the element into view when necessary, including scrolling nested scrollable containers. When set to {@code
+ * "none"}, Playwright does not scroll the element and the action fails if the element is not already in the viewport. This
+ * is useful to assert that an element is reachable by the user without additional scrolling.
+ */
+ public ScrollMode scroll;
/**
* Maximum time in milliseconds. Defaults to {@code 30000} (30 seconds). Pass {@code 0} to disable timeout. The default
* value can be changed by using the {@link com.microsoft.playwright.BrowserContext#setDefaultTimeout
@@ -1065,6 +1155,16 @@ public TapOptions setPosition(Position position) {
this.position = position;
return this;
}
+ /**
+ * Controls whether Playwright scrolls the element into view before performing the action. Defaults to {@code "auto"},
+ * which scrolls the element into view when necessary, including scrolling nested scrollable containers. When set to {@code
+ * "none"}, Playwright does not scroll the element and the action fails if the element is not already in the viewport. This
+ * is useful to assert that an element is reachable by the user without additional scrolling.
+ */
+ public TapOptions setScroll(ScrollMode scroll) {
+ this.scroll = scroll;
+ return this;
+ }
/**
* Maximum time in milliseconds. Defaults to {@code 30000} (30 seconds). Pass {@code 0} to disable timeout. The default
* value can be changed by using the {@link com.microsoft.playwright.BrowserContext#setDefaultTimeout
@@ -1142,6 +1242,13 @@ class UncheckOptions {
* element.
*/
public Position position;
+ /**
+ * Controls whether Playwright scrolls the element into view before performing the action. Defaults to {@code "auto"},
+ * which scrolls the element into view when necessary, including scrolling nested scrollable containers. When set to {@code
+ * "none"}, Playwright does not scroll the element and the action fails if the element is not already in the viewport. This
+ * is useful to assert that an element is reachable by the user without additional scrolling.
+ */
+ public ScrollMode scroll;
/**
* Maximum time in milliseconds. Defaults to {@code 30000} (30 seconds). Pass {@code 0} to disable timeout. The default
* value can be changed by using the {@link com.microsoft.playwright.BrowserContext#setDefaultTimeout
@@ -1186,6 +1293,16 @@ public UncheckOptions setPosition(Position position) {
this.position = position;
return this;
}
+ /**
+ * Controls whether Playwright scrolls the element into view before performing the action. Defaults to {@code "auto"},
+ * which scrolls the element into view when necessary, including scrolling nested scrollable containers. When set to {@code
+ * "none"}, Playwright does not scroll the element and the action fails if the element is not already in the viewport. This
+ * is useful to assert that an element is reachable by the user without additional scrolling.
+ */
+ public UncheckOptions setScroll(ScrollMode scroll) {
+ this.scroll = scroll;
+ return this;
+ }
/**
* Maximum time in milliseconds. Defaults to {@code 30000} (30 seconds). Pass {@code 0} to disable timeout. The default
* value can be changed by using the {@link com.microsoft.playwright.BrowserContext#setDefaultTimeout
diff --git a/playwright/src/main/java/com/microsoft/playwright/Frame.java b/playwright/src/main/java/com/microsoft/playwright/Frame.java
index b00258a6b..82f6874bd 100644
--- a/playwright/src/main/java/com/microsoft/playwright/Frame.java
+++ b/playwright/src/main/java/com/microsoft/playwright/Frame.java
@@ -165,6 +165,13 @@ class CheckOptions {
* element.
*/
public Position position;
+ /**
+ * Controls whether Playwright scrolls the element into view before performing the action. Defaults to {@code "auto"},
+ * which scrolls the element into view when necessary, including scrolling nested scrollable containers. When set to {@code
+ * "none"}, Playwright does not scroll the element and the action fails if the element is not already in the viewport. This
+ * is useful to assert that an element is reachable by the user without additional scrolling.
+ */
+ public ScrollMode scroll;
/**
* When true, the call requires selector to resolve to a single element. If given selector resolves to more than one
* element, the call throws an exception.
@@ -214,6 +221,16 @@ public CheckOptions setPosition(Position position) {
this.position = position;
return this;
}
+ /**
+ * Controls whether Playwright scrolls the element into view before performing the action. Defaults to {@code "auto"},
+ * which scrolls the element into view when necessary, including scrolling nested scrollable containers. When set to {@code
+ * "none"}, Playwright does not scroll the element and the action fails if the element is not already in the viewport. This
+ * is useful to assert that an element is reachable by the user without additional scrolling.
+ */
+ public CheckOptions setScroll(ScrollMode scroll) {
+ this.scroll = scroll;
+ return this;
+ }
/**
* When true, the call requires selector to resolve to a single element. If given selector resolves to more than one
* element, the call throws an exception.
@@ -275,6 +292,13 @@ class ClickOptions {
* element.
*/
public Position position;
+ /**
+ * Controls whether Playwright scrolls the element into view before performing the action. Defaults to {@code "auto"},
+ * which scrolls the element into view when necessary, including scrolling nested scrollable containers. When set to {@code
+ * "none"}, Playwright does not scroll the element and the action fails if the element is not already in the viewport. This
+ * is useful to assert that an element is reachable by the user without additional scrolling.
+ */
+ public ScrollMode scroll;
/**
* When true, the call requires selector to resolve to a single element. If given selector resolves to more than one
* element, the call throws an exception.
@@ -355,6 +379,16 @@ public ClickOptions setPosition(Position position) {
this.position = position;
return this;
}
+ /**
+ * Controls whether Playwright scrolls the element into view before performing the action. Defaults to {@code "auto"},
+ * which scrolls the element into view when necessary, including scrolling nested scrollable containers. When set to {@code
+ * "none"}, Playwright does not scroll the element and the action fails if the element is not already in the viewport. This
+ * is useful to assert that an element is reachable by the user without additional scrolling.
+ */
+ public ClickOptions setScroll(ScrollMode scroll) {
+ this.scroll = scroll;
+ return this;
+ }
/**
* When true, the call requires selector to resolve to a single element. If given selector resolves to more than one
* element, the call throws an exception.
@@ -413,6 +447,13 @@ class DblclickOptions {
* element.
*/
public Position position;
+ /**
+ * Controls whether Playwright scrolls the element into view before performing the action. Defaults to {@code "auto"},
+ * which scrolls the element into view when necessary, including scrolling nested scrollable containers. When set to {@code
+ * "none"}, Playwright does not scroll the element and the action fails if the element is not already in the viewport. This
+ * is useful to assert that an element is reachable by the user without additional scrolling.
+ */
+ public ScrollMode scroll;
/**
* When true, the call requires selector to resolve to a single element. If given selector resolves to more than one
* element, the call throws an exception.
@@ -486,6 +527,16 @@ public DblclickOptions setPosition(Position position) {
this.position = position;
return this;
}
+ /**
+ * Controls whether Playwright scrolls the element into view before performing the action. Defaults to {@code "auto"},
+ * which scrolls the element into view when necessary, including scrolling nested scrollable containers. When set to {@code
+ * "none"}, Playwright does not scroll the element and the action fails if the element is not already in the viewport. This
+ * is useful to assert that an element is reachable by the user without additional scrolling.
+ */
+ public DblclickOptions setScroll(ScrollMode scroll) {
+ this.scroll = scroll;
+ return this;
+ }
/**
* When true, the call requires selector to resolve to a single element. If given selector resolves to more than one
* element, the call throws an exception.
@@ -558,6 +609,13 @@ class DragAndDropOptions {
* @deprecated This option has no effect.
*/
public Boolean noWaitAfter;
+ /**
+ * Controls whether Playwright scrolls the element into view before performing the action. Defaults to {@code "auto"},
+ * which scrolls the element into view when necessary, including scrolling nested scrollable containers. When set to {@code
+ * "none"}, Playwright does not scroll the element and the action fails if the element is not already in the viewport. This
+ * is useful to assert that an element is reachable by the user without additional scrolling.
+ */
+ public ScrollMode scroll;
/**
* Clicks on the source element at this point relative to the top-left corner of the element's padding box. If not
* specified, some visible point of the element is used.
@@ -607,6 +665,16 @@ public DragAndDropOptions setNoWaitAfter(boolean noWaitAfter) {
this.noWaitAfter = noWaitAfter;
return this;
}
+ /**
+ * Controls whether Playwright scrolls the element into view before performing the action. Defaults to {@code "auto"},
+ * which scrolls the element into view when necessary, including scrolling nested scrollable containers. When set to {@code
+ * "none"}, Playwright does not scroll the element and the action fails if the element is not already in the viewport. This
+ * is useful to assert that an element is reachable by the user without additional scrolling.
+ */
+ public DragAndDropOptions setScroll(ScrollMode scroll) {
+ this.scroll = scroll;
+ return this;
+ }
/**
* Clicks on the source element at this point relative to the top-left corner of the element's padding box. If not
* specified, some visible point of the element is used.
@@ -1156,6 +1224,13 @@ class HoverOptions {
* element.
*/
public Position position;
+ /**
+ * Controls whether Playwright scrolls the element into view before performing the action. Defaults to {@code "auto"},
+ * which scrolls the element into view when necessary, including scrolling nested scrollable containers. When set to {@code
+ * "none"}, Playwright does not scroll the element and the action fails if the element is not already in the viewport. This
+ * is useful to assert that an element is reachable by the user without additional scrolling.
+ */
+ public ScrollMode scroll;
/**
* When true, the call requires selector to resolve to a single element. If given selector resolves to more than one
* element, the call throws an exception.
@@ -1215,6 +1290,16 @@ public HoverOptions setPosition(Position position) {
this.position = position;
return this;
}
+ /**
+ * Controls whether Playwright scrolls the element into view before performing the action. Defaults to {@code "auto"},
+ * which scrolls the element into view when necessary, including scrolling nested scrollable containers. When set to {@code
+ * "none"}, Playwright does not scroll the element and the action fails if the element is not already in the viewport. This
+ * is useful to assert that an element is reachable by the user without additional scrolling.
+ */
+ public HoverOptions setScroll(ScrollMode scroll) {
+ this.scroll = scroll;
+ return this;
+ }
/**
* When true, the call requires selector to resolve to a single element. If given selector resolves to more than one
* element, the call throws an exception.
@@ -1772,6 +1857,13 @@ class SetCheckedOptions {
* element.
*/
public Position position;
+ /**
+ * Controls whether Playwright scrolls the element into view before performing the action. Defaults to {@code "auto"},
+ * which scrolls the element into view when necessary, including scrolling nested scrollable containers. When set to {@code
+ * "none"}, Playwright does not scroll the element and the action fails if the element is not already in the viewport. This
+ * is useful to assert that an element is reachable by the user without additional scrolling.
+ */
+ public ScrollMode scroll;
/**
* When true, the call requires selector to resolve to a single element. If given selector resolves to more than one
* element, the call throws an exception.
@@ -1821,6 +1913,16 @@ public SetCheckedOptions setPosition(Position position) {
this.position = position;
return this;
}
+ /**
+ * Controls whether Playwright scrolls the element into view before performing the action. Defaults to {@code "auto"},
+ * which scrolls the element into view when necessary, including scrolling nested scrollable containers. When set to {@code
+ * "none"}, Playwright does not scroll the element and the action fails if the element is not already in the viewport. This
+ * is useful to assert that an element is reachable by the user without additional scrolling.
+ */
+ public SetCheckedOptions setScroll(ScrollMode scroll) {
+ this.scroll = scroll;
+ return this;
+ }
/**
* When true, the call requires selector to resolve to a single element. If given selector resolves to more than one
* element, the call throws an exception.
@@ -1963,6 +2065,13 @@ class TapOptions {
* element.
*/
public Position position;
+ /**
+ * Controls whether Playwright scrolls the element into view before performing the action. Defaults to {@code "auto"},
+ * which scrolls the element into view when necessary, including scrolling nested scrollable containers. When set to {@code
+ * "none"}, Playwright does not scroll the element and the action fails if the element is not already in the viewport. This
+ * is useful to assert that an element is reachable by the user without additional scrolling.
+ */
+ public ScrollMode scroll;
/**
* When true, the call requires selector to resolve to a single element. If given selector resolves to more than one
* element, the call throws an exception.
@@ -2022,6 +2131,16 @@ public TapOptions setPosition(Position position) {
this.position = position;
return this;
}
+ /**
+ * Controls whether Playwright scrolls the element into view before performing the action. Defaults to {@code "auto"},
+ * which scrolls the element into view when necessary, including scrolling nested scrollable containers. When set to {@code
+ * "none"}, Playwright does not scroll the element and the action fails if the element is not already in the viewport. This
+ * is useful to assert that an element is reachable by the user without additional scrolling.
+ */
+ public TapOptions setScroll(ScrollMode scroll) {
+ this.scroll = scroll;
+ return this;
+ }
/**
* When true, the call requires selector to resolve to a single element. If given selector resolves to more than one
* element, the call throws an exception.
@@ -2154,6 +2273,13 @@ class UncheckOptions {
* element.
*/
public Position position;
+ /**
+ * Controls whether Playwright scrolls the element into view before performing the action. Defaults to {@code "auto"},
+ * which scrolls the element into view when necessary, including scrolling nested scrollable containers. When set to {@code
+ * "none"}, Playwright does not scroll the element and the action fails if the element is not already in the viewport. This
+ * is useful to assert that an element is reachable by the user without additional scrolling.
+ */
+ public ScrollMode scroll;
/**
* When true, the call requires selector to resolve to a single element. If given selector resolves to more than one
* element, the call throws an exception.
@@ -2203,6 +2329,16 @@ public UncheckOptions setPosition(Position position) {
this.position = position;
return this;
}
+ /**
+ * Controls whether Playwright scrolls the element into view before performing the action. Defaults to {@code "auto"},
+ * which scrolls the element into view when necessary, including scrolling nested scrollable containers. When set to {@code
+ * "none"}, Playwright does not scroll the element and the action fails if the element is not already in the viewport. This
+ * is useful to assert that an element is reachable by the user without additional scrolling.
+ */
+ public UncheckOptions setScroll(ScrollMode scroll) {
+ this.scroll = scroll;
+ return this;
+ }
/**
* When true, the call requires selector to resolve to a single element. If given selector resolves to more than one
* element, the call throws an exception.
diff --git a/playwright/src/main/java/com/microsoft/playwright/Locator.java b/playwright/src/main/java/com/microsoft/playwright/Locator.java
index b0eb27f08..5b997bac9 100644
--- a/playwright/src/main/java/com/microsoft/playwright/Locator.java
+++ b/playwright/src/main/java/com/microsoft/playwright/Locator.java
@@ -145,6 +145,13 @@ class CheckOptions {
* element.
*/
public Position position;
+ /**
+ * Controls whether Playwright scrolls the element into view before performing the action. Defaults to {@code "auto"},
+ * which scrolls the element into view when necessary, including scrolling nested scrollable containers. When set to {@code
+ * "none"}, Playwright does not scroll the element and the action fails if the element is not already in the viewport. This
+ * is useful to assert that an element is reachable by the user without additional scrolling.
+ */
+ public ScrollMode scroll;
/**
* Maximum time in milliseconds. Defaults to {@code 30000} (30 seconds). Pass {@code 0} to disable timeout. The default
* value can be changed by using the {@link com.microsoft.playwright.BrowserContext#setDefaultTimeout
@@ -189,6 +196,16 @@ public CheckOptions setPosition(Position position) {
this.position = position;
return this;
}
+ /**
+ * Controls whether Playwright scrolls the element into view before performing the action. Defaults to {@code "auto"},
+ * which scrolls the element into view when necessary, including scrolling nested scrollable containers. When set to {@code
+ * "none"}, Playwright does not scroll the element and the action fails if the element is not already in the viewport. This
+ * is useful to assert that an element is reachable by the user without additional scrolling.
+ */
+ public CheckOptions setScroll(ScrollMode scroll) {
+ this.scroll = scroll;
+ return this;
+ }
/**
* Maximum time in milliseconds. Defaults to {@code 30000} (30 seconds). Pass {@code 0} to disable timeout. The default
* value can be changed by using the {@link com.microsoft.playwright.BrowserContext#setDefaultTimeout
@@ -286,6 +303,13 @@ class ClickOptions {
* element.
*/
public Position position;
+ /**
+ * Controls whether Playwright scrolls the element into view before performing the action. Defaults to {@code "auto"},
+ * which scrolls the element into view when necessary, including scrolling nested scrollable containers. When set to {@code
+ * "none"}, Playwright does not scroll the element and the action fails if the element is not already in the viewport. This
+ * is useful to assert that an element is reachable by the user without additional scrolling.
+ */
+ public ScrollMode scroll;
/**
* Defaults to 1. Sends {@code n} interpolated {@code mousemove} events to represent travel between Playwright's current
* cursor position and the provided destination. When set to 1, emits a single {@code mousemove} event at the destination
@@ -367,6 +391,16 @@ public ClickOptions setPosition(Position position) {
this.position = position;
return this;
}
+ /**
+ * Controls whether Playwright scrolls the element into view before performing the action. Defaults to {@code "auto"},
+ * which scrolls the element into view when necessary, including scrolling nested scrollable containers. When set to {@code
+ * "none"}, Playwright does not scroll the element and the action fails if the element is not already in the viewport. This
+ * is useful to assert that an element is reachable by the user without additional scrolling.
+ */
+ public ClickOptions setScroll(ScrollMode scroll) {
+ this.scroll = scroll;
+ return this;
+ }
/**
* Defaults to 1. Sends {@code n} interpolated {@code mousemove} events to represent travel between Playwright's current
* cursor position and the provided destination. When set to 1, emits a single {@code mousemove} event at the destination
@@ -426,6 +460,13 @@ class DblclickOptions {
* element.
*/
public Position position;
+ /**
+ * Controls whether Playwright scrolls the element into view before performing the action. Defaults to {@code "auto"},
+ * which scrolls the element into view when necessary, including scrolling nested scrollable containers. When set to {@code
+ * "none"}, Playwright does not scroll the element and the action fails if the element is not already in the viewport. This
+ * is useful to assert that an element is reachable by the user without additional scrolling.
+ */
+ public ScrollMode scroll;
/**
* Defaults to 1. Sends {@code n} interpolated {@code mousemove} events to represent travel between Playwright's current
* cursor position and the provided destination. When set to 1, emits a single {@code mousemove} event at the destination
@@ -500,6 +541,16 @@ public DblclickOptions setPosition(Position position) {
this.position = position;
return this;
}
+ /**
+ * Controls whether Playwright scrolls the element into view before performing the action. Defaults to {@code "auto"},
+ * which scrolls the element into view when necessary, including scrolling nested scrollable containers. When set to {@code
+ * "none"}, Playwright does not scroll the element and the action fails if the element is not already in the viewport. This
+ * is useful to assert that an element is reachable by the user without additional scrolling.
+ */
+ public DblclickOptions setScroll(ScrollMode scroll) {
+ this.scroll = scroll;
+ return this;
+ }
/**
* Defaults to 1. Sends {@code n} interpolated {@code mousemove} events to represent travel between Playwright's current
* cursor position and the provided destination. When set to 1, emits a single {@code mousemove} event at the destination
@@ -560,6 +611,13 @@ class DragToOptions {
* @deprecated This option has no effect.
*/
public Boolean noWaitAfter;
+ /**
+ * Controls whether Playwright scrolls the element into view before performing the action. Defaults to {@code "auto"},
+ * which scrolls the element into view when necessary, including scrolling nested scrollable containers. When set to {@code
+ * "none"}, Playwright does not scroll the element and the action fails if the element is not already in the viewport. This
+ * is useful to assert that an element is reachable by the user without additional scrolling.
+ */
+ public ScrollMode scroll;
/**
* Clicks on the source element at this point relative to the top-left corner of the element's padding box. If not
* specified, some visible point of the element is used.
@@ -604,6 +662,16 @@ public DragToOptions setNoWaitAfter(boolean noWaitAfter) {
this.noWaitAfter = noWaitAfter;
return this;
}
+ /**
+ * Controls whether Playwright scrolls the element into view before performing the action. Defaults to {@code "auto"},
+ * which scrolls the element into view when necessary, including scrolling nested scrollable containers. When set to {@code
+ * "none"}, Playwright does not scroll the element and the action fails if the element is not already in the viewport. This
+ * is useful to assert that an element is reachable by the user without additional scrolling.
+ */
+ public DragToOptions setScroll(ScrollMode scroll) {
+ this.scroll = scroll;
+ return this;
+ }
/**
* Clicks on the source element at this point relative to the top-left corner of the element's padding box. If not
* specified, some visible point of the element is used.
@@ -1241,6 +1309,13 @@ class HoverOptions {
* element.
*/
public Position position;
+ /**
+ * Controls whether Playwright scrolls the element into view before performing the action. Defaults to {@code "auto"},
+ * which scrolls the element into view when necessary, including scrolling nested scrollable containers. When set to {@code
+ * "none"}, Playwright does not scroll the element and the action fails if the element is not already in the viewport. This
+ * is useful to assert that an element is reachable by the user without additional scrolling.
+ */
+ public ScrollMode scroll;
/**
* Maximum time in milliseconds. Defaults to {@code 30000} (30 seconds). Pass {@code 0} to disable timeout. The default
* value can be changed by using the {@link com.microsoft.playwright.BrowserContext#setDefaultTimeout
@@ -1295,6 +1370,16 @@ public HoverOptions setPosition(Position position) {
this.position = position;
return this;
}
+ /**
+ * Controls whether Playwright scrolls the element into view before performing the action. Defaults to {@code "auto"},
+ * which scrolls the element into view when necessary, including scrolling nested scrollable containers. When set to {@code
+ * "none"}, Playwright does not scroll the element and the action fails if the element is not already in the viewport. This
+ * is useful to assert that an element is reachable by the user without additional scrolling.
+ */
+ public HoverOptions setScroll(ScrollMode scroll) {
+ this.scroll = scroll;
+ return this;
+ }
/**
* Maximum time in milliseconds. Defaults to {@code 30000} (30 seconds). Pass {@code 0} to disable timeout. The default
* value can be changed by using the {@link com.microsoft.playwright.BrowserContext#setDefaultTimeout
@@ -1710,7 +1795,9 @@ class ScreenshotOptions {
*/
public Path path;
/**
- * The quality of the image, between 0-100. Not applicable to {@code png} images.
+ * The quality of the image, between 0-100. Not applicable to {@code png} images. For {@code jpeg} the default is {@code
+ * 80}. For {@code webp}, a quality of {@code 100} (the default) produces a lossless image, while lower values use lossy
+ * compression.
*/
public Integer quality;
/**
@@ -1798,7 +1885,9 @@ public ScreenshotOptions setPath(Path path) {
return this;
}
/**
- * The quality of the image, between 0-100. Not applicable to {@code png} images.
+ * The quality of the image, between 0-100. Not applicable to {@code png} images. For {@code jpeg} the default is {@code
+ * 80}. For {@code webp}, a quality of {@code 100} (the default) produces a lossless image, while lower values use lossy
+ * compression.
*/
public ScreenshotOptions setQuality(int quality) {
this.quality = quality;
@@ -1954,6 +2043,13 @@ class SetCheckedOptions {
* element.
*/
public Position position;
+ /**
+ * Controls whether Playwright scrolls the element into view before performing the action. Defaults to {@code "auto"},
+ * which scrolls the element into view when necessary, including scrolling nested scrollable containers. When set to {@code
+ * "none"}, Playwright does not scroll the element and the action fails if the element is not already in the viewport. This
+ * is useful to assert that an element is reachable by the user without additional scrolling.
+ */
+ public ScrollMode scroll;
/**
* Maximum time in milliseconds. Defaults to {@code 30000} (30 seconds). Pass {@code 0} to disable timeout. The default
* value can be changed by using the {@link com.microsoft.playwright.BrowserContext#setDefaultTimeout
@@ -1998,6 +2094,16 @@ public SetCheckedOptions setPosition(Position position) {
this.position = position;
return this;
}
+ /**
+ * Controls whether Playwright scrolls the element into view before performing the action. Defaults to {@code "auto"},
+ * which scrolls the element into view when necessary, including scrolling nested scrollable containers. When set to {@code
+ * "none"}, Playwright does not scroll the element and the action fails if the element is not already in the viewport. This
+ * is useful to assert that an element is reachable by the user without additional scrolling.
+ */
+ public SetCheckedOptions setScroll(ScrollMode scroll) {
+ this.scroll = scroll;
+ return this;
+ }
/**
* Maximum time in milliseconds. Defaults to {@code 30000} (30 seconds). Pass {@code 0} to disable timeout. The default
* value can be changed by using the {@link com.microsoft.playwright.BrowserContext#setDefaultTimeout
@@ -2070,6 +2176,13 @@ class TapOptions {
* element.
*/
public Position position;
+ /**
+ * Controls whether Playwright scrolls the element into view before performing the action. Defaults to {@code "auto"},
+ * which scrolls the element into view when necessary, including scrolling nested scrollable containers. When set to {@code
+ * "none"}, Playwright does not scroll the element and the action fails if the element is not already in the viewport. This
+ * is useful to assert that an element is reachable by the user without additional scrolling.
+ */
+ public ScrollMode scroll;
/**
* Maximum time in milliseconds. Defaults to {@code 30000} (30 seconds). Pass {@code 0} to disable timeout. The default
* value can be changed by using the {@link com.microsoft.playwright.BrowserContext#setDefaultTimeout
@@ -2124,6 +2237,16 @@ public TapOptions setPosition(Position position) {
this.position = position;
return this;
}
+ /**
+ * Controls whether Playwright scrolls the element into view before performing the action. Defaults to {@code "auto"},
+ * which scrolls the element into view when necessary, including scrolling nested scrollable containers. When set to {@code
+ * "none"}, Playwright does not scroll the element and the action fails if the element is not already in the viewport. This
+ * is useful to assert that an element is reachable by the user without additional scrolling.
+ */
+ public TapOptions setScroll(ScrollMode scroll) {
+ this.scroll = scroll;
+ return this;
+ }
/**
* Maximum time in milliseconds. Defaults to {@code 30000} (30 seconds). Pass {@code 0} to disable timeout. The default
* value can be changed by using the {@link com.microsoft.playwright.BrowserContext#setDefaultTimeout
@@ -2222,6 +2345,13 @@ class UncheckOptions {
* element.
*/
public Position position;
+ /**
+ * Controls whether Playwright scrolls the element into view before performing the action. Defaults to {@code "auto"},
+ * which scrolls the element into view when necessary, including scrolling nested scrollable containers. When set to {@code
+ * "none"}, Playwright does not scroll the element and the action fails if the element is not already in the viewport. This
+ * is useful to assert that an element is reachable by the user without additional scrolling.
+ */
+ public ScrollMode scroll;
/**
* Maximum time in milliseconds. Defaults to {@code 30000} (30 seconds). Pass {@code 0} to disable timeout. The default
* value can be changed by using the {@link com.microsoft.playwright.BrowserContext#setDefaultTimeout
@@ -2266,6 +2396,16 @@ public UncheckOptions setPosition(Position position) {
this.position = position;
return this;
}
+ /**
+ * Controls whether Playwright scrolls the element into view before performing the action. Defaults to {@code "auto"},
+ * which scrolls the element into view when necessary, including scrolling nested scrollable containers. When set to {@code
+ * "none"}, Playwright does not scroll the element and the action fails if the element is not already in the viewport. This
+ * is useful to assert that an element is reachable by the user without additional scrolling.
+ */
+ public UncheckOptions setScroll(ScrollMode scroll) {
+ this.scroll = scroll;
+ return this;
+ }
/**
* Maximum time in milliseconds. Defaults to {@code 30000} (30 seconds). Pass {@code 0} to disable timeout. The default
* value can be changed by using the {@link com.microsoft.playwright.BrowserContext#setDefaultTimeout
@@ -2333,6 +2473,26 @@ public WaitForOptions setTimeout(double timeout) {
return this;
}
}
+ class WaitForFunctionOptions {
+ /**
+ * Maximum time to wait for in milliseconds. Defaults to {@code 30000} (30 seconds). Pass {@code 0} to disable timeout. The
+ * default value can be changed by using the {@link com.microsoft.playwright.BrowserContext#setDefaultTimeout
+ * BrowserContext.setDefaultTimeout()} or {@link com.microsoft.playwright.Page#setDefaultTimeout Page.setDefaultTimeout()}
+ * methods.
+ */
+ public Double timeout;
+
+ /**
+ * Maximum time to wait for in milliseconds. Defaults to {@code 30000} (30 seconds). Pass {@code 0} to disable timeout. The
+ * default value can be changed by using the {@link com.microsoft.playwright.BrowserContext#setDefaultTimeout
+ * BrowserContext.setDefaultTimeout()} or {@link com.microsoft.playwright.Page#setDefaultTimeout Page.setDefaultTimeout()}
+ * methods.
+ */
+ public WaitForFunctionOptions setTimeout(double timeout) {
+ this.timeout = timeout;
+ return this;
+ }
+ }
/**
* When the locator points to a list of elements, this returns an array of locators, pointing to their respective elements.
*
@@ -5696,5 +5856,83 @@ default void waitFor() {
* @since v1.16
*/
void waitFor(WaitForOptions options);
+ /**
+ * Returns when {@code expression} returns a truthy value, called with the matching element as a first argument, and {@code
+ * arg} as a second argument.
+ *
+ *
This is a generic way to wait for an element to reach a custom condition without asserting it. The locator is
+ * re-resolved on each retry, so it tolerates the element being re-rendered while waiting.
+ *
+ *
If {@code expression} returns a Promise, this method
+ * will wait for the promise to resolve before checking its value.
+ *
+ *
If {@code expression} throws or rejects, this method throws.
+ *
+ *
Usage
+ *
+ *
Wait for an attribute to appear:
+ *
+ *
Passing argument to {@code expression}:
+ *
+ * @param expression JavaScript expression to be evaluated in the browser context. If the expression evaluates to a function, the function is
+ * automatically invoked.
+ * @param arg Optional argument to pass to {@code expression}.
+ * @since v1.62
+ */
+ default void waitForFunction(String expression, Object arg) {
+ waitForFunction(expression, arg, null);
+ }
+ /**
+ * Returns when {@code expression} returns a truthy value, called with the matching element as a first argument, and {@code
+ * arg} as a second argument.
+ *
+ *
This is a generic way to wait for an element to reach a custom condition without asserting it. The locator is
+ * re-resolved on each retry, so it tolerates the element being re-rendered while waiting.
+ *
+ *
If {@code expression} returns a Promise, this method
+ * will wait for the promise to resolve before checking its value.
+ *
+ *
If {@code expression} throws or rejects, this method throws.
+ *
+ *
Usage
+ *
+ *
Wait for an attribute to appear:
+ *
+ *
Passing argument to {@code expression}:
+ *
+ * @param expression JavaScript expression to be evaluated in the browser context. If the expression evaluates to a function, the function is
+ * automatically invoked.
+ * @since v1.62
+ */
+ default void waitForFunction(String expression) {
+ waitForFunction(expression, null);
+ }
+ /**
+ * Returns when {@code expression} returns a truthy value, called with the matching element as a first argument, and {@code
+ * arg} as a second argument.
+ *
+ *
This is a generic way to wait for an element to reach a custom condition without asserting it. The locator is
+ * re-resolved on each retry, so it tolerates the element being re-rendered while waiting.
+ *
+ *
If {@code expression} returns a Promise, this method
+ * will wait for the promise to resolve before checking its value.
+ *
+ *
If {@code expression} throws or rejects, this method throws.
+ *
+ *
Usage
+ *
+ *
Wait for an attribute to appear:
+ *
+ *
Passing argument to {@code expression}:
+ *
+ * @param expression JavaScript expression to be evaluated in the browser context. If the expression evaluates to a function, the function is
+ * automatically invoked.
+ * @param arg Optional argument to pass to {@code expression}.
+ * @since v1.62
+ */
+ void waitForFunction(String expression, Object arg, WaitForFunctionOptions options);
}
diff --git a/playwright/src/main/java/com/microsoft/playwright/Page.java b/playwright/src/main/java/com/microsoft/playwright/Page.java
index db240171f..9d1295c43 100644
--- a/playwright/src/main/java/com/microsoft/playwright/Page.java
+++ b/playwright/src/main/java/com/microsoft/playwright/Page.java
@@ -435,6 +435,13 @@ class CheckOptions {
* element.
*/
public Position position;
+ /**
+ * Controls whether Playwright scrolls the element into view before performing the action. Defaults to {@code "auto"},
+ * which scrolls the element into view when necessary, including scrolling nested scrollable containers. When set to {@code
+ * "none"}, Playwright does not scroll the element and the action fails if the element is not already in the viewport. This
+ * is useful to assert that an element is reachable by the user without additional scrolling.
+ */
+ public ScrollMode scroll;
/**
* When true, the call requires selector to resolve to a single element. If given selector resolves to more than one
* element, the call throws an exception.
@@ -484,6 +491,16 @@ public CheckOptions setPosition(Position position) {
this.position = position;
return this;
}
+ /**
+ * Controls whether Playwright scrolls the element into view before performing the action. Defaults to {@code "auto"},
+ * which scrolls the element into view when necessary, including scrolling nested scrollable containers. When set to {@code
+ * "none"}, Playwright does not scroll the element and the action fails if the element is not already in the viewport. This
+ * is useful to assert that an element is reachable by the user without additional scrolling.
+ */
+ public CheckOptions setScroll(ScrollMode scroll) {
+ this.scroll = scroll;
+ return this;
+ }
/**
* When true, the call requires selector to resolve to a single element. If given selector resolves to more than one
* element, the call throws an exception.
@@ -545,6 +562,13 @@ class ClickOptions {
* element.
*/
public Position position;
+ /**
+ * Controls whether Playwright scrolls the element into view before performing the action. Defaults to {@code "auto"},
+ * which scrolls the element into view when necessary, including scrolling nested scrollable containers. When set to {@code
+ * "none"}, Playwright does not scroll the element and the action fails if the element is not already in the viewport. This
+ * is useful to assert that an element is reachable by the user without additional scrolling.
+ */
+ public ScrollMode scroll;
/**
* When true, the call requires selector to resolve to a single element. If given selector resolves to more than one
* element, the call throws an exception.
@@ -625,6 +649,16 @@ public ClickOptions setPosition(Position position) {
this.position = position;
return this;
}
+ /**
+ * Controls whether Playwright scrolls the element into view before performing the action. Defaults to {@code "auto"},
+ * which scrolls the element into view when necessary, including scrolling nested scrollable containers. When set to {@code
+ * "none"}, Playwright does not scroll the element and the action fails if the element is not already in the viewport. This
+ * is useful to assert that an element is reachable by the user without additional scrolling.
+ */
+ public ClickOptions setScroll(ScrollMode scroll) {
+ this.scroll = scroll;
+ return this;
+ }
/**
* When true, the call requires selector to resolve to a single element. If given selector resolves to more than one
* element, the call throws an exception.
@@ -710,6 +744,13 @@ class DblclickOptions {
* element.
*/
public Position position;
+ /**
+ * Controls whether Playwright scrolls the element into view before performing the action. Defaults to {@code "auto"},
+ * which scrolls the element into view when necessary, including scrolling nested scrollable containers. When set to {@code
+ * "none"}, Playwright does not scroll the element and the action fails if the element is not already in the viewport. This
+ * is useful to assert that an element is reachable by the user without additional scrolling.
+ */
+ public ScrollMode scroll;
/**
* When true, the call requires selector to resolve to a single element. If given selector resolves to more than one
* element, the call throws an exception.
@@ -783,6 +824,16 @@ public DblclickOptions setPosition(Position position) {
this.position = position;
return this;
}
+ /**
+ * Controls whether Playwright scrolls the element into view before performing the action. Defaults to {@code "auto"},
+ * which scrolls the element into view when necessary, including scrolling nested scrollable containers. When set to {@code
+ * "none"}, Playwright does not scroll the element and the action fails if the element is not already in the viewport. This
+ * is useful to assert that an element is reachable by the user without additional scrolling.
+ */
+ public DblclickOptions setScroll(ScrollMode scroll) {
+ this.scroll = scroll;
+ return this;
+ }
/**
* When true, the call requires selector to resolve to a single element. If given selector resolves to more than one
* element, the call throws an exception.
@@ -855,6 +906,13 @@ class DragAndDropOptions {
* @deprecated This option has no effect.
*/
public Boolean noWaitAfter;
+ /**
+ * Controls whether Playwright scrolls the element into view before performing the action. Defaults to {@code "auto"},
+ * which scrolls the element into view when necessary, including scrolling nested scrollable containers. When set to {@code
+ * "none"}, Playwright does not scroll the element and the action fails if the element is not already in the viewport. This
+ * is useful to assert that an element is reachable by the user without additional scrolling.
+ */
+ public ScrollMode scroll;
/**
* Clicks on the source element at this point relative to the top-left corner of the element's padding box. If not
* specified, some visible point of the element is used.
@@ -904,6 +962,16 @@ public DragAndDropOptions setNoWaitAfter(boolean noWaitAfter) {
this.noWaitAfter = noWaitAfter;
return this;
}
+ /**
+ * Controls whether Playwright scrolls the element into view before performing the action. Defaults to {@code "auto"},
+ * which scrolls the element into view when necessary, including scrolling nested scrollable containers. When set to {@code
+ * "none"}, Playwright does not scroll the element and the action fails if the element is not already in the viewport. This
+ * is useful to assert that an element is reachable by the user without additional scrolling.
+ */
+ public DragAndDropOptions setScroll(ScrollMode scroll) {
+ this.scroll = scroll;
+ return this;
+ }
/**
* Clicks on the source element at this point relative to the top-left corner of the element's padding box. If not
* specified, some visible point of the element is used.
@@ -1623,6 +1691,13 @@ class HoverOptions {
* element.
*/
public Position position;
+ /**
+ * Controls whether Playwright scrolls the element into view before performing the action. Defaults to {@code "auto"},
+ * which scrolls the element into view when necessary, including scrolling nested scrollable containers. When set to {@code
+ * "none"}, Playwright does not scroll the element and the action fails if the element is not already in the viewport. This
+ * is useful to assert that an element is reachable by the user without additional scrolling.
+ */
+ public ScrollMode scroll;
/**
* When true, the call requires selector to resolve to a single element. If given selector resolves to more than one
* element, the call throws an exception.
@@ -1682,6 +1757,16 @@ public HoverOptions setPosition(Position position) {
this.position = position;
return this;
}
+ /**
+ * Controls whether Playwright scrolls the element into view before performing the action. Defaults to {@code "auto"},
+ * which scrolls the element into view when necessary, including scrolling nested scrollable containers. When set to {@code
+ * "none"}, Playwright does not scroll the element and the action fails if the element is not already in the viewport. This
+ * is useful to assert that an element is reachable by the user without additional scrolling.
+ */
+ public HoverOptions setScroll(ScrollMode scroll) {
+ this.scroll = scroll;
+ return this;
+ }
/**
* When true, the call requires selector to resolve to a single element. If given selector resolves to more than one
* element, the call throws an exception.
@@ -2598,7 +2683,9 @@ class ScreenshotOptions {
*/
public Path path;
/**
- * The quality of the image, between 0-100. Not applicable to {@code png} images.
+ * The quality of the image, between 0-100. Not applicable to {@code png} images. For {@code jpeg} the default is {@code
+ * 80}. For {@code webp}, a quality of {@code 100} (the default) produces a lossless image, while lower values use lossy
+ * compression.
*/
public Integer quality;
/**
@@ -2707,7 +2794,9 @@ public ScreenshotOptions setPath(Path path) {
return this;
}
/**
- * The quality of the image, between 0-100. Not applicable to {@code png} images.
+ * The quality of the image, between 0-100. Not applicable to {@code png} images. For {@code jpeg} the default is {@code
+ * 80}. For {@code webp}, a quality of {@code 100} (the default) produces a lossless image, while lower values use lossy
+ * compression.
*/
public ScreenshotOptions setQuality(int quality) {
this.quality = quality;
@@ -2823,6 +2912,13 @@ class SetCheckedOptions {
* element.
*/
public Position position;
+ /**
+ * Controls whether Playwright scrolls the element into view before performing the action. Defaults to {@code "auto"},
+ * which scrolls the element into view when necessary, including scrolling nested scrollable containers. When set to {@code
+ * "none"}, Playwright does not scroll the element and the action fails if the element is not already in the viewport. This
+ * is useful to assert that an element is reachable by the user without additional scrolling.
+ */
+ public ScrollMode scroll;
/**
* When true, the call requires selector to resolve to a single element. If given selector resolves to more than one
* element, the call throws an exception.
@@ -2872,6 +2968,16 @@ public SetCheckedOptions setPosition(Position position) {
this.position = position;
return this;
}
+ /**
+ * Controls whether Playwright scrolls the element into view before performing the action. Defaults to {@code "auto"},
+ * which scrolls the element into view when necessary, including scrolling nested scrollable containers. When set to {@code
+ * "none"}, Playwright does not scroll the element and the action fails if the element is not already in the viewport. This
+ * is useful to assert that an element is reachable by the user without additional scrolling.
+ */
+ public SetCheckedOptions setScroll(ScrollMode scroll) {
+ this.scroll = scroll;
+ return this;
+ }
/**
* When true, the call requires selector to resolve to a single element. If given selector resolves to more than one
* element, the call throws an exception.
@@ -3075,6 +3181,13 @@ class TapOptions {
* element.
*/
public Position position;
+ /**
+ * Controls whether Playwright scrolls the element into view before performing the action. Defaults to {@code "auto"},
+ * which scrolls the element into view when necessary, including scrolling nested scrollable containers. When set to {@code
+ * "none"}, Playwright does not scroll the element and the action fails if the element is not already in the viewport. This
+ * is useful to assert that an element is reachable by the user without additional scrolling.
+ */
+ public ScrollMode scroll;
/**
* When true, the call requires selector to resolve to a single element. If given selector resolves to more than one
* element, the call throws an exception.
@@ -3134,6 +3247,16 @@ public TapOptions setPosition(Position position) {
this.position = position;
return this;
}
+ /**
+ * Controls whether Playwright scrolls the element into view before performing the action. Defaults to {@code "auto"},
+ * which scrolls the element into view when necessary, including scrolling nested scrollable containers. When set to {@code
+ * "none"}, Playwright does not scroll the element and the action fails if the element is not already in the viewport. This
+ * is useful to assert that an element is reachable by the user without additional scrolling.
+ */
+ public TapOptions setScroll(ScrollMode scroll) {
+ this.scroll = scroll;
+ return this;
+ }
/**
* When true, the call requires selector to resolve to a single element. If given selector resolves to more than one
* element, the call throws an exception.
@@ -3266,6 +3389,13 @@ class UncheckOptions {
* element.
*/
public Position position;
+ /**
+ * Controls whether Playwright scrolls the element into view before performing the action. Defaults to {@code "auto"},
+ * which scrolls the element into view when necessary, including scrolling nested scrollable containers. When set to {@code
+ * "none"}, Playwright does not scroll the element and the action fails if the element is not already in the viewport. This
+ * is useful to assert that an element is reachable by the user without additional scrolling.
+ */
+ public ScrollMode scroll;
/**
* When true, the call requires selector to resolve to a single element. If given selector resolves to more than one
* element, the call throws an exception.
@@ -3315,6 +3445,16 @@ public UncheckOptions setPosition(Position position) {
this.position = position;
return this;
}
+ /**
+ * Controls whether Playwright scrolls the element into view before performing the action. Defaults to {@code "auto"},
+ * which scrolls the element into view when necessary, including scrolling nested scrollable containers. When set to {@code
+ * "none"}, Playwright does not scroll the element and the action fails if the element is not already in the viewport. This
+ * is useful to assert that an element is reachable by the user without additional scrolling.
+ */
+ public UncheckOptions setScroll(ScrollMode scroll) {
+ this.scroll = scroll;
+ return this;
+ }
/**
* When true, the call requires selector to resolve to a single element. If given selector resolves to more than one
* element, the call throws an exception.
@@ -5464,6 +5604,11 @@ default Locator getByTitle(Pattern text) {
*
*
Navigate to the previous page in history.
*
+ *
NOTE: **Testing Back/Forward Cache (BFCache) is not supported.** By default, Playwright disables the Back/Forward Cache
+ * across all browsers. Even if explicitly enabled, Playwright's internal state relies on network-level navigation events.
+ * Because BFCache restores unfreeze the DOM without firing these events, using {@code page.goBack()} or {@code
+ * page.goForward()} to trigger a BFCache restore will result in timeouts and a desynchronized {@code Page} state.
+ *
* @since v1.8
*/
default Response goBack() {
@@ -5475,6 +5620,11 @@ default Response goBack() {
*
*
Navigate to the previous page in history.
*
+ *
NOTE: **Testing Back/Forward Cache (BFCache) is not supported.** By default, Playwright disables the Back/Forward Cache
+ * across all browsers. Even if explicitly enabled, Playwright's internal state relies on network-level navigation events.
+ * Because BFCache restores unfreeze the DOM without firing these events, using {@code page.goBack()} or {@code
+ * page.goForward()} to trigger a BFCache restore will result in timeouts and a desynchronized {@code Page} state.
+ *
* @since v1.8
*/
Response goBack(GoBackOptions options);
@@ -5484,6 +5634,11 @@ default Response goBack() {
*
*
Navigate to the next page in history.
*
+ *
NOTE: **Testing Back/Forward Cache (BFCache) is not supported.** By default, Playwright disables the Back/Forward Cache
+ * across all browsers. Even if explicitly enabled, Playwright's internal state relies on network-level navigation events.
+ * Because BFCache restores unfreeze the DOM without firing these events, using {@code page.goBack()} or {@code
+ * page.goForward()} to trigger a BFCache restore will result in timeouts and a desynchronized {@code Page} state.
+ *
* @since v1.8
*/
default Response goForward() {
@@ -5495,6 +5650,11 @@ default Response goForward() {
*
*
Navigate to the next page in history.
*
+ *
NOTE: **Testing Back/Forward Cache (BFCache) is not supported.** By default, Playwright disables the Back/Forward Cache
+ * across all browsers. Even if explicitly enabled, Playwright's internal state relies on network-level navigation events.
+ * Because BFCache restores unfreeze the DOM without firing these events, using {@code page.goBack()} or {@code
+ * page.goForward()} to trigger a BFCache restore will result in timeouts and a desynchronized {@code Page} state.
+ *
* @since v1.8
*/
Response goForward(GoForwardOptions options);
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 385aca2c8..21f96b2cb 100644
--- a/playwright/src/main/java/com/microsoft/playwright/impl/APIResponseImpl.java
+++ b/playwright/src/main/java/com/microsoft/playwright/impl/APIResponseImpl.java
@@ -24,6 +24,7 @@
import com.microsoft.playwright.options.HttpHeader;
import com.microsoft.playwright.options.SecurityDetails;
import com.microsoft.playwright.options.ServerAddr;
+import com.microsoft.playwright.options.Timing;
import java.nio.charset.StandardCharsets;
import java.util.Base64;
@@ -118,6 +119,26 @@ public String text() {
return new String(body(), StandardCharsets.UTF_8);
}
+ @Override
+ public Timing timing() {
+ Timing timing;
+ if (initializer.has("timing")) {
+ timing = gson().fromJson(initializer.get("timing"), Timing.class);
+ } else {
+ timing = new Timing();
+ timing.startTime = -1;
+ timing.domainLookupStart = -1;
+ timing.domainLookupEnd = -1;
+ timing.connectStart = -1;
+ timing.secureConnectionStart = -1;
+ timing.connectEnd = -1;
+ timing.requestStart = -1;
+ timing.responseStart = -1;
+ }
+ timing.responseEnd = initializer.has("responseEndTiming") ? initializer.get("responseEndTiming").getAsDouble() : -1;
+ return timing;
+ }
+
@Override
public String url() {
return initializer.get("url").getAsString();
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 78c63f897..500e9449a 100644
--- a/playwright/src/main/java/com/microsoft/playwright/impl/BrowserContextImpl.java
+++ b/playwright/src/main/java/com/microsoft/playwright/impl/BrowserContextImpl.java
@@ -547,6 +547,9 @@ public void routeFromHAR(Path har, RouteFromHAROptions options) {
HARRouter harRouter = new HARRouter(connection.localUtils, har, options.notFound);
onClose(context -> harRouter.dispose());
route(matcher, route -> harRouter.handle(route), null);
+ if (options.interceptAPIRequests != null && options.interceptAPIRequests) {
+ harRouter.addAPIRequestRoute(this, options.url);
+ }
}
private void route(UrlMatcher matcher, Consumer handler, RouteOptions options) {
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 729c300f3..a626bfc02 100644
--- a/playwright/src/main/java/com/microsoft/playwright/impl/ChannelOwner.java
+++ b/playwright/src/main/java/com/microsoft/playwright/impl/ChannelOwner.java
@@ -125,11 +125,12 @@ JsonElement sendMessage(String method) {
JsonElement sendMessage(String method, JsonObject params, Double timeout) {
checkNotCollected();
if (timeout != null) {
- params.addProperty("timeout", timeout);
+ // Timeout is passed in the message metadata, remove potential leftover from serialized options.
+ params.remove("timeout");
} else if (params.has("timeout")) {
throw new PlaywrightException("Internal error: timeout must be passed explicitly.");
}
- return connection.sendMessage(guid, method, params);
+ return connection.sendMessage(guid, method, params, timeout);
}
private void checkNotCollected() {
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 46354abf2..b0bc2bd37 100644
--- a/playwright/src/main/java/com/microsoft/playwright/impl/Connection.java
+++ b/playwright/src/main/java/com/microsoft/playwright/impl/Connection.java
@@ -129,19 +129,23 @@ void close() throws IOException {
}
public JsonElement sendMessage(String guid, String method, JsonObject params) {
- return root.runUntil(() -> {}, sendMessageAsync(guid, method, params));
+ return sendMessage(guid, method, params, null);
+ }
+
+ public JsonElement sendMessage(String guid, String method, JsonObject params, Double timeout) {
+ return root.runUntil(() -> {}, internalSendMessage(guid, method, params, timeout, true, true));
}
public WaitableResult sendMessageAsync(String guid, String method, JsonObject params) {
- return internalSendMessage(guid, method, params, true, true);
+ return internalSendMessage(guid, method, params, null, true, true);
}
// Fire-and-forget: the server never replies.
public void sendMessageNoReply(String guid, String method, JsonObject params) {
- internalSendMessage(guid, method, params, false, false);
+ internalSendMessage(guid, method, params, null, false, false);
}
- private WaitableResult internalSendMessage(String guid, String method, JsonObject params, boolean sendStack, boolean expectsReply) {
+ private WaitableResult internalSendMessage(String guid, String method, JsonObject params, Double timeout, boolean sendStack, boolean expectsReply) {
int id = ++lastId;
WaitableResult result = new WaitableResult<>();
if (expectsReply) {
@@ -154,6 +158,9 @@ private WaitableResult internalSendMessage(String guid, String meth
message.add("params", params);
JsonObject metadata = new JsonObject();
metadata.addProperty("wallTime", currentTimeMillis());
+ if (timeout != null) {
+ metadata.addProperty("timeout", timeout);
+ }
JsonArray stack = null;
if (titleReported) {
metadata.addProperty("internal", true);
@@ -183,7 +190,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, true);
+ internalSendMessage(localUtils.guid,"addStackToTracingNoReply", stackParams, null, false, true);
}
return result;
}
diff --git a/playwright/src/main/java/com/microsoft/playwright/impl/ElementHandleImpl.java b/playwright/src/main/java/com/microsoft/playwright/impl/ElementHandleImpl.java
index a8b6667bc..a9e293896 100644
--- a/playwright/src/main/java/com/microsoft/playwright/impl/ElementHandleImpl.java
+++ b/playwright/src/main/java/com/microsoft/playwright/impl/ElementHandleImpl.java
@@ -38,6 +38,7 @@
import static com.microsoft.playwright.impl.Utils.addFilePathUploadParams;
import static com.microsoft.playwright.options.ScreenshotType.JPEG;
import static com.microsoft.playwright.options.ScreenshotType.PNG;
+import static com.microsoft.playwright.options.ScreenshotType.WEBP;
public class ElementHandleImpl extends JSHandleImpl implements ElementHandle {
private final FrameImpl frame;
@@ -278,6 +279,8 @@ public byte[] screenshot(ScreenshotOptions options) {
String extension = fileName.substring(extStart).toLowerCase();
if (".jpeg".equals(extension) || ".jpg".equals(extension)) {
options.type = JPEG;
+ } else if (".webp".equals(extension)) {
+ options.type = WEBP;
}
}
}
diff --git a/playwright/src/main/java/com/microsoft/playwright/impl/HARRouter.java b/playwright/src/main/java/com/microsoft/playwright/impl/HARRouter.java
index c932cc99c..4ceeda0f1 100644
--- a/playwright/src/main/java/com/microsoft/playwright/impl/HARRouter.java
+++ b/playwright/src/main/java/com/microsoft/playwright/impl/HARRouter.java
@@ -25,18 +25,23 @@
import com.microsoft.playwright.options.HarNotFound;
import java.nio.file.Path;
+import java.util.ArrayList;
import java.util.Base64;
+import java.util.List;
import java.util.Map;
+import java.util.regex.Pattern;
import static com.microsoft.playwright.impl.ChannelOwner.NO_TIMEOUT;
import static com.microsoft.playwright.impl.LoggingSupport.*;
import static com.microsoft.playwright.impl.Serialization.fromNameValues;
import static com.microsoft.playwright.impl.Serialization.gson;
+import static com.microsoft.playwright.impl.Utils.toJsRegexFlags;
public class HARRouter {
private final LocalUtils localUtils;
private final HarNotFound defaultAction;
private final String harId;
+ private final List> apiRequestRegistrations = new ArrayList<>();
HARRouter(LocalUtils localUtils, Path harFile, HarNotFound defaultAction) {
this.localUtils = localUtils;
@@ -51,6 +56,21 @@ public class HARRouter {
harId = json.get("harId").getAsString();
}
+ void addAPIRequestRoute(BrowserContextImpl context, Object url) {
+ JsonObject params = new JsonObject();
+ params.addProperty("harId", harId);
+ if (url instanceof String) {
+ params.addProperty("urlGlob", (String) url);
+ } else if (url instanceof Pattern) {
+ Pattern pattern = (Pattern) url;
+ params.addProperty("urlRegexSource", pattern.pattern());
+ params.addProperty("urlRegexFlags", toJsRegexFlags(pattern));
+ }
+ params.addProperty("notFound", defaultAction == HarNotFound.FALLBACK ? "fallback" : "abort");
+ JsonObject result = context.sendMessage("routeAPIRequestsFromHar", params, NO_TIMEOUT).getAsJsonObject();
+ apiRequestRegistrations.add(new java.util.AbstractMap.SimpleEntry<>(context, result.get("registrationId").getAsString()));
+ }
+
void handle(Route route) {
Request request = route.request();
@@ -127,6 +147,12 @@ private static Map mergeSetCookieHeaders(JsonArray headersArray)
}
void dispose() {
+ for (Map.Entry registration : apiRequestRegistrations) {
+ JsonObject unrouteParams = new JsonObject();
+ unrouteParams.addProperty("registrationId", registration.getValue());
+ registration.getKey().sendMessageAsync("unrouteAPIRequestsFromHar", unrouteParams);
+ }
+ apiRequestRegistrations.clear();
JsonObject params = new JsonObject();
params.addProperty("harId", harId);
localUtils.sendMessageAsync("harClose", params);
diff --git a/playwright/src/main/java/com/microsoft/playwright/impl/LocatorImpl.java b/playwright/src/main/java/com/microsoft/playwright/impl/LocatorImpl.java
index ba71aa5ef..38dc949b9 100644
--- a/playwright/src/main/java/com/microsoft/playwright/impl/LocatorImpl.java
+++ b/playwright/src/main/java/com/microsoft/playwright/impl/LocatorImpl.java
@@ -29,6 +29,7 @@
import static com.microsoft.playwright.impl.LocatorUtils.*;
import static com.microsoft.playwright.impl.Serialization.gson;
+import static com.microsoft.playwright.impl.Serialization.serializeArgument;
import static com.microsoft.playwright.impl.Utils.convertType;
class LocatorImpl implements Locator {
@@ -666,6 +667,16 @@ public void waitFor(WaitForOptions options) {
frame.waitForSelectorImpl(selector, convertType(options, Frame.WaitForSelectorOptions.class).setStrict(true), true);
}
+ @Override
+ public void waitForFunction(String expression, Object arg, WaitForFunctionOptions options) {
+ JsonObject params = new JsonObject();
+ params.addProperty("selector", selector);
+ params.addProperty("strict", true);
+ params.addProperty("expression", expression);
+ params.add("arg", gson().toJsonTree(serializeArgument(arg)));
+ frame.sendMessage("waitForFunction", params, frame.timeout(options == null ? null : options.timeout));
+ }
+
@Override
public String toString() {
String description = description();
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 4956ea623..aca2c8370 100644
--- a/playwright/src/main/java/com/microsoft/playwright/impl/PageImpl.java
+++ b/playwright/src/main/java/com/microsoft/playwright/impl/PageImpl.java
@@ -35,6 +35,7 @@
import static com.microsoft.playwright.impl.Utils.*;
import static com.microsoft.playwright.options.ScreenshotType.JPEG;
import static com.microsoft.playwright.options.ScreenshotType.PNG;
+import static com.microsoft.playwright.options.ScreenshotType.WEBP;
import static java.nio.charset.StandardCharsets.UTF_8;
import static java.nio.file.Files.readAllBytes;
import static java.util.Arrays.asList;
@@ -1259,6 +1260,8 @@ private byte[] screenshotImpl(ScreenshotOptions options) {
String extension = fileName.substring(extStart).toLowerCase();
if (".jpeg".equals(extension) || ".jpg".equals(extension)) {
options.type = JPEG;
+ } else if (".webp".equals(extension)) {
+ options.type = WEBP;
}
}
}
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 a9d80aab0..aba7fcd91 100644
--- a/playwright/src/main/java/com/microsoft/playwright/impl/ScreencastImpl.java
+++ b/playwright/src/main/java/com/microsoft/playwright/impl/ScreencastImpl.java
@@ -39,15 +39,21 @@ class ScreencastImpl implements Screencast {
}
void handleScreencastFrame(JsonObject params) {
- if (onFrame == null) {
- return;
+ try {
+ if (onFrame != null) {
+ 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, timestamp, viewportWidth, viewportHeight));
+ }
+ } finally {
+ // The server sends the next frame only after the previous one is acknowledged.
+ JsonObject ackParams = new JsonObject();
+ ackParams.add("frameId", params.get("frameId"));
+ page.sendMessageAsync("screencastFrameAck", ackParams);
}
- 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, timestamp, viewportWidth, viewportHeight));
}
@Override
diff --git a/playwright/src/main/java/com/microsoft/playwright/impl/Serialization.java b/playwright/src/main/java/com/microsoft/playwright/impl/Serialization.java
index 34899dfbb..d07aaf569 100644
--- a/playwright/src/main/java/com/microsoft/playwright/impl/Serialization.java
+++ b/playwright/src/main/java/com/microsoft/playwright/impl/Serialization.java
@@ -58,6 +58,7 @@ class Serialization {
.registerTypeAdapter(ScreenshotCaret.class, new ToLowerCaseSerializer())
.registerTypeAdapter(ServiceWorkerPolicy.class, new ToLowerCaseAndDashSerializer())
.registerTypeAdapter(MouseButton.class, new ToLowerCaseSerializer())
+ .registerTypeAdapter(ScrollMode.class, new ToLowerCaseSerializer())
.registerTypeAdapter(ConsoleMessagesFilter.class, new ConsoleMessagesFilterSerializer())
.registerTypeAdapter(AriaSnapshotMode.class, new ToLowerCaseSerializer())
.registerTypeAdapter(LoadState.class, new ToLowerCaseSerializer())
diff --git a/playwright/src/main/java/com/microsoft/playwright/options/ScreenshotType.java b/playwright/src/main/java/com/microsoft/playwright/options/ScreenshotType.java
index 6c21e8d8b..6914e5dee 100644
--- a/playwright/src/main/java/com/microsoft/playwright/options/ScreenshotType.java
+++ b/playwright/src/main/java/com/microsoft/playwright/options/ScreenshotType.java
@@ -18,5 +18,6 @@
public enum ScreenshotType {
PNG,
- JPEG
+ JPEG,
+ WEBP
}
\ No newline at end of file
diff --git a/playwright/src/main/java/com/microsoft/playwright/options/ScrollMode.java b/playwright/src/main/java/com/microsoft/playwright/options/ScrollMode.java
new file mode 100644
index 000000000..170ed0e12
--- /dev/null
+++ b/playwright/src/main/java/com/microsoft/playwright/options/ScrollMode.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 ScrollMode {
+ AUTO,
+ NONE
+}
\ No newline at end of file
diff --git a/playwright/src/main/java/com/microsoft/playwright/options/Timing.java b/playwright/src/main/java/com/microsoft/playwright/options/Timing.java
index 0415468d1..906539a64 100644
--- a/playwright/src/main/java/com/microsoft/playwright/options/Timing.java
+++ b/playwright/src/main/java/com/microsoft/playwright/options/Timing.java
@@ -22,42 +22,42 @@ public class Timing {
*/
public double startTime;
/**
- * Time immediately before the browser starts the domain name lookup for the resource. The value is given in milliseconds
+ * Time immediately before the client starts the domain name lookup for the resource. The value is given in milliseconds
* relative to {@code startTime}, -1 if not available.
*/
public double domainLookupStart;
/**
- * Time immediately after the browser starts the domain name lookup for the resource. The value is given in milliseconds
+ * Time immediately after the client ends the domain name lookup for the resource. The value is given in milliseconds
* relative to {@code startTime}, -1 if not available.
*/
public double domainLookupEnd;
/**
- * Time immediately before the user agent starts establishing the connection to the server to retrieve the resource. The
- * value is given in milliseconds relative to {@code startTime}, -1 if not available.
+ * Time immediately before the client starts establishing the connection to the server to retrieve the resource. The value
+ * is given in milliseconds relative to {@code startTime}, -1 if not available.
*/
public double connectStart;
/**
- * Time immediately before the browser starts the handshake process to secure the current connection. The value is given in
+ * Time immediately before the client starts the handshake process to secure the current connection. The value is given in
* milliseconds relative to {@code startTime}, -1 if not available.
*/
public double secureConnectionStart;
/**
- * Time immediately before the user agent starts establishing the connection to the server to retrieve the resource. The
- * value is given in milliseconds relative to {@code startTime}, -1 if not available.
+ * Time immediately after the client establishes the connection to the server to retrieve the resource. The value is given
+ * in milliseconds relative to {@code startTime}, -1 if not available.
*/
public double connectEnd;
/**
- * Time immediately before the browser starts requesting the resource from the server, cache, or local resource. The value
+ * Time immediately before the client starts requesting the resource from the server, cache, or local resource. The value
* is given in milliseconds relative to {@code startTime}, -1 if not available.
*/
public double requestStart;
/**
- * Time immediately after the browser receives the first byte of the response from the server, cache, or local resource.
- * The value is given in milliseconds relative to {@code startTime}, -1 if not available.
+ * Time immediately after the client receives the first byte of the response from the server, cache, or local resource. The
+ * value is given in milliseconds relative to {@code startTime}, -1 if not available.
*/
public double responseStart;
/**
- * Time immediately after the browser receives the last byte of the resource or immediately before the transport connection
+ * Time immediately after the client receives the last byte of the resource or immediately before the transport connection
* is closed, whichever comes first. The value is given in milliseconds relative to {@code startTime}, -1 if not available.
*/
public double responseEnd;
diff --git a/playwright/src/test/java/com/microsoft/playwright/TestBrowserContextFetch.java b/playwright/src/test/java/com/microsoft/playwright/TestBrowserContextFetch.java
index a0783ac5b..0713f4b10 100644
--- a/playwright/src/test/java/com/microsoft/playwright/TestBrowserContextFetch.java
+++ b/playwright/src/test/java/com/microsoft/playwright/TestBrowserContextFetch.java
@@ -56,6 +56,22 @@ void getShouldWork() {
assertEquals("{\"foo\": \"bar\"}\n", response.text());
}
+ @Test
+ void getShouldReturnTiming() {
+ APIResponse response = context.request().get(server.PREFIX + "/simple.json");
+ assertTrue(response.ok());
+ Timing timing = response.timing();
+ assertTrue(timing.startTime > 0, "startTime = " + timing.startTime);
+ assertTrue(timing.domainLookupEnd >= timing.domainLookupStart);
+ assertTrue(timing.connectStart >= timing.domainLookupEnd);
+ assertEquals(-1, timing.secureConnectionStart);
+ assertTrue(timing.connectEnd >= timing.connectStart);
+ assertTrue(timing.requestStart >= timing.connectEnd);
+ assertTrue(timing.responseStart >= timing.requestStart);
+ assertTrue(timing.responseEnd >= timing.responseStart);
+ assertTrue(timing.responseEnd < 60_000, "responseEnd = " + timing.responseEnd);
+ }
+
@Test
void fetchShouldWork() {
APIResponse response = context.request().fetch(server.PREFIX + "/simple.json");
diff --git a/playwright/src/test/java/com/microsoft/playwright/TestBrowserContextHar.java b/playwright/src/test/java/com/microsoft/playwright/TestBrowserContextHar.java
index 9cc58d13c..bcc991dbe 100644
--- a/playwright/src/test/java/com/microsoft/playwright/TestBrowserContextHar.java
+++ b/playwright/src/test/java/com/microsoft/playwright/TestBrowserContextHar.java
@@ -19,6 +19,7 @@
import com.microsoft.playwright.options.HarMode;
import com.microsoft.playwright.options.HarNotFound;
import com.microsoft.playwright.options.RouteFromHarUpdateContentPolicy;
+import com.microsoft.playwright.options.Timing;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledIf;
import org.junit.jupiter.api.io.TempDir;
@@ -501,4 +502,61 @@ void shouldIgnoreAbortedRequests(@TempDir Path tmpDir) {
assertNull(page.evaluate("window.result"));
}
}
+
+ private void setJsonRoute(String path, String json) {
+ server.setRoute(path, exchange -> {
+ exchange.getResponseHeaders().add("Content-Type", "application/json");
+ byte[] body = json.getBytes(StandardCharsets.UTF_8);
+ exchange.sendResponseHeaders(200, body.length);
+ try (OutputStream out = exchange.getResponseBody()) {
+ out.write(body);
+ }
+ });
+ }
+
+ @Test
+ void shouldFulfillAPIRequestContextRequestsFromHAR(@TempDir Path tmpDir) {
+ setJsonRoute("/api/data", "{\"hello\": \"live\"}");
+ Path harPath = tmpDir.resolve("api.har");
+ try (BrowserContext context1 = browser.newContext()) {
+ context1.routeFromHAR(harPath, new BrowserContext.RouteFromHAROptions().setUpdate(true));
+ Page page1 = context1.newPage();
+ page1.navigate(server.EMPTY_PAGE);
+ APIResponse recorded = page1.request().get(server.PREFIX + "/api/data");
+ assertEquals("{\"hello\": \"live\"}", recorded.text());
+ }
+
+ // Now stop serving on the network side - the request must come from the HAR.
+ setJsonRoute("/api/data", "NOT_FROM_HAR");
+ try (BrowserContext context2 = browser.newContext()) {
+ context2.routeFromHAR(harPath, new BrowserContext.RouteFromHAROptions().setInterceptAPIRequests(true));
+ Page page2 = context2.newPage();
+ APIResponse replayed = page2.request().get(server.PREFIX + "/api/data");
+ assertEquals("{\"hello\": \"live\"}", replayed.text());
+ Timing timing = replayed.timing();
+ assertEquals(-1, timing.startTime);
+ assertEquals(-1, timing.responseEnd);
+ }
+ }
+
+ @Test
+ void shouldNotInterceptAPIRequestContextRequestsByDefault(@TempDir Path tmpDir) {
+ setJsonRoute("/api/data", "{\"hello\": \"live\"}");
+ Path harPath = tmpDir.resolve("api.har");
+ try (BrowserContext context1 = browser.newContext()) {
+ context1.routeFromHAR(harPath, new BrowserContext.RouteFromHAROptions().setUpdate(true));
+ Page page1 = context1.newPage();
+ page1.navigate(server.EMPTY_PAGE);
+ page1.request().get(server.PREFIX + "/api/data");
+ }
+
+ // Without the option, the live network is hit.
+ setJsonRoute("/api/data", "{\"hello\": \"fresh\"}");
+ try (BrowserContext context2 = browser.newContext()) {
+ context2.routeFromHAR(harPath, new BrowserContext.RouteFromHAROptions().setNotFound(HarNotFound.FALLBACK));
+ Page page2 = context2.newPage();
+ APIResponse replayed = page2.request().get(server.PREFIX + "/api/data");
+ assertEquals("{\"hello\": \"fresh\"}", replayed.text());
+ }
+ }
}
diff --git a/playwright/src/test/java/com/microsoft/playwright/TestLocatorClick.java b/playwright/src/test/java/com/microsoft/playwright/TestLocatorClick.java
index 7359ccc54..395e595b8 100644
--- a/playwright/src/test/java/com/microsoft/playwright/TestLocatorClick.java
+++ b/playwright/src/test/java/com/microsoft/playwright/TestLocatorClick.java
@@ -17,12 +17,13 @@
package com.microsoft.playwright;
import com.microsoft.playwright.options.KeyboardModifier;
+import com.microsoft.playwright.options.ScrollMode;
import org.junit.jupiter.api.Tag;
import org.junit.jupiter.api.Test;
import static com.microsoft.playwright.assertions.PlaywrightAssertions.assertThat;
import static java.util.Arrays.asList;
-import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.*;
@Tag("smoke")
public class TestLocatorClick extends TestBase {
@@ -104,4 +105,24 @@ void shouldClickWithTweenedMouseMovement() {
page.evaluate("result")
);
}
+
+ @Test
+ void shouldNotScrollWhenScrollIsNone() {
+ page.setContent("filler\n" +
+ "");
+ PlaywrightException e = assertThrows(PlaywrightException.class,
+ () -> page.locator("button").click(new Locator.ClickOptions().setScroll(ScrollMode.NONE).setTimeout(2000)));
+ assertTrue(e.getMessage().contains("element is outside of the viewport"), e.getMessage());
+ assertNull(page.evaluate("window._clicked"));
+ assertEquals(0, page.evaluate("() => window.scrollY"));
+ }
+
+ @Test
+ void shouldClickInViewportElementWhenScrollIsNone() {
+ page.setContent("\n" +
+ "");
+ page.locator("button").click(new Locator.ClickOptions().setScroll(ScrollMode.NONE).setTimeout(2000));
+ assertEquals(true, page.evaluate("window._clicked"));
+ assertEquals(0, page.evaluate("() => window.scrollY"));
+ }
}
diff --git a/playwright/src/test/java/com/microsoft/playwright/TestLocatorMisc.java b/playwright/src/test/java/com/microsoft/playwright/TestLocatorMisc.java
index 5e057ffdc..43cca0091 100644
--- a/playwright/src/test/java/com/microsoft/playwright/TestLocatorMisc.java
+++ b/playwright/src/test/java/com/microsoft/playwright/TestLocatorMisc.java
@@ -140,4 +140,49 @@ public void shouldSupportFilterVisible() {
assertThat(page.locator(".item").filter(new Locator.FilterOptions().setVisible(true)).getByText("data3")).hasText("visible data3");
assertThat(page.locator(".item").filter(new Locator.FilterOptions().setVisible(false)).getByText("data1")).hasText("Hidden data1");
}
+
+ @Test
+ void waitForFunctionShouldWaitForAnAttributeToAppear() {
+ page.setContent("");
+ page.evaluate("() => setTimeout(() => document.querySelector('#toggle').setAttribute('aria-expanded', 'true'), 500)");
+ page.locator("#toggle").waitForFunction("element => element.hasAttribute('aria-expanded')");
+ }
+
+ @Test
+ void waitForFunctionShouldReturnImmediatelyWhenAlreadyTruthy() {
+ page.setContent("yes");
+ page.locator("#target").waitForFunction("element => element.textContent === 'yes'");
+ }
+
+ @Test
+ void waitForFunctionShouldAcceptElementHandleArguments() {
+ page.setContent("value");
+ ElementHandle handle = page.querySelector("#b");
+ page.locator("#a").waitForFunction("(element, other) => other.textContent === 'value'", handle);
+ }
+
+ @Test
+ void waitForFunctionShouldThrowWhenPredicateThrows() {
+ page.setContent("no");
+ PlaywrightException e = assertThrows(PlaywrightException.class,
+ () -> page.locator("#target").waitForFunction("() => { throw new Error('oh my'); }"));
+ assertTrue(e.getMessage().contains("oh my"), e.getMessage());
+ }
+
+ @Test
+ void waitForFunctionShouldThrowOnStrictModeViolation() {
+ page.setContent("12");
+ PlaywrightException e = assertThrows(PlaywrightException.class,
+ () -> page.locator("div.x").waitForFunction("() => true"));
+ assertTrue(e.getMessage().contains("strict mode violation"), e.getMessage());
+ }
+
+ @Test
+ void waitForFunctionShouldRespectTimeout() {
+ page.setContent("no");
+ PlaywrightException e = assertThrows(PlaywrightException.class,
+ () -> page.locator("#target").waitForFunction("element => element.textContent === 'yes'", null,
+ new Locator.WaitForFunctionOptions().setTimeout(500)));
+ assertTrue(e.getMessage().contains("Timeout 500ms exceeded"), e.getMessage());
+ }
}
diff --git a/playwright/src/test/java/com/microsoft/playwright/TestPageAriaSnapshotAI.java b/playwright/src/test/java/com/microsoft/playwright/TestPageAriaSnapshotAI.java
index b29813211..ec5bc660e 100644
--- a/playwright/src/test/java/com/microsoft/playwright/TestPageAriaSnapshotAI.java
+++ b/playwright/src/test/java/com/microsoft/playwright/TestPageAriaSnapshotAI.java
@@ -82,7 +82,10 @@ void shouldNotNestCursorPointerHints(Page page) {
"Link with a button " +
"");
String snapshot = aiSnapshot(page);
- assertTrue(snapshot.contains("link \"Link with a button Button\" [ref=e2] [cursor=pointer]"), snapshot);
+ // The link's name is redundant - "Link with a button" prints as text and "Button" as the button -
+ // so it is dropped even though the node is clickable.
+ assertTrue(snapshot.contains("link [ref=e2] [cursor=pointer]"), snapshot);
+ assertTrue(snapshot.contains("text: Link with a button"), snapshot);
// The button inside a cursor-pointer link should not get a redundant [cursor=pointer]
assertTrue(snapshot.contains("button \"Button\" [ref=e3]"), snapshot);
assertFalse(snapshot.contains("button \"Button\" [ref=e3] [cursor=pointer]"), snapshot);
diff --git a/playwright/src/test/java/com/microsoft/playwright/TestPageScreenshot.java b/playwright/src/test/java/com/microsoft/playwright/TestPageScreenshot.java
index d3485fc6f..9ba228b5e 100644
--- a/playwright/src/test/java/com/microsoft/playwright/TestPageScreenshot.java
+++ b/playwright/src/test/java/com/microsoft/playwright/TestPageScreenshot.java
@@ -20,9 +20,11 @@
import com.microsoft.playwright.options.ScreenshotAnimations;
import com.microsoft.playwright.options.ScreenshotCaret;
import com.microsoft.playwright.options.ScreenshotScale;
+import com.microsoft.playwright.options.ScreenshotType;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledIf;
+import org.junit.jupiter.api.io.TempDir;
import org.opentest4j.AssertionFailedError;
import javax.imageio.ImageIO;
@@ -65,6 +67,39 @@ void shouldClipRect() throws IOException {
// expect(screenshot).toMatchSnapshot("screenshot-clip-rect.png");
}
+ private static void assertWebp(byte[] screenshot) {
+ // WebP magic: "RIFF" at offset 0, "WEBP" at offset 8.
+ assertTrue(screenshot.length > 12);
+ assertEquals("RIFF", new String(screenshot, 0, 4, java.nio.charset.StandardCharsets.US_ASCII));
+ assertEquals("WEBP", new String(screenshot, 8, 4, java.nio.charset.StandardCharsets.US_ASCII));
+ }
+
+ @Test
+ void shouldProduceAValidWebpScreenshot() {
+ page.setViewportSize(300, 300);
+ page.navigate(server.EMPTY_PAGE);
+ byte[] screenshot = page.screenshot(new Page.ScreenshotOptions().setType(ScreenshotType.WEBP));
+ assertWebp(screenshot);
+ }
+
+ @Test
+ void pathOptionShouldDetectWebp(@TempDir Path tmpDir) throws IOException {
+ page.setViewportSize(300, 300);
+ page.navigate(server.EMPTY_PAGE);
+ Path outputPath = tmpDir.resolve("screenshot.webp");
+ byte[] screenshot = page.screenshot(new Page.ScreenshotOptions().setPath(outputPath));
+ assertWebp(screenshot);
+ assertWebp(Files.readAllBytes(outputPath));
+ }
+
+ @Test
+ void qualityOptionShouldWorkForWebp() {
+ page.navigate(server.PREFIX + "/grid.html");
+ byte[] lowQuality = page.screenshot(new Page.ScreenshotOptions().setType(ScreenshotType.WEBP).setQuality(0));
+ byte[] highQuality = page.screenshot(new Page.ScreenshotOptions().setType(ScreenshotType.WEBP).setQuality(100));
+ assertTrue(lowQuality.length < highQuality.length);
+ }
+
static private void rafraf(Page page) {
// Do a double raf since single raf does not
// actually guarantee a new animation frame.
diff --git a/scripts/DRIVER_VERSION b/scripts/DRIVER_VERSION
index 30e298c74..a77c2858a 100644
--- a/scripts/DRIVER_VERSION
+++ b/scripts/DRIVER_VERSION
@@ -1 +1 @@
-1.61.1
+1.62.0-alpha-2026-07-22
diff --git a/scripts/download_driver.sh b/scripts/download_driver.sh
index c72dad687..32dfa0bb7 100755
--- a/scripts/download_driver.sh
+++ b/scripts/download_driver.sh
@@ -46,9 +46,15 @@ if [[ -z "$GIT_HEAD" ]]; then
exit 1
fi
-# The Node.js version is kept in sync with the driver version in the upstream build script.
-NODE_VERSION=$(curl -fsSL "https://raw.githubusercontent.com/microsoft/playwright/$GIT_HEAD/utils/build/build-playwright-driver.sh" \
+# The Node.js version used to be pinned in the upstream driver build script. The script was
+# removed in microsoft/playwright#41518, so for newer versions we follow the same policy it
+# had: the latest Node.js LTS (see upstream utils/build/update-playwright-node.mjs).
+NODE_VERSION=$(curl -fsSL "https://raw.githubusercontent.com/microsoft/playwright/$GIT_HEAD/utils/build/build-playwright-driver.sh" 2>/dev/null \
| sed -n 's/^NODE_VERSION="\([^"]*\)".*/\1/p')
+if [[ -z "$NODE_VERSION" ]]; then
+ NODE_VERSION=$(curl -fsSL "https://nodejs.org/dist/index.json" \
+ | node -e "let s='';process.stdin.on('data',d=>s+=d).on('end',()=>console.log(JSON.parse(s).find(r=>r.lts).version.slice(1)))")
+fi
if [[ -z "$NODE_VERSION" ]]; then
echo "Failed to determine Node.js version for playwright@$DRIVER_VERSION ($GIT_HEAD)"
exit 1