diff --git a/README.md b/README.md index 4448d474e..2831c78ae 100644 --- a/README.md +++ b/README.md @@ -10,9 +10,9 @@ Playwright is a Java library to automate [Chromium](https://www.chromium.org/Hom | | Linux | macOS | Windows | | :--- | :---: | :---: | :---: | -| Chromium 139.0.7258.5 | :white_check_mark: | :white_check_mark: | :white_check_mark: | +| Chromium 140.0.7339.16 | :white_check_mark: | :white_check_mark: | :white_check_mark: | | WebKit 26.0 | ✅ | ✅ | ✅ | -| Firefox 140.0.2 | :white_check_mark: | :white_check_mark: | :white_check_mark: | +| Firefox 141.0 | :white_check_mark: | :white_check_mark: | :white_check_mark: | ## Documentation diff --git a/examples/pom.xml b/examples/pom.xml index 7474e88fa..5b55e1735 100644 --- a/examples/pom.xml +++ b/examples/pom.xml @@ -10,7 +10,7 @@ Playwright Client Examples UTF-8 - 1.54.0 + 1.55.0 diff --git a/playwright/src/main/java/com/microsoft/playwright/APIRequest.java b/playwright/src/main/java/com/microsoft/playwright/APIRequest.java index ba3090b79..5e0cc42c5 100644 --- a/playwright/src/main/java/com/microsoft/playwright/APIRequest.java +++ b/playwright/src/main/java/com/microsoft/playwright/APIRequest.java @@ -51,6 +51,10 @@ class NewContextOptions { * {@code pfx}). Optionally, {@code passphrase} property should be provided if the certificate is encrypted. The {@code * origin} property should be provided with an exact match to the request origin that the certificate is valid for. * + *

Client certificate authentication is only active when at least one client certificate is provided. If you want to reject + * all client certificates sent by the server, you need to provide a client certificate with an {@code origin} that does + * not match any of the domains you plan to visit. + * *

NOTE: When using WebKit on macOS, accessing {@code localhost} will not pick up client certificates. You can make it work by * replacing {@code localhost} with {@code local.playwright}. */ @@ -134,6 +138,10 @@ public NewContextOptions setBaseURL(String baseURL) { * {@code pfx}). Optionally, {@code passphrase} property should be provided if the certificate is encrypted. The {@code * origin} property should be provided with an exact match to the request origin that the certificate is valid for. * + *

Client certificate authentication is only active when at least one client certificate is provided. If you want to reject + * all client certificates sent by the server, you need to provide a client certificate with an {@code origin} that does + * not match any of the domains you plan to visit. + * *

NOTE: When using WebKit on macOS, accessing {@code localhost} will not pick up client certificates. You can make it work by * replacing {@code localhost} with {@code local.playwright}. */ diff --git a/playwright/src/main/java/com/microsoft/playwright/Browser.java b/playwright/src/main/java/com/microsoft/playwright/Browser.java index 265e02fdb..793ea1dc5 100644 --- a/playwright/src/main/java/com/microsoft/playwright/Browser.java +++ b/playwright/src/main/java/com/microsoft/playwright/Browser.java @@ -106,6 +106,10 @@ class NewContextOptions { * {@code pfx}). Optionally, {@code passphrase} property should be provided if the certificate is encrypted. The {@code * origin} property should be provided with an exact match to the request origin that the certificate is valid for. * + *

Client certificate authentication is only active when at least one client certificate is provided. If you want to reject + * all client certificates sent by the server, you need to provide a client certificate with an {@code origin} that does + * not match any of the domains you plan to visit. + * *

NOTE: When using WebKit on macOS, accessing {@code localhost} will not pick up client certificates. You can make it work by * replacing {@code localhost} with {@code local.playwright}. */ @@ -323,6 +327,10 @@ public NewContextOptions setBypassCSP(boolean bypassCSP) { * {@code pfx}). Optionally, {@code passphrase} property should be provided if the certificate is encrypted. The {@code * origin} property should be provided with an exact match to the request origin that the certificate is valid for. * + *

Client certificate authentication is only active when at least one client certificate is provided. If you want to reject + * all client certificates sent by the server, you need to provide a client certificate with an {@code origin} that does + * not match any of the domains you plan to visit. + * *

NOTE: When using WebKit on macOS, accessing {@code localhost} will not pick up client certificates. You can make it work by * replacing {@code localhost} with {@code local.playwright}. */ @@ -674,6 +682,10 @@ class NewPageOptions { * {@code pfx}). Optionally, {@code passphrase} property should be provided if the certificate is encrypted. The {@code * origin} property should be provided with an exact match to the request origin that the certificate is valid for. * + *

Client certificate authentication is only active when at least one client certificate is provided. If you want to reject + * all client certificates sent by the server, you need to provide a client certificate with an {@code origin} that does + * not match any of the domains you plan to visit. + * *

NOTE: When using WebKit on macOS, accessing {@code localhost} will not pick up client certificates. You can make it work by * replacing {@code localhost} with {@code local.playwright}. */ @@ -891,6 +903,10 @@ public NewPageOptions setBypassCSP(boolean bypassCSP) { * {@code pfx}). Optionally, {@code passphrase} property should be provided if the certificate is encrypted. The {@code * origin} property should be provided with an exact match to the request origin that the certificate is valid for. * + *

Client certificate authentication is only active when at least one client certificate is provided. If you want to reject + * all client certificates sent by the server, you need to provide a client certificate with an {@code origin} that does + * not match any of the domains you plan to visit. + * *

NOTE: When using WebKit on macOS, accessing {@code localhost} will not pick up client certificates. You can make it work by * replacing {@code localhost} with {@code local.playwright}. */ diff --git a/playwright/src/main/java/com/microsoft/playwright/BrowserType.java b/playwright/src/main/java/com/microsoft/playwright/BrowserType.java index 0a2782fc9..54864b3b0 100644 --- a/playwright/src/main/java/com/microsoft/playwright/BrowserType.java +++ b/playwright/src/main/java/com/microsoft/playwright/BrowserType.java @@ -491,6 +491,10 @@ class LaunchPersistentContextOptions { * {@code pfx}). Optionally, {@code passphrase} property should be provided if the certificate is encrypted. The {@code * origin} property should be provided with an exact match to the request origin that the certificate is valid for. * + *

Client certificate authentication is only active when at least one client certificate is provided. If you want to reject + * all client certificates sent by the server, you need to provide a client certificate with an {@code origin} that does + * not match any of the domains you plan to visit. + * *

NOTE: When using WebKit on macOS, accessing {@code localhost} will not pick up client certificates. You can make it work by * replacing {@code localhost} with {@code local.playwright}. */ @@ -813,6 +817,10 @@ public LaunchPersistentContextOptions setChromiumSandbox(boolean chromiumSandbox * {@code pfx}). Optionally, {@code passphrase} property should be provided if the certificate is encrypted. The {@code * origin} property should be provided with an exact match to the request origin that the certificate is valid for. * + *

Client certificate authentication is only active when at least one client certificate is provided. If you want to reject + * all client certificates sent by the server, you need to provide a client certificate with an {@code origin} that does + * not match any of the domains you plan to visit. + * *

NOTE: When using WebKit on macOS, accessing {@code localhost} will not pick up client certificates. You can make it work by * replacing {@code localhost} with {@code local.playwright}. */ @@ -1386,6 +1394,11 @@ default Browser launch() { * the **parent** directory of the "Profile Path" seen at {@code chrome://version}. * *

Note that browsers do not allow launching multiple instances with the same User Data Directory. + * + *

NOTE: Chromium/Chrome: Due to recent Chrome policy changes, automating the default Chrome user profile is not supported. + * Pointing {@code userDataDir} to Chrome's main "User Data" directory (the profile used for your regular browsing) may + * result in pages not loading or the browser exiting. Create and use a separate directory (for example, an empty folder) + * as your automation profile instead. See https://developer.chrome.com/blog/remote-debugging-port for details. * @since v1.8 */ default BrowserContext launchPersistentContext(Path userDataDir) { @@ -1406,6 +1419,11 @@ default BrowserContext launchPersistentContext(Path userDataDir) { * the **parent** directory of the "Profile Path" seen at {@code chrome://version}. * *

Note that browsers do not allow launching multiple instances with the same User Data Directory. + * + *

NOTE: Chromium/Chrome: Due to recent Chrome policy changes, automating the default Chrome user profile is not supported. + * Pointing {@code userDataDir} to Chrome's main "User Data" directory (the profile used for your regular browsing) may + * result in pages not loading or the browser exiting. Create and use a separate directory (for example, an empty folder) + * as your automation profile instead. See https://developer.chrome.com/blog/remote-debugging-port for details. * @since v1.8 */ BrowserContext launchPersistentContext(Path userDataDir, LaunchPersistentContextOptions options); diff --git a/playwright/src/main/java/com/microsoft/playwright/Page.java b/playwright/src/main/java/com/microsoft/playwright/Page.java index 3f7158283..8a00b22ff 100644 --- a/playwright/src/main/java/com/microsoft/playwright/Page.java +++ b/playwright/src/main/java/com/microsoft/playwright/Page.java @@ -5812,8 +5812,8 @@ default Locator locator(String selector) { */ Page opener(); /** - * Pauses script execution. Playwright will stop executing the script and wait for the user to either press 'Resume' button - * in the page overlay or to call {@code playwright.resume()} in the DevTools console. + * Pauses script execution. Playwright will stop executing the script and wait for the user to either press the 'Resume' + * button in the page overlay or to call {@code playwright.resume()} in the DevTools console. * *

User can inspect selectors or perform manual steps while paused. Resume will continue running the original script from * the place it was paused. diff --git a/playwright/src/test/java/com/microsoft/playwright/TestDownload.java b/playwright/src/test/java/com/microsoft/playwright/TestDownload.java index be942cf8a..9b08a1ce3 100644 --- a/playwright/src/test/java/com/microsoft/playwright/TestDownload.java +++ b/playwright/src/test/java/com/microsoft/playwright/TestDownload.java @@ -93,18 +93,12 @@ void shouldReportDownloadWhenNavigationTurnsIntoDownload() throws IOException { assertTrue(Files.exists(path)); byte[] bytes = readAllBytes(path); assertEquals("Hello world", new String(bytes, UTF_8)); - if (isChromium()) { - assertNotNull(error[0]); - assertTrue(error[0].getMessage().contains("net::ERR_ABORTED")); - assertEquals("about:blank", page.url()); - } else if (isWebKit()) { - assertNotNull(error[0]); - assertTrue(error[0].getMessage().contains("Download is starting")); - assertEquals("about:blank", page.url()); - } else { - assertNotNull(error[0]); + assertNotNull(error[0]); + if (!chromiumVersionLessThan(browser.version(), "140.0.0.0")) { assertTrue(error[0].getMessage().contains("Download is starting")); } + if (!isFirefox()) + assertEquals("about:blank", page.url()); page.close(); } diff --git a/playwright/src/test/java/com/microsoft/playwright/TestLaunch.java b/playwright/src/test/java/com/microsoft/playwright/TestLaunch.java deleted file mode 100644 index c0e60d633..000000000 --- a/playwright/src/test/java/com/microsoft/playwright/TestLaunch.java +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Copyright (c) Microsoft Corporation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.microsoft.playwright; - -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.condition.EnabledIf; -import org.junit.jupiter.api.io.TempDir; - -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.util.List; - -import static com.microsoft.playwright.Utils.mapOf; -import static java.util.Arrays.asList; -import static org.junit.jupiter.api.Assertions.*; - -public class TestLaunch extends TestBase { - - @Override - @BeforeAll - // Hide base class method to not launch browser. - void launchBrowser() { - } - - @Override - void createContextAndPage() { - // Do nothing - } - - @Test - void passEnvVar() { - BrowserType.LaunchOptions options = new BrowserType.LaunchOptions(); - options.setEnv(mapOf("DEBUG", "pw:protocol")); - launchBrowser(options); - } - - public static boolean canRunHeaded() { - // On linux headed browser requires xvfb. - return isHeadful() || isMac || isWindows; - } - - public static boolean canRunExtensionTest() { - return canRunHeaded() && isChromium(); - } - - @Test - @EnabledIf(value="com.microsoft.playwright.TestLaunch#canRunExtensionTest", disabledReason="Only Chromium Headed") - void shouldReturnBackgroundPages(@TempDir Path tmpDir) throws IOException { - Path profileDir = tmpDir.resolve("profile"); - Files.createDirectories(profileDir); - String extensionPath = Paths.get("src/test/resources/simple-extension").toAbsolutePath().toString(); - initBrowserType(); - BrowserContext context = browserType.launchPersistentContext(profileDir, new BrowserType.LaunchPersistentContextOptions() - .setHeadless(false) - .setArgs(asList( - "--disable-extensions-except=" + extensionPath, - "--load-extension=" + extensionPath - ))); - List backgroundPages = context.backgroundPages(); - context.onBackgroundPage(page1 -> backgroundPages.add(page1)); - context.waitForCondition(() -> !backgroundPages.isEmpty(), - new BrowserContext.WaitForConditionOptions().setTimeout(10_000)); - Page backgroundPage = backgroundPages.get(0); - assertNotNull(backgroundPage); - assertTrue(context.backgroundPages().contains(backgroundPage)); - assertFalse(context.pages().contains(backgroundPage)); - context.close(); - assertEquals(0, context.pages().size()); - assertEquals(0, context.backgroundPages().size()); - } -} diff --git a/playwright/src/test/java/com/microsoft/playwright/TestPageInterception.java b/playwright/src/test/java/com/microsoft/playwright/TestPageInterception.java index 907d37bbc..98e3694a9 100644 --- a/playwright/src/test/java/com/microsoft/playwright/TestPageInterception.java +++ b/playwright/src/test/java/com/microsoft/playwright/TestPageInterception.java @@ -186,6 +186,13 @@ void shouldWorkWithGlob() { assertTrue(urlMatches("http://playwright.dev", "http://playwright.dev/?x=y", "?x=y")); assertTrue(urlMatches("http://playwright.dev/foo/", "http://playwright.dev/foo/bar?x=y", "./bar?x=y")); + // Case insensitive matching + assertTrue(urlMatches(null, "https://playwright.dev/fooBAR", "HtTpS://pLaYwRiGhT.dEv/fooBAR")); + assertTrue(urlMatches("http://ignored", "https://playwright.dev/fooBAR", "HtTpS://pLaYwRiGhT.dEv/fooBAR")); + // Path and search query are case-sensitive + assertFalse(urlMatches(null, "https://playwright.dev/foobar", "https://playwright.dev/fooBAR")); + assertFalse(urlMatches(null, "https://playwright.dev/foobar?a=b", "https://playwright.dev/foobar?A=B")); + // This is not supported, we treat ? as a query separator. assertFalse(urlMatches(null, "http://localhost:8080/Simple/path.js", "http://localhost:8080/?imple/path.js")); assertFalse(urlMatches(null, "http://playwright.dev/", "http://playwright.?ev")); diff --git a/playwright/src/test/java/com/microsoft/playwright/TestTracing.java b/playwright/src/test/java/com/microsoft/playwright/TestTracing.java index 877bbe5f0..4b22abd27 100644 --- a/playwright/src/test/java/com/microsoft/playwright/TestTracing.java +++ b/playwright/src/test/java/com/microsoft/playwright/TestTracing.java @@ -269,27 +269,6 @@ void shouldTraceVariousAPIs(@TempDir Path tempDir) throws Exception { calls); } - @Test - public void shouldNotRecordNetworkActions(@TempDir Path tempDir) throws IOException { - context.tracing().start(new Tracing.StartOptions()); - - page.onRequest(request -> { - request.allHeaders(); - }); - page.onResponse(response -> { - response.text(); - }); - page.navigate(server.EMPTY_PAGE); - - Path traceFile1 = tempDir.resolve("trace1.zip"); - context.tracing().stop(new Tracing.StopOptions().setPath(traceFile1)); - - List events = parseTraceEvents(traceFile1); - List calls = events.stream().filter(e -> e.renderedTitle() != null).map(e -> e.renderedTitle()) - .collect(Collectors.toList()); - assertEquals(asList("Frame.goto"), calls); - } - private static class TraceEvent { String type; String name; diff --git a/playwright/src/test/resources/simple-extension/content-script.js b/playwright/src/test/resources/simple-extension/content-script.js deleted file mode 100644 index 965f99fd3..000000000 --- a/playwright/src/test/resources/simple-extension/content-script.js +++ /dev/null @@ -1,3 +0,0 @@ -console.log('hey from the content-script'); -self.thisIsTheContentScript = true; - diff --git a/playwright/src/test/resources/simple-extension/index.js b/playwright/src/test/resources/simple-extension/index.js deleted file mode 100644 index a0bb3f4ea..000000000 --- a/playwright/src/test/resources/simple-extension/index.js +++ /dev/null @@ -1,2 +0,0 @@ -// Mock script for background extension -window.MAGIC = 42; diff --git a/playwright/src/test/resources/simple-extension/manifest.json b/playwright/src/test/resources/simple-extension/manifest.json deleted file mode 100644 index da2cd082e..000000000 --- a/playwright/src/test/resources/simple-extension/manifest.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "name": "Simple extension", - "version": "0.1", - "background": { - "scripts": ["index.js"] - }, - "content_scripts": [{ - "matches": [""], - "css": [], - "js": ["content-script.js"] - }], - "permissions": ["background", "activeTab"], - "manifest_version": 2 -} diff --git a/scripts/DRIVER_VERSION b/scripts/DRIVER_VERSION index ae07da081..094d6ad00 100644 --- a/scripts/DRIVER_VERSION +++ b/scripts/DRIVER_VERSION @@ -1 +1 @@ -1.54.1 +1.55.0