diff --git a/README.md b/README.md index f1a17428..9093b4f2 100644 --- a/README.md +++ b/README.md @@ -11,9 +11,9 @@ Playwright is a Java library to automate [Chromium](https://www.chromium.org/Hom | | Linux | macOS | Windows | | :--- | :---: | :---: | :---: | -| Chromium 120.0.6099.28 | :white_check_mark: | :white_check_mark: | :white_check_mark: | +| Chromium 121.0.6167.16 | :white_check_mark: | :white_check_mark: | :white_check_mark: | | WebKit 17.4 | ✅ | ✅ | ✅ | -| Firefox 119.0 | :white_check_mark: | :white_check_mark: | :white_check_mark: | +| Firefox 120.0.1 | :white_check_mark: | :white_check_mark: | :white_check_mark: | Headless execution is supported for all the browsers on all platforms. Check out [system requirements](https://playwright.dev/java/docs/intro#system-requirements) for details. diff --git a/playwright/src/main/java/com/microsoft/playwright/BrowserContext.java b/playwright/src/main/java/com/microsoft/playwright/BrowserContext.java index 86e71d89..14f2cf6d 100644 --- a/playwright/src/main/java/com/microsoft/playwright/BrowserContext.java +++ b/playwright/src/main/java/com/microsoft/playwright/BrowserContext.java @@ -1260,6 +1260,13 @@ public interface BrowserContext extends AutoCloseable { * @since v1.12 */ Tracing tracing(); + /** + * Removes all routes created with {@link BrowserContext#route BrowserContext.route()} and {@link + * BrowserContext#routeFromHAR BrowserContext.routeFromHAR()}. + * + * @since v1.41 + */ + void unrouteAll(); /** * Removes a route created with {@link BrowserContext#route BrowserContext.route()}. When {@code handler} is not specified, * removes all routes for the {@code url}. diff --git a/playwright/src/main/java/com/microsoft/playwright/BrowserType.java b/playwright/src/main/java/com/microsoft/playwright/BrowserType.java index ac0bba3e..b7703540 100644 --- a/playwright/src/main/java/com/microsoft/playwright/BrowserType.java +++ b/playwright/src/main/java/com/microsoft/playwright/BrowserType.java @@ -165,8 +165,10 @@ public interface BrowserType { } class LaunchOptions { /** - * Additional arguments to pass to the browser instance. The list of Chromium flags can be found here. + * NOTE: Use custom browser args at your own risk, as some of them may break Playwright functionality. + * + *

Additional arguments to pass to the browser instance. The list of Chromium flags can be found here. */ public List args; /** @@ -253,8 +255,10 @@ public interface BrowserType { public Path tracesDir; /** - * Additional arguments to pass to the browser instance. The list of Chromium flags can be found here. + * NOTE: Use custom browser args at your own risk, as some of them may break Playwright functionality. + * + *

Additional arguments to pass to the browser instance. The list of Chromium flags can be found here. */ public LaunchOptions setArgs(List args) { this.args = args; @@ -416,8 +420,10 @@ public interface BrowserType { */ public Boolean acceptDownloads; /** - * Additional arguments to pass to the browser instance. The list of Chromium flags can be found here. + * NOTE: Use custom browser args at your own risk, as some of them may break Playwright functionality. + * + *

Additional arguments to pass to the browser instance. The list of Chromium flags can be found here. */ public List args; /** @@ -675,8 +681,10 @@ public interface BrowserType { return this; } /** - * Additional arguments to pass to the browser instance. The list of Chromium flags can be found here. + * NOTE: Use custom browser args at your own risk, as some of them may break Playwright functionality. + * + *

Additional arguments to pass to the browser instance. The list of Chromium flags can be found here. */ public LaunchPersistentContextOptions setArgs(List args) { this.args = args; diff --git a/playwright/src/main/java/com/microsoft/playwright/ElementHandle.java b/playwright/src/main/java/com/microsoft/playwright/ElementHandle.java index 965783f8..3dfb2a8d 100644 --- a/playwright/src/main/java/com/microsoft/playwright/ElementHandle.java +++ b/playwright/src/main/java/com/microsoft/playwright/ElementHandle.java @@ -634,6 +634,12 @@ public interface ElementHandle extends JSHandle { *

Defaults to {@code "device"}. */ public ScreenshotScale scale; + /** + * Text of the stylesheet to apply while making the screenshot. This is where you can hide dynamic elements, make elements + * invisible or change their properties to help you creating repeatable screenshots. This stylesheet pierces the Shadow DOM + * and applies to the inner frames. + */ + public String style; /** * 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 BrowserContext#setDefaultTimeout BrowserContext.setDefaultTimeout()} or {@link @@ -719,6 +725,15 @@ public interface ElementHandle extends JSHandle { this.scale = scale; return this; } + /** + * Text of the stylesheet to apply while making the screenshot. This is where you can hide dynamic elements, make elements + * invisible or change their properties to help you creating repeatable screenshots. This stylesheet pierces the Shadow DOM + * and applies to the inner frames. + */ + public ScreenshotOptions setStyle(String style) { + this.style = style; + 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 BrowserContext#setDefaultTimeout BrowserContext.setDefaultTimeout()} or {@link diff --git a/playwright/src/main/java/com/microsoft/playwright/Frame.java b/playwright/src/main/java/com/microsoft/playwright/Frame.java index dc641ff4..d1aef5da 100644 --- a/playwright/src/main/java/com/microsoft/playwright/Frame.java +++ b/playwright/src/main/java/com/microsoft/playwright/Frame.java @@ -1470,8 +1470,14 @@ public interface Frame { } class LocatorOptions { /** - * Matches elements containing an element that matches an inner locator. Inner locator is queried against the outer one. - * For example, {@code article} that has {@code text=Playwright} matches {@code

Playwright
}. + * Narrows down the results of the method to those which contain elements matching this relative locator. For example, + * {@code article} that has {@code text=Playwright} matches {@code
Playwright
}. + * + *

Inner locator **must be relative** to the outer locator and is queried starting with the outer locator match, not the + * document root. For example, you can find {@code content} that has {@code div} in {@code + *

Playwright
}. However, looking for {@code content} that has {@code + * article div} will fail, because the inner locator must be relative and should not use any elements outside the {@code + * content}. * *

Note that outer and inner locators must belong to the same frame. Inner locator must not contain {@code FrameLocator}s. */ @@ -1497,8 +1503,14 @@ public interface Frame { public Object hasText; /** - * Matches elements containing an element that matches an inner locator. Inner locator is queried against the outer one. - * For example, {@code article} that has {@code text=Playwright} matches {@code

Playwright
}. + * Narrows down the results of the method to those which contain elements matching this relative locator. For example, + * {@code article} that has {@code text=Playwright} matches {@code
Playwright
}. + * + *

Inner locator **must be relative** to the outer locator and is queried starting with the outer locator match, not the + * document root. For example, you can find {@code content} that has {@code div} in {@code + *

Playwright
}. However, looking for {@code content} that has {@code + * article div} will fail, because the inner locator must be relative and should not use any elements outside the {@code + * content}. * *

Note that outer and inner locators must belong to the same frame. Inner locator must not contain {@code FrameLocator}s. */ diff --git a/playwright/src/main/java/com/microsoft/playwright/FrameLocator.java b/playwright/src/main/java/com/microsoft/playwright/FrameLocator.java index 6f5088c6..d3b14279 100644 --- a/playwright/src/main/java/com/microsoft/playwright/FrameLocator.java +++ b/playwright/src/main/java/com/microsoft/playwright/FrameLocator.java @@ -285,8 +285,14 @@ public interface FrameLocator { } class LocatorOptions { /** - * Matches elements containing an element that matches an inner locator. Inner locator is queried against the outer one. - * For example, {@code article} that has {@code text=Playwright} matches {@code

Playwright
}. + * Narrows down the results of the method to those which contain elements matching this relative locator. For example, + * {@code article} that has {@code text=Playwright} matches {@code
Playwright
}. + * + *

Inner locator **must be relative** to the outer locator and is queried starting with the outer locator match, not the + * document root. For example, you can find {@code content} that has {@code div} in {@code + *

Playwright
}. However, looking for {@code content} that has {@code + * article div} will fail, because the inner locator must be relative and should not use any elements outside the {@code + * content}. * *

Note that outer and inner locators must belong to the same frame. Inner locator must not contain {@code FrameLocator}s. */ @@ -312,8 +318,14 @@ public interface FrameLocator { public Object hasText; /** - * Matches elements containing an element that matches an inner locator. Inner locator is queried against the outer one. - * For example, {@code article} that has {@code text=Playwright} matches {@code

Playwright
}. + * Narrows down the results of the method to those which contain elements matching this relative locator. For example, + * {@code article} that has {@code text=Playwright} matches {@code
Playwright
}. + * + *

Inner locator **must be relative** to the outer locator and is queried starting with the outer locator match, not the + * document root. For example, you can find {@code content} that has {@code div} in {@code + *

Playwright
}. However, looking for {@code content} that has {@code + * article div} will fail, because the inner locator must be relative and should not use any elements outside the {@code + * content}. * *

Note that outer and inner locators must belong to the same frame. Inner locator must not contain {@code FrameLocator}s. */ diff --git a/playwright/src/main/java/com/microsoft/playwright/Locator.java b/playwright/src/main/java/com/microsoft/playwright/Locator.java index a55c62a9..7c6d1dbd 100644 --- a/playwright/src/main/java/com/microsoft/playwright/Locator.java +++ b/playwright/src/main/java/com/microsoft/playwright/Locator.java @@ -656,8 +656,14 @@ public interface Locator { } class FilterOptions { /** - * Matches elements containing an element that matches an inner locator. Inner locator is queried against the outer one. - * For example, {@code article} that has {@code text=Playwright} matches {@code

Playwright
}. + * Narrows down the results of the method to those which contain elements matching this relative locator. For example, + * {@code article} that has {@code text=Playwright} matches {@code
Playwright
}. + * + *

Inner locator **must be relative** to the outer locator and is queried starting with the outer locator match, not the + * document root. For example, you can find {@code content} that has {@code div} in {@code + *

Playwright
}. However, looking for {@code content} that has {@code + * article div} will fail, because the inner locator must be relative and should not use any elements outside the {@code + * content}. * *

Note that outer and inner locators must belong to the same frame. Inner locator must not contain {@code FrameLocator}s. */ @@ -683,8 +689,14 @@ public interface Locator { public Object hasText; /** - * Matches elements containing an element that matches an inner locator. Inner locator is queried against the outer one. - * For example, {@code article} that has {@code text=Playwright} matches {@code

Playwright
}. + * Narrows down the results of the method to those which contain elements matching this relative locator. For example, + * {@code article} that has {@code text=Playwright} matches {@code
Playwright
}. + * + *

Inner locator **must be relative** to the outer locator and is queried starting with the outer locator match, not the + * document root. For example, you can find {@code content} that has {@code div} in {@code + *

Playwright
}. However, looking for {@code content} that has {@code + * article div} will fail, because the inner locator must be relative and should not use any elements outside the {@code + * content}. * *

Note that outer and inner locators must belong to the same frame. Inner locator must not contain {@code FrameLocator}s. */ @@ -1262,8 +1274,14 @@ public interface Locator { } class LocatorOptions { /** - * Matches elements containing an element that matches an inner locator. Inner locator is queried against the outer one. - * For example, {@code article} that has {@code text=Playwright} matches {@code

Playwright
}. + * Narrows down the results of the method to those which contain elements matching this relative locator. For example, + * {@code article} that has {@code text=Playwright} matches {@code
Playwright
}. + * + *

Inner locator **must be relative** to the outer locator and is queried starting with the outer locator match, not the + * document root. For example, you can find {@code content} that has {@code div} in {@code + *

Playwright
}. However, looking for {@code content} that has {@code + * article div} will fail, because the inner locator must be relative and should not use any elements outside the {@code + * content}. * *

Note that outer and inner locators must belong to the same frame. Inner locator must not contain {@code FrameLocator}s. */ @@ -1289,8 +1307,14 @@ public interface Locator { public Object hasText; /** - * Matches elements containing an element that matches an inner locator. Inner locator is queried against the outer one. - * For example, {@code article} that has {@code text=Playwright} matches {@code

Playwright
}. + * Narrows down the results of the method to those which contain elements matching this relative locator. For example, + * {@code article} that has {@code text=Playwright} matches {@code
Playwright
}. + * + *

Inner locator **must be relative** to the outer locator and is queried starting with the outer locator match, not the + * document root. For example, you can find {@code content} that has {@code div} in {@code + *

Playwright
}. However, looking for {@code content} that has {@code + * article div} will fail, because the inner locator must be relative and should not use any elements outside the {@code + * content}. * *

Note that outer and inner locators must belong to the same frame. Inner locator must not contain {@code FrameLocator}s. */ @@ -1483,6 +1507,12 @@ public interface Locator { *

Defaults to {@code "device"}. */ public ScreenshotScale scale; + /** + * Text of the stylesheet to apply while making the screenshot. This is where you can hide dynamic elements, make elements + * invisible or change their properties to help you creating repeatable screenshots. This stylesheet pierces the Shadow DOM + * and applies to the inner frames. + */ + public String style; /** * 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 BrowserContext#setDefaultTimeout BrowserContext.setDefaultTimeout()} or {@link @@ -1568,6 +1598,15 @@ public interface Locator { this.scale = scale; return this; } + /** + * Text of the stylesheet to apply while making the screenshot. This is where you can hide dynamic elements, make elements + * invisible or change their properties to help you creating repeatable screenshots. This stylesheet pierces the Shadow DOM + * and applies to the inner frames. + */ + public ScreenshotOptions setStyle(String style) { + this.style = style; + 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 BrowserContext#setDefaultTimeout BrowserContext.setDefaultTimeout()} or {@link diff --git a/playwright/src/main/java/com/microsoft/playwright/Page.java b/playwright/src/main/java/com/microsoft/playwright/Page.java index 751fe68e..7259936f 100644 --- a/playwright/src/main/java/com/microsoft/playwright/Page.java +++ b/playwright/src/main/java/com/microsoft/playwright/Page.java @@ -1924,8 +1924,14 @@ public interface Page extends AutoCloseable { } class LocatorOptions { /** - * Matches elements containing an element that matches an inner locator. Inner locator is queried against the outer one. - * For example, {@code article} that has {@code text=Playwright} matches {@code

Playwright
}. + * Narrows down the results of the method to those which contain elements matching this relative locator. For example, + * {@code article} that has {@code text=Playwright} matches {@code
Playwright
}. + * + *

Inner locator **must be relative** to the outer locator and is queried starting with the outer locator match, not the + * document root. For example, you can find {@code content} that has {@code div} in {@code + *

Playwright
}. However, looking for {@code content} that has {@code + * article div} will fail, because the inner locator must be relative and should not use any elements outside the {@code + * content}. * *

Note that outer and inner locators must belong to the same frame. Inner locator must not contain {@code FrameLocator}s. */ @@ -1951,8 +1957,14 @@ public interface Page extends AutoCloseable { public Object hasText; /** - * Matches elements containing an element that matches an inner locator. Inner locator is queried against the outer one. - * For example, {@code article} that has {@code text=Playwright} matches {@code

Playwright
}. + * Narrows down the results of the method to those which contain elements matching this relative locator. For example, + * {@code article} that has {@code text=Playwright} matches {@code
Playwright
}. + * + *

Inner locator **must be relative** to the outer locator and is queried starting with the outer locator match, not the + * document root. For example, you can find {@code content} that has {@code div} in {@code + *

Playwright
}. However, looking for {@code content} that has {@code + * article div} will fail, because the inner locator must be relative and should not use any elements outside the {@code + * content}. * *

Note that outer and inner locators must belong to the same frame. Inner locator must not contain {@code FrameLocator}s. */ @@ -2450,6 +2462,12 @@ public interface Page extends AutoCloseable { *

Defaults to {@code "device"}. */ public ScreenshotScale scale; + /** + * Text of the stylesheet to apply while making the screenshot. This is where you can hide dynamic elements, make elements + * invisible or change their properties to help you creating repeatable screenshots. This stylesheet pierces the Shadow DOM + * and applies to the inner frames. + */ + public String style; /** * 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 BrowserContext#setDefaultTimeout BrowserContext.setDefaultTimeout()} or {@link @@ -2556,6 +2574,15 @@ public interface Page extends AutoCloseable { this.scale = scale; return this; } + /** + * Text of the stylesheet to apply while making the screenshot. This is where you can hide dynamic elements, make elements + * invisible or change their properties to help you creating repeatable screenshots. This stylesheet pierces the Shadow DOM + * and applies to the inner frames. + */ + public ScreenshotOptions setStyle(String style) { + this.style = style; + 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 BrowserContext#setDefaultTimeout BrowserContext.setDefaultTimeout()} or {@link @@ -7030,6 +7057,12 @@ public interface Page extends AutoCloseable { * @since v1.8 */ void uncheck(String selector, UncheckOptions options); + /** + * Removes all routes created with {@link Page#route Page.route()} and {@link Page#routeFromHAR Page.routeFromHAR()}. + * + * @since v1.41 + */ + void unrouteAll(); /** * Removes a route created with {@link Page#route Page.route()}. When {@code handler} is not specified, removes all routes * for the {@code url}. 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 f0e85770..9108ea74 100644 --- a/playwright/src/main/java/com/microsoft/playwright/impl/BrowserContextImpl.java +++ b/playwright/src/main/java/com/microsoft/playwright/impl/BrowserContextImpl.java @@ -568,6 +568,14 @@ class BrowserContextImpl extends ChannelOwner implements BrowserContext { return tracing; } + @Override + public void unrouteAll() { + withLogging("BrowserContext.unrouteAll", () -> { + routes.removeAll(); + updateInterceptionPatterns(); + }); + } + @Override public void unroute(String url, Consumer handler) { unroute(new UrlMatcher(this.baseUrl, url), handler); 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 aa27b619..873842bd 100644 --- a/playwright/src/main/java/com/microsoft/playwright/impl/PageImpl.java +++ b/playwright/src/main/java/com/microsoft/playwright/impl/PageImpl.java @@ -1226,6 +1226,14 @@ public class PageImpl extends ChannelOwner implements Page { () -> mainFrame.uncheckImpl(selector, convertType(options, Frame.UncheckOptions.class))); } + @Override + public void unrouteAll() { + withLogging("Page.unrouteAll", () -> { + routes.removeAll(); + updateInterceptionPatterns(); + }); + } + @Override public void unroute(String url, Consumer handler) { unroute(new UrlMatcher(browserContext.baseUrl, url), handler); diff --git a/playwright/src/main/java/com/microsoft/playwright/impl/Router.java b/playwright/src/main/java/com/microsoft/playwright/impl/Router.java index 80506215..87c274a3 100644 --- a/playwright/src/main/java/com/microsoft/playwright/impl/Router.java +++ b/playwright/src/main/java/com/microsoft/playwright/impl/Router.java @@ -66,8 +66,8 @@ class Router { .collect(Collectors.toList()); } - int size() { - return routes.size(); + void removeAll() { + routes.clear(); } enum HandleResult { NoMatchingHandler, Handled, Fallback, PendingHandler } diff --git a/playwright/src/test/java/com/microsoft/playwright/TestBrowserContextBasic.java b/playwright/src/test/java/com/microsoft/playwright/TestBrowserContextBasic.java index 5f477a3a..4bdf4c3b 100644 --- a/playwright/src/test/java/com/microsoft/playwright/TestBrowserContextBasic.java +++ b/playwright/src/test/java/com/microsoft/playwright/TestBrowserContextBasic.java @@ -236,8 +236,17 @@ public class TestBrowserContextBasic extends TestBase { void shouldWorkWithOfflineOption() { BrowserContext context = browser.newContext(new Browser.NewContextOptions().setOffline(true)); Page page = context.newPage(); - assertThrows(PlaywrightException.class, () -> page.navigate(server.EMPTY_PAGE)); - + if (isFirefox()) { + // Firefox navigates to an error page, and this navigation might conflict with the + // next navigation we do in test. + // So we need to wait for the navigation explicitly. + boolean[] frameNavigated = { false }; + page.onFrameNavigated(frame -> frameNavigated[0] = true); + assertThrows(PlaywrightException.class, () -> page.navigate(server.EMPTY_PAGE)); + page.waitForCondition(() -> frameNavigated[0], new Page.WaitForConditionOptions().setTimeout(10_000)); + } else { + assertThrows(PlaywrightException.class, () -> page.navigate(server.EMPTY_PAGE)); + } context.setOffline(false); Response response = page.navigate(server.EMPTY_PAGE); assertEquals(200, response.status()); diff --git a/playwright/src/test/java/com/microsoft/playwright/TestPageKeyboard.java b/playwright/src/test/java/com/microsoft/playwright/TestPageKeyboard.java index a7a0ce00..c81e60d3 100644 --- a/playwright/src/test/java/com/microsoft/playwright/TestPageKeyboard.java +++ b/playwright/src/test/java/com/microsoft/playwright/TestPageKeyboard.java @@ -374,17 +374,9 @@ public class TestPageKeyboard extends TestBase { JSHandle lastEvent = captureLastKeyDown(); page.keyboard().press("Meta"); LinkedHashMap eventData = (LinkedHashMap) lastEvent.jsonValue(); - if (isFirefox() && !isMac) { - assertEquals("OS", eventData.get("key")); - } else { - assertEquals("Meta", eventData.get("key")); - } + assertEquals("Meta", eventData.get("key")); assertEquals("MetaLeft", eventData.get("code")); - if (isFirefox() && !isMac) { - assertFalse((Boolean) eventData.get("metaKey"), eventData.toString()); - } else { - assertTrue((Boolean) eventData.get("metaKey"), eventData.toString()); - } + assertTrue((Boolean) eventData.get("metaKey"), eventData.toString()); } @Test diff --git a/playwright/src/test/java/com/microsoft/playwright/TestPageNetworkRequest.java b/playwright/src/test/java/com/microsoft/playwright/TestPageNetworkRequest.java index cd058555..2c0c95fe 100644 --- a/playwright/src/test/java/com/microsoft/playwright/TestPageNetworkRequest.java +++ b/playwright/src/test/java/com/microsoft/playwright/TestPageNetworkRequest.java @@ -134,15 +134,4 @@ public class TestPageNetworkRequest extends TestBase { assertTrue(request[0].isNavigationRequest()); assertTrue(error[0].getMessage().contains("Frame for this navigation request is not available"), error[0].getMessage()); } - - @Test - void shouldThrowIfRequestWasGCed() { - List requests = new ArrayList<>(); - page.onRequest(req -> requests.add(req)); - for (int i = 0; i < 1001; i++) { - page.navigate(server.EMPTY_PAGE); - } - PlaywrightException e = assertThrows(PlaywrightException.class, () -> requests.get(0).response()); - assertEquals("The object has been collected to prevent unbounded heap growth.", e.getMessage()); - } } diff --git a/playwright/src/test/java/com/microsoft/playwright/TestPageScreenshot.java b/playwright/src/test/java/com/microsoft/playwright/TestPageScreenshot.java index 3c901a57..d13346cd 100644 --- a/playwright/src/test/java/com/microsoft/playwright/TestPageScreenshot.java +++ b/playwright/src/test/java/com/microsoft/playwright/TestPageScreenshot.java @@ -28,7 +28,10 @@ import org.opentest4j.AssertionFailedError; import javax.imageio.ImageIO; import java.awt.image.BufferedImage; import java.io.ByteArrayInputStream; +import java.io.File; import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; import java.nio.file.Paths; import java.util.Arrays; @@ -249,4 +252,40 @@ public class TestPageScreenshot extends TestBase { assertThrows(AssertionError.class, () -> assertArrayEquals(screenshot1, screenshot2)); } + @Test + @DisabledIf(value="com.microsoft.playwright.TestBase#isWebKit", disabledReason="array lengths differ") + void shouldHideElementsBasedOnAttr() throws IOException { + page.setViewportSize(500, 500); + page.navigate(server.PREFIX + "/grid.html"); + page.locator("div").nth(5).evaluate("element => {\n" + + " element.setAttribute('data-test-screenshot', 'hide');\n" + + "}"); + byte[] actual = page.screenshot(new Page.ScreenshotOptions().setStyle("[data-test-screenshot=\"hide\"] {\n" + + " visibility: hidden;\n" + + " }")); + assertArrayEquals(expectedScreenshot("hide-should-work"), actual, "Screenshots should match"); + Object visibility = page.locator("div").nth(5).evaluate("element => element.style.visibility"); + assertEquals("", visibility); + } + + @Test + @DisabledIf(value="com.microsoft.playwright.TestBase#isWebKit", disabledReason="array lengths differ") + void shouldRemoveElementsBasedOnAttr() throws IOException { + page.setViewportSize(500, 500); + page.navigate(server.PREFIX + "/grid.html"); + page.locator("div").nth(5).evaluate("element => {\n" + + " element.setAttribute('data-test-screenshot', 'remove');\n" + + " }"); + byte[] actual = page.screenshot(new Page.ScreenshotOptions().setStyle("[data-test-screenshot=\"remove\"] {\n" + + " display: none;\n" + + " }")); + assertArrayEquals(expectedScreenshot("remove-should-work"), actual, "Screenshots should match"); + Object display = page.locator("div").nth(5).evaluate("element => element.style.display"); + assertEquals("", display); + } + + private byte[] expectedScreenshot(String name) throws IOException { + Path path = Paths.get("src/test/resources/expectations"); + return Files.readAllBytes(path.resolve(name + "-" + browserType.name() + ".png")); + } } diff --git a/playwright/src/test/java/com/microsoft/playwright/TestUnrouteBehavior.java b/playwright/src/test/java/com/microsoft/playwright/TestUnrouteBehavior.java new file mode 100644 index 00000000..52840f50 --- /dev/null +++ b/playwright/src/test/java/com/microsoft/playwright/TestUnrouteBehavior.java @@ -0,0 +1,33 @@ +package com.microsoft.playwright; + +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertTrue; + +public class TestUnrouteBehavior extends TestBase { + @Test + void contextUnrouteAllRemovesAllHandlers() { + context.route("**/*", route -> { + route.abort(); + }); + context.route("**/empty.html", route -> { + route.abort(); + }); + context.unrouteAll(); + page.navigate(server.EMPTY_PAGE); + } + + @Test + void pageUnrouteAllRemovesAllRoutes() { + page.route("**/*", route -> { + route.abort(); + }); + page.route("**/empty.html", route -> { + route.abort(); + }); + page.unrouteAll(); + Response response = page.navigate(server.EMPTY_PAGE); + assertTrue(response.ok()); + } + +} diff --git a/playwright/src/test/resources/expectations/hide-should-work-chromium.png b/playwright/src/test/resources/expectations/hide-should-work-chromium.png new file mode 100644 index 00000000..dd0549a4 Binary files /dev/null and b/playwright/src/test/resources/expectations/hide-should-work-chromium.png differ diff --git a/playwright/src/test/resources/expectations/hide-should-work-firefox.png b/playwright/src/test/resources/expectations/hide-should-work-firefox.png new file mode 100644 index 00000000..7af4f1af Binary files /dev/null and b/playwright/src/test/resources/expectations/hide-should-work-firefox.png differ diff --git a/playwright/src/test/resources/expectations/hide-should-work-webkit.png b/playwright/src/test/resources/expectations/hide-should-work-webkit.png new file mode 100644 index 00000000..b3d74594 Binary files /dev/null and b/playwright/src/test/resources/expectations/hide-should-work-webkit.png differ diff --git a/playwright/src/test/resources/expectations/remove-should-work-chromium.png b/playwright/src/test/resources/expectations/remove-should-work-chromium.png new file mode 100644 index 00000000..d35ddd42 Binary files /dev/null and b/playwright/src/test/resources/expectations/remove-should-work-chromium.png differ diff --git a/playwright/src/test/resources/expectations/remove-should-work-firefox.png b/playwright/src/test/resources/expectations/remove-should-work-firefox.png new file mode 100644 index 00000000..cbae7f34 Binary files /dev/null and b/playwright/src/test/resources/expectations/remove-should-work-firefox.png differ diff --git a/playwright/src/test/resources/expectations/remove-should-work-webkit.png b/playwright/src/test/resources/expectations/remove-should-work-webkit.png new file mode 100644 index 00000000..88699136 Binary files /dev/null and b/playwright/src/test/resources/expectations/remove-should-work-webkit.png differ diff --git a/scripts/CLI_VERSION b/scripts/CLI_VERSION index 32b7211c..94b9fbd7 100644 --- a/scripts/CLI_VERSION +++ b/scripts/CLI_VERSION @@ -1 +1 @@ -1.40.0 +1.41.0-alpha-1702670966000