NOTE: The {@code null} value opts out from the default presets, makes viewport depend on the host window size defined by the
+ * operating system. It makes the execution of the tests non-deterministic.
*/
public Optional NOTE: The {@code null} value opts out from the default presets, makes viewport depend on the host window size defined by the
+ * operating system. It makes the execution of the tests non-deterministic.
*/
public NewContextOptions setViewportSize(int width, int height) {
return setViewportSize(new ViewportSize(width, height));
}
/**
- * Emulates consistent viewport for each page. Defaults to an 1280x720 viewport. {@code null} disables the default
- * viewport.
+ * Emulates consistent viewport for each page. Defaults to an 1280x720 viewport. Use {@code null} to disable the consistent
+ * viewport emulation.
+ *
+ * NOTE: The {@code null} value opts out from the default presets, makes viewport depend on the host window size defined by the
+ * operating system. It makes the execution of the tests non-deterministic.
*/
public NewContextOptions setViewportSize(ViewportSize viewportSize) {
this.viewportSize = Optional.ofNullable(viewportSize);
@@ -722,8 +731,11 @@ public interface Browser extends AutoCloseable {
*/
public String userAgent;
/**
- * Emulates consistent viewport for each page. Defaults to an 1280x720 viewport. {@code null} disables the default
- * viewport.
+ * Emulates consistent viewport for each page. Defaults to an 1280x720 viewport. Use {@code null} to disable the consistent
+ * viewport emulation.
+ *
+ * NOTE: The {@code null} value opts out from the default presets, makes viewport depend on the host window size defined by the
+ * operating system. It makes the execution of the tests non-deterministic.
*/
public Optional NOTE: The {@code null} value opts out from the default presets, makes viewport depend on the host window size defined by the
+ * operating system. It makes the execution of the tests non-deterministic.
*/
public NewPageOptions setViewportSize(int width, int height) {
return setViewportSize(new ViewportSize(width, height));
}
/**
- * Emulates consistent viewport for each page. Defaults to an 1280x720 viewport. {@code null} disables the default
- * viewport.
+ * Emulates consistent viewport for each page. Defaults to an 1280x720 viewport. Use {@code null} to disable the consistent
+ * viewport emulation.
+ *
+ * NOTE: The {@code null} value opts out from the default presets, makes viewport depend on the host window size defined by the
+ * operating system. It makes the execution of the tests non-deterministic.
*/
public NewPageOptions setViewportSize(ViewportSize viewportSize) {
this.viewportSize = Optional.ofNullable(viewportSize);
diff --git a/playwright/src/main/java/com/microsoft/playwright/BrowserType.java b/playwright/src/main/java/com/microsoft/playwright/BrowserType.java
index 3fb82fab..644036e8 100644
--- a/playwright/src/main/java/com/microsoft/playwright/BrowserType.java
+++ b/playwright/src/main/java/com/microsoft/playwright/BrowserType.java
@@ -601,8 +601,11 @@ public interface BrowserType {
*/
public String userAgent;
/**
- * Emulates consistent viewport for each page. Defaults to an 1280x720 viewport. {@code null} disables the default
- * viewport.
+ * Emulates consistent viewport for each page. Defaults to an 1280x720 viewport. Use {@code null} to disable the consistent
+ * viewport emulation.
+ *
+ * NOTE: The {@code null} value opts out from the default presets, makes viewport depend on the host window size defined by the
+ * operating system. It makes the execution of the tests non-deterministic.
*/
public Optional NOTE: The {@code null} value opts out from the default presets, makes viewport depend on the host window size defined by the
+ * operating system. It makes the execution of the tests non-deterministic.
*/
public LaunchPersistentContextOptions setViewportSize(int width, int height) {
return setViewportSize(new ViewportSize(width, height));
}
/**
- * Emulates consistent viewport for each page. Defaults to an 1280x720 viewport. {@code null} disables the default
- * viewport.
+ * Emulates consistent viewport for each page. Defaults to an 1280x720 viewport. Use {@code null} to disable the consistent
+ * viewport emulation.
+ *
+ * NOTE: The {@code null} value opts out from the default presets, makes viewport depend on the host window size defined by the
+ * operating system. It makes the execution of the tests non-deterministic.
*/
public LaunchPersistentContextOptions setViewportSize(ViewportSize viewportSize) {
this.viewportSize = Optional.ofNullable(viewportSize);
diff --git a/playwright/src/main/java/com/microsoft/playwright/Locator.java b/playwright/src/main/java/com/microsoft/playwright/Locator.java
index 093631ef..e2574530 100644
--- a/playwright/src/main/java/com/microsoft/playwright/Locator.java
+++ b/playwright/src/main/java/com/microsoft/playwright/Locator.java
@@ -2283,7 +2283,7 @@ public interface Locator {
*/
void dblclick(DblclickOptions options);
/**
- * Programmaticaly dispatch an event on the matching element.
+ * Programmatically dispatch an event on the matching element.
*
* **Usage**
* **Usage**
* **Usage**
* **Usage**
* **Usage**
* This code above is equivalent to:
+ * When all steps combined have not finished during the specified {@code timeout}, this method throws a {@code
* TimeoutError}. Passing zero timeout disables this.
*
- * NOTE: {@link Page#tap Page.tap()} requires that the {@code hasTouch} option of the browser context be set to true.
+ * NOTE: {@link Page#tap Page.tap()} the method will throw if {@code hasTouch} option of the browser context is false.
*
* @param selector A selector to search for an element. If there are multiple elements satisfying the selector, the first will be used.
* @since v1.8
@@ -6749,7 +6788,7 @@ public interface Page extends AutoCloseable {
* When all steps combined have not finished during the specified {@code timeout}, this method throws a {@code
* TimeoutError}. Passing zero timeout disables this.
*
- * NOTE: {@link Page#tap Page.tap()} requires that the {@code hasTouch} option of the browser context be set to true.
+ * NOTE: {@link Page#tap Page.tap()} the method will throw if {@code hasTouch} option of the browser context is false.
*
* @param selector A selector to search for an element. If there are multiple elements satisfying the selector, the first will be used.
* @since v1.8
@@ -7838,44 +7877,5 @@ public interface Page extends AutoCloseable {
* @since v1.8
*/
List This code above is equivalent to:
- * **Details**
+ *
+ * Note that any overrides such as {@code url} or {@code headers} only apply to the request being routed. If this request
+ * results in a redirect, overrides will not be applied to the new redirected request. If you want to propagate a header
+ * through redirects, use the combination of {@link Route#fetch Route.fetch()} and {@link Route#fulfill Route.fulfill()}
+ * instead.
+ *
* @since v1.8
*/
default void resume() {
@@ -340,6 +360,13 @@ public interface Route {
* });
* } **Details**
+ *
+ * Note that any overrides such as {@code url} or {@code headers} only apply to the request being routed. If this request
+ * results in a redirect, overrides will not be applied to the new redirected request. If you want to propagate a header
+ * through redirects, use the combination of {@link Route#fetch Route.fetch()} and {@link Route#fulfill Route.fulfill()}
+ * instead.
+ *
* @since v1.8
*/
void resume(ResumeOptions options);
@@ -488,6 +515,12 @@ public interface Route {
* });
* } **Details**
+ *
+ * Note that {@code headers} option will apply to the fetched request as well as any redirects initiated by it. If you want
+ * to only apply {@code headers} to the original request, but not to redirects, look into {@link Route#resume
+ * Route.resume()} instead.
+ *
* @since v1.29
*/
default APIResponse fetch() {
@@ -510,6 +543,12 @@ public interface Route {
* });
* } **Details**
+ *
+ * Note that {@code headers} option will apply to the fetched request as well as any redirects initiated by it. If you want
+ * to only apply {@code headers} to the original request, but not to redirects, look into {@link Route#resume
+ * Route.resume()} instead.
+ *
* @since v1.29
*/
APIResponse fetch(FetchOptions options);
diff --git a/playwright/src/main/java/com/microsoft/playwright/Selectors.java b/playwright/src/main/java/com/microsoft/playwright/Selectors.java
index 99b8960a..b3dddf89 100644
--- a/playwright/src/main/java/com/microsoft/playwright/Selectors.java
+++ b/playwright/src/main/java/com/microsoft/playwright/Selectors.java
@@ -42,7 +42,9 @@ public interface Selectors {
}
}
/**
- * **Usage**
+ * Selectors must be registered before creating the page.
+ *
+ * **Usage**
*
* An example of registering selector engine that queries elements based on a tag name:
* **Usage**
*
* An example of registering selector engine that queries elements based on a tag name:
* **Usage**
*
* An example of registering selector engine that queries elements based on a tag name:
* **Usage**
*
* An example of registering selector engine that queries elements based on a tag name:
* NOTE: {@link Page#tap Page.tap()} the method will throw if {@code hasTouch} option of the browser context is false.
+ *
* @since v1.8
*/
void tap(double x, double y);
diff --git a/playwright/src/main/java/com/microsoft/playwright/assertions/APIResponseAssertions.java b/playwright/src/main/java/com/microsoft/playwright/assertions/APIResponseAssertions.java
index 9258a26c..fe62f1b6 100644
--- a/playwright/src/main/java/com/microsoft/playwright/assertions/APIResponseAssertions.java
+++ b/playwright/src/main/java/com/microsoft/playwright/assertions/APIResponseAssertions.java
@@ -19,8 +19,7 @@ package com.microsoft.playwright.assertions;
/**
* The {@code APIResponseAssertions} class provides assertion methods that can be used to make assertions about the {@code
- * APIResponse} in the tests. A new instance of {@code APIResponseAssertions} is created by calling {@link
- * PlaywrightAssertions#assertThat PlaywrightAssertions.assertThat()}:
+ * APIResponse} in the tests.
* **Usage**
+ * **Usage**
+ * {@code
@@ -2328,7 +2328,7 @@ public interface Locator {
dispatchEvent(type, eventInit, null);
}
/**
- * Programmaticaly dispatch an event on the matching element.
+ * Programmatically dispatch an event on the matching element.
*
* {@code
@@ -2372,7 +2372,7 @@ public interface Locator {
dispatchEvent(type, null);
}
/**
- * Programmaticaly dispatch an event on the matching element.
+ * Programmatically dispatch an event on the matching element.
*
* {@code
@@ -3717,7 +3717,7 @@ public interface Locator {
*/
Page page();
/**
- * Focuses the mathing element and presses a combintation of the keys.
+ * Focuses the matching element and presses a combination of the keys.
*
*
*
+ * {@code
@@ -3756,7 +3756,7 @@ public interface Locator {
press(key, null);
}
/**
- * Focuses the mathing element and presses a combintation of the keys.
+ * Focuses the matching element and presses a combination of the keys.
*
*
*
+ * {@code
diff --git a/playwright/src/main/java/com/microsoft/playwright/Page.java b/playwright/src/main/java/com/microsoft/playwright/Page.java
index 3321171d..6d149101 100644
--- a/playwright/src/main/java/com/microsoft/playwright/Page.java
+++ b/playwright/src/main/java/com/microsoft/playwright/Page.java
@@ -5441,6 +5441,45 @@ public interface Page extends AutoCloseable {
* @since v1.8
*/
Mouse mouse();
+ /**
+ * Adds one-off {@code Dialog} handler. The handler will be removed immediately after next {@code Dialog} is created.
+ *
*
+ * {@code
+ * page.onceDialog(dialog -> {
+ * dialog.accept("foo");
+ * });
+ *
+ * // prints 'foo'
+ * System.out.println(page.evaluate("prompt('Enter string:')"));
+ *
+ * // prints 'null' as the dialog will be auto-dismissed because there are no handlers.
+ * System.out.println(page.evaluate("prompt('Enter string:')"));
+ * }
+ *
+ * {@code
+ * Consumer
+ *
+ * @param handler Receives the {@code Dialog} object, it **must** either {@link Dialog#accept Dialog.accept()} or {@link Dialog#dismiss
+ * Dialog.dismiss()} the dialog - otherwise the page will freeze waiting for the
+ * dialog, and actions like click will never finish.
+ * @since v1.10
+ */
+ void onceDialog(Consumer{@code
- * page.onceDialog(dialog -> {
- * dialog.accept("foo");
- * });
- *
- * // prints 'foo'
- * System.out.println(page.evaluate("prompt('Enter string:')"));
- *
- * // prints 'null' as the dialog will be auto-dismissed because there are no handlers.
- * System.out.println(page.evaluate("prompt('Enter string:')"));
- * }
- *
- * {@code
- * Consumer
- *
- * @param handler Receives the {@code Dialog} object, it **must** either {@link Dialog#accept Dialog.accept()} or {@link Dialog#dismiss
- * Dialog.dismiss()} the dialog - otherwise the page will freeze waiting for the
- * dialog, and actions like click will never finish.
- * @since v1.10
- */
- void onceDialog(Consumer{@code
- * Playwright playwright = Playwright.create()) {
+ * Playwright playwright = Playwright.create();
* Browser browser = playwright.webkit().launch();
* Page page = browser.newPage();
* page.navigate("https://www.w3.org/");
diff --git a/playwright/src/main/java/com/microsoft/playwright/Route.java b/playwright/src/main/java/com/microsoft/playwright/Route.java
index 0042eb61..4e0e8285 100644
--- a/playwright/src/main/java/com/microsoft/playwright/Route.java
+++ b/playwright/src/main/java/com/microsoft/playwright/Route.java
@@ -141,6 +141,11 @@ public interface Route {
* If set changes the request HTTP headers. Header values will be converted to a string.
*/
public Map
*
+ * {@code
@@ -64,8 +66,8 @@ public interface Selectors {
* page.setContent("");
* // Use the selector prefixed with its name.
* Locator button = page.locator("tag=button");
- * // Combine it with other selector engines.
- * page.locator("tag=div >> text=\"Click me\"").click();
+ * // Combine it with built-in locators.
+ * page.locator("tag=div").getByText("Click me").click();
* // Can use it in any methods supporting selectors.
* int buttonCount = (int) page.locator("tag=button").count();
* browser.close();
@@ -80,7 +82,9 @@ public interface Selectors {
register(name, script, null);
}
/**
- * **Usage**
+ * Selectors must be registered before creating the page.
+ *
+ * {@code
@@ -102,8 +106,8 @@ public interface Selectors {
* page.setContent("");
* // Use the selector prefixed with its name.
* Locator button = page.locator("tag=button");
- * // Combine it with other selector engines.
- * page.locator("tag=div >> text=\"Click me\"").click();
+ * // Combine it with built-in locators.
+ * page.locator("tag=div").getByText("Click me").click();
* // Can use it in any methods supporting selectors.
* int buttonCount = (int) page.locator("tag=button").count();
* browser.close();
@@ -116,7 +120,9 @@ public interface Selectors {
*/
void register(String name, String script, RegisterOptions options);
/**
- * **Usage**
+ * Selectors must be registered before creating the page.
+ *
+ * {@code
@@ -138,8 +144,8 @@ public interface Selectors {
* page.setContent("");
* // Use the selector prefixed with its name.
* Locator button = page.locator("tag=button");
- * // Combine it with other selector engines.
- * page.locator("tag=div >> text=\"Click me\"").click();
+ * // Combine it with built-in locators.
+ * page.locator("tag=div").getByText("Click me").click();
* // Can use it in any methods supporting selectors.
* int buttonCount = (int) page.locator("tag=button").count();
* browser.close();
@@ -154,7 +160,9 @@ public interface Selectors {
register(name, script, null);
}
/**
- * **Usage**
+ * Selectors must be registered before creating the page.
+ *
+ * {@code
@@ -176,8 +184,8 @@ public interface Selectors {
* page.setContent("");
* // Use the selector prefixed with its name.
* Locator button = page.locator("tag=button");
- * // Combine it with other selector engines.
- * page.locator("tag=div >> text=\"Click me\"").click();
+ * // Combine it with built-in locators.
+ * page.locator("tag=div").getByText("Click me").click();
* // Can use it in any methods supporting selectors.
* int buttonCount = (int) page.locator("tag=button").count();
* browser.close();
diff --git a/playwright/src/main/java/com/microsoft/playwright/Touchscreen.java b/playwright/src/main/java/com/microsoft/playwright/Touchscreen.java
index 38d4c909..b93f1b4a 100644
--- a/playwright/src/main/java/com/microsoft/playwright/Touchscreen.java
+++ b/playwright/src/main/java/com/microsoft/playwright/Touchscreen.java
@@ -25,6 +25,8 @@ public interface Touchscreen {
/**
* Dispatches a {@code touchstart} and {@code touchend} event with a single touch at the position ({@code x},{@code y}).
*
+ * {@code
* ...
* import static com.microsoft.playwright.assertions.PlaywrightAssertions.assertThat;
diff --git a/playwright/src/main/java/com/microsoft/playwright/assertions/LocatorAssertions.java b/playwright/src/main/java/com/microsoft/playwright/assertions/LocatorAssertions.java
index 38411c96..81bf2055 100644
--- a/playwright/src/main/java/com/microsoft/playwright/assertions/LocatorAssertions.java
+++ b/playwright/src/main/java/com/microsoft/playwright/assertions/LocatorAssertions.java
@@ -20,8 +20,7 @@ import java.util.regex.Pattern;
/**
* The {@code LocatorAssertions} class provides assertion methods that can be used to make assertions about the {@code
- * Locator} state in the tests. A new instance of {@code LocatorAssertions} is created by calling {@link
- * PlaywrightAssertions#assertThat PlaywrightAssertions.assertThat()}:
+ * Locator} state in the tests.
* {@code
* ...
* import static com.microsoft.playwright.assertions.PlaywrightAssertions.assertThat;
@@ -151,6 +150,33 @@ public interface LocatorAssertions {
return this;
}
}
+ class IsInViewportOptions {
+ /**
+ * The minimal ratio of the element to intersect viewport. If equals to {@code 0}, then element should intersect viewport
+ * at any positive ratio. Defaults to {@code 0}.
+ */
+ public Double ratio;
+ /**
+ * Time to retry the assertion for.
+ */
+ public Double timeout;
+
+ /**
+ * The minimal ratio of the element to intersect viewport. If equals to {@code 0}, then element should intersect viewport
+ * at any positive ratio. Defaults to {@code 0}.
+ */
+ public IsInViewportOptions setRatio(double ratio) {
+ this.ratio = ratio;
+ return this;
+ }
+ /**
+ * Time to retry the assertion for.
+ */
+ public IsInViewportOptions setTimeout(double timeout) {
+ this.timeout = timeout;
+ return this;
+ }
+ }
class IsVisibleOptions {
/**
* Time to retry the assertion for.
@@ -548,6 +574,44 @@ public interface LocatorAssertions {
* @since v1.20
*/
void isHidden(IsHiddenOptions options);
+ /**
+ * Ensures the {@code Locator} points to an element that intersects viewport, according to the intersection observer API.
+ *
+ * {@code
+ * Locator locator = page.locator("button.submit");
+ * // Make sure at least some part of element intersects viewport.
+ * assertThat(locator).isInViewport();
+ * // Make sure element is fully outside of viewport.
+ * assertThat(locator).not().isInViewport();
+ * // Make sure that at least half of the element intersects viewport.
+ * assertThat(locator).isInViewport(new LocatorAssertions.IsInViewportOptions().setRatio(0.5));
+ * }
+ *
+ * @since v1.31
+ */
+ default void isInViewport() {
+ isInViewport(null);
+ }
+ /**
+ * Ensures the {@code Locator} points to an element that intersects viewport, according to the intersection observer API.
+ *
+ * {@code
+ * Locator locator = page.locator("button.submit");
+ * // Make sure at least some part of element intersects viewport.
+ * assertThat(locator).isInViewport();
+ * // Make sure element is fully outside of viewport.
+ * assertThat(locator).not().isInViewport();
+ * // Make sure that at least half of the element intersects viewport.
+ * assertThat(locator).isInViewport(new LocatorAssertions.IsInViewportOptions().setRatio(0.5));
+ * }
+ *
+ * @since v1.31
+ */
+ void isInViewport(IsInViewportOptions options);
/**
* Ensures that {@code Locator} points to an attached
* and visible DOM node.
diff --git a/playwright/src/main/java/com/microsoft/playwright/assertions/PageAssertions.java b/playwright/src/main/java/com/microsoft/playwright/assertions/PageAssertions.java
index 09215b4d..9d46459e 100644
--- a/playwright/src/main/java/com/microsoft/playwright/assertions/PageAssertions.java
+++ b/playwright/src/main/java/com/microsoft/playwright/assertions/PageAssertions.java
@@ -20,8 +20,7 @@ import java.util.regex.Pattern;
/**
* The {@code PageAssertions} class provides assertion methods that can be used to make assertions about the {@code Page}
- * state in the tests. A new instance of {@code PageAssertions} is created by calling {@link
- * PlaywrightAssertions#assertThat PlaywrightAssertions.assertThat()}:
+ * state in the tests.
* {@code
* ...
* import static com.microsoft.playwright.assertions.PlaywrightAssertions.assertThat;
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 f3e930ed..50359995 100644
--- a/playwright/src/main/java/com/microsoft/playwright/impl/BrowserContextImpl.java
+++ b/playwright/src/main/java/com/microsoft/playwright/impl/BrowserContextImpl.java
@@ -399,11 +399,7 @@ class BrowserContextImpl extends ChannelOwner implements BrowserContext {
private void route(UrlMatcher matcher, Consumerhello
\n" +
+ " ");
+ assertThat(page.locator("h1")).isInViewport();
+ }
+}
diff --git a/playwright/src/test/java/com/microsoft/playwright/TestClick.java b/playwright/src/test/java/com/microsoft/playwright/TestClick.java
index a155e66c..74f24e49 100644
--- a/playwright/src/test/java/com/microsoft/playwright/TestClick.java
+++ b/playwright/src/test/java/com/microsoft/playwright/TestClick.java
@@ -17,6 +17,7 @@
package com.microsoft.playwright;
import com.microsoft.playwright.options.AriaRole;
+import com.microsoft.playwright.options.WaitUntilState;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledIf;
import org.junit.jupiter.api.condition.EnabledIf;
diff --git a/playwright/src/test/java/com/microsoft/playwright/TestPageInterception.java b/playwright/src/test/java/com/microsoft/playwright/TestPageInterception.java
index 57197a64..61ab82c1 100644
--- a/playwright/src/test/java/com/microsoft/playwright/TestPageInterception.java
+++ b/playwright/src/test/java/com/microsoft/playwright/TestPageInterception.java
@@ -92,4 +92,17 @@ public class TestPageInterception extends TestBase {
page.navigate(server.PREFIX + "/empty.html");
assertEquals("{ \"foo\": \"bar\" }", new String(request.get().postBody));
}
+
+ @Test
+ void shouldNotFollowRedirectsWhenMaxRedirectsIsSetTo0InRouteFetch() {
+ server.setRedirect("/foo", "/empty.html");
+ page.route("**/*", route -> {
+ APIResponse response = route.fetch(new Route.FetchOptions().setMaxRedirects(0));
+ assertEquals("/empty.html", response.headers().get("location"));
+ assertEquals(302, response.status());
+ route.fulfill(new Route.FulfillOptions().setBody("hello"));
+ });
+ page.navigate(server.PREFIX + "/foo");
+ assertTrue(page.content().contains("hello"));
+ }
}
diff --git a/playwright/src/test/java/com/microsoft/playwright/TestPageRequestContinue.java b/playwright/src/test/java/com/microsoft/playwright/TestPageRequestContinue.java
index a2eab766..40437110 100644
--- a/playwright/src/test/java/com/microsoft/playwright/TestPageRequestContinue.java
+++ b/playwright/src/test/java/com/microsoft/playwright/TestPageRequestContinue.java
@@ -73,7 +73,7 @@ public class TestPageRequestContinue extends TestBase {
done[0] = true;
});
PlaywrightException e = assertThrows(PlaywrightException.class, () -> page.navigate(server.EMPTY_PAGE));
- assertTrue(e.getMessage().contains("Navigation failed because page was closed") ||
+ assertTrue(e.getMessage().contains("Target page, context or browser has been closed") ||
e.getMessage().contains("frame was detached"), e.getMessage());
assertTrue(done[0]);
}
diff --git a/scripts/CLI_VERSION b/scripts/CLI_VERSION
index 231d458d..b78197a0 100644
--- a/scripts/CLI_VERSION
+++ b/scripts/CLI_VERSION
@@ -1 +1 @@
-1.30.0-beta-1674276599000
+1.31.0-beta-1676596096000