diff --git a/playwright/src/test/java/com/microsoft/playwright/TestBase.java b/playwright/src/test/java/com/microsoft/playwright/TestBase.java
index 74cfb8b8..c4500b9b 100644
--- a/playwright/src/test/java/com/microsoft/playwright/TestBase.java
+++ b/playwright/src/test/java/com/microsoft/playwright/TestBase.java
@@ -16,10 +16,7 @@
package com.microsoft.playwright;
-import org.junit.jupiter.api.AfterAll;
-import org.junit.jupiter.api.AfterEach;
-import org.junit.jupiter.api.BeforeAll;
-import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.*;
import java.io.IOException;
@@ -51,10 +48,17 @@ public class TestBase {
return "firefox".equals(browserType.name());
}
- @BeforeAll
- static void launchBrowser() {
- playwright = Playwright.create();
+ static BrowserType.LaunchOptions createLaunchOptions() {
+ String headfulEnv = System.getenv("HEADFUL");
+ headful = headfulEnv != null && !"0".equals(headfulEnv) && !"false".equals(headfulEnv);
+ BrowserType.LaunchOptions options;
+ options = new BrowserType.LaunchOptions();
+ options.headless = !headful;
+ return options;
+ }
+ static void launchBrowser(BrowserType.LaunchOptions launchOptions) {
+ playwright = Playwright.create();
String browserName = System.getenv("BROWSER");
if (browserName == null) {
@@ -73,11 +77,12 @@ public class TestBase {
default:
throw new IllegalArgumentException("Unknown browser: " + browserName);
}
- String headfulEnv = System.getenv("HEADFUL");
- headful = headfulEnv != null && !"0".equals(headfulEnv) && !"false".equals(headfulEnv);
- BrowserType.LaunchOptions options = new BrowserType.LaunchOptions();
- options.headless = !headful;
- browser = browserType.launch(options);
+ browser = browserType.launch(launchOptions);
+ }
+
+ @BeforeAll
+ static void launchBrowser() {
+ launchBrowser(createLaunchOptions());
}
@AfterAll
diff --git a/playwright/src/test/java/com/microsoft/playwright/TestBrowserContextProxy.java b/playwright/src/test/java/com/microsoft/playwright/TestBrowserContextProxy.java
new file mode 100644
index 00000000..b710d694
--- /dev/null
+++ b/playwright/src/test/java/com/microsoft/playwright/TestBrowserContextProxy.java
@@ -0,0 +1,216 @@
+/*
+ * 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.DisabledIf;
+
+import java.io.OutputStreamWriter;
+import java.util.Base64;
+import java.util.List;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+public class TestBrowserContextProxy extends TestBase {
+
+ @BeforeAll
+ // Hide base class method to provide extra option.
+ static void launchBrowser() {
+ BrowserType.LaunchOptions options = createLaunchOptions();
+ options.setProxy().withServer("per-context").done();
+ launchBrowser(options);
+ }
+
+ @Test
+ void shouldThrowForMissingGlobalProxy() {
+ Browser browser = browserType.launch(createLaunchOptions());
+ try {
+ browser.newContext(new Browser.NewContextOptions().setProxy().withServer("localhost:" + server.PORT).done());
+ fail("did not throw");
+ } catch (PlaywrightException e) {
+ assertTrue(e.getMessage().contains("Browser needs to be launched with the global proxy"));
+ } finally {
+ browser.close();
+ }
+ }
+
+ void shouldThrowForBadServerValue() {
+ // Enforced by compiler in Java
+ }
+
+ @Test
+ void shouldUseProxy() {
+ server.setRoute("/target.html", exchange -> {
+ exchange.sendResponseHeaders(200, 0);
+ try (OutputStreamWriter writer = new OutputStreamWriter(exchange.getResponseBody())) {
+ writer.write("
Served by the proxy");
+ }
+ });
+ BrowserContext context = browser.newContext(new Browser.NewContextOptions().setProxy()
+ .withServer("localhost:" + server.PORT).done());
+ Page page = context.newPage();
+ page.navigate("http://non-existent.com/target.html");
+ assertEquals("Served by the proxy", page.title());
+ context.close();
+ }
+
+ @Test
+ void shouldUseProxyTwice() {
+ server.setRoute("/target.html", exchange -> {
+ exchange.sendResponseHeaders(200, 0);
+ try (OutputStreamWriter writer = new OutputStreamWriter(exchange.getResponseBody())) {
+ writer.write("Served by the proxy");
+ }
+ });
+ BrowserContext context = browser.newContext(new Browser.NewContextOptions().setProxy()
+ .withServer("localhost:" + server.PORT).done());
+ Page page = context.newPage();
+ page.navigate("http://non-existent.com/target.html");
+ page.navigate("http://non-existent-2.com/target.html");
+ assertEquals("Served by the proxy", page.title());
+ context.close();
+ }
+
+ @Test
+ void shouldUseProxyForSecondPage() {
+ server.setRoute("/target.html", exchange -> {
+ exchange.sendResponseHeaders(200, 0);
+ try (OutputStreamWriter writer = new OutputStreamWriter(exchange.getResponseBody())) {
+ writer.write("Served by the proxy");
+ }
+ });
+ BrowserContext context = browser.newContext(new Browser.NewContextOptions().setProxy()
+ .withServer("localhost:" + server.PORT).done());
+
+ Page page = context.newPage();
+ page.navigate("http://non-existent.com/target.html");
+ assertEquals("Served by the proxy", page.title());
+
+ Page page2 = context.newPage();
+ page2.navigate("http://non-existent.com/target.html");
+ assertEquals("Served by the proxy", page2.title());
+
+ context.close();
+ }
+
+ @Test
+ void shouldWorkWithIPPORTNotion() {
+ server.setRoute("/target.html", exchange -> {
+ exchange.sendResponseHeaders(200, 0);
+ try (OutputStreamWriter writer = new OutputStreamWriter(exchange.getResponseBody())) {
+ writer.write("Served by the proxy");
+ }
+ });
+ BrowserContext context = browser.newContext(new Browser.NewContextOptions().setProxy()
+ .withServer("127.0.0.1:" + server.PORT).done());
+
+ Page page = context.newPage();
+ page.navigate("http://non-existent.com/target.html");
+ assertEquals("Served by the proxy", page.title());
+ context.close();
+ }
+
+ @Test
+ void shouldAuthenticate() {
+ server.setRoute("/target.html", exchange -> {
+ List auth = exchange.getRequestHeaders().get("proxy-authorization");
+ if (auth == null) {
+ exchange.getResponseHeaders().add("Proxy-Authenticate", "Basic realm='Access to internal site'");
+ exchange.sendResponseHeaders(407, 0);
+ exchange.getResponseBody().close();
+ return;
+ }
+ exchange.sendResponseHeaders(200, 0);
+ try (OutputStreamWriter writer = new OutputStreamWriter(exchange.getResponseBody())) {
+ writer.write("" + auth.get(0) + "");
+ }
+ });
+ BrowserContext context = browser.newContext(new Browser.NewContextOptions().setProxy()
+ .withServer("localhost:" + server.PORT)
+ .withUsername("user")
+ .withPassword("secret").done());
+ Page page = context.newPage();
+ page.navigate("http://non-existent.com/target.html");
+ assertEquals("Basic " + Base64.getEncoder().encodeToString("user:secret".getBytes()), page.title());
+ context.close();
+ }
+
+ static boolean isChromiumHeadful() {
+ return isChromium() && isHeadful();
+ }
+
+ @Test
+ @DisabledIf(value="isChromiumHeadful", disabledReason="fixme")
+ void shouldExcludePatterns() {
+ server.setRoute("/target.html", exchange -> {
+ exchange.sendResponseHeaders(200, 0);
+ try (OutputStreamWriter writer = new OutputStreamWriter(exchange.getResponseBody())) {
+ writer.write("Served by the proxy");
+ }
+ });
+ BrowserContext context = browser.newContext(new Browser.NewContextOptions().setProxy()
+ .withServer("127.0.0.1:" + server.PORT)
+ // FYI: using long and weird domain names to avoid ATT DNS hijacking
+ // that resolves everything to some weird search results page.
+ //
+ // @see https://gist.github.com/CollinChaffin/24f6c9652efb3d6d5ef2f5502720ef00
+ .withBypass("1.non.existent.domain.for.the.test, 2.non.existent.domain.for.the.test, .another.test").done());
+
+ Page page = context.newPage();
+ page.navigate("http://0.non.existent.domain.for.the.test/target.html");
+ assertEquals("Served by the proxy", page.title());
+
+ try {
+ page.navigate("http://1.non.existent.domain.for.the.test/target.html");
+ fail("did not throw");
+ } catch (PlaywrightException exception) {
+ }
+
+ try {
+ page.navigate("http://2.non.existent.domain.for.the.test/target.html");
+ fail("did not throw");
+ } catch (PlaywrightException e) {
+ }
+
+ try {
+ page.navigate("http://foo.is.the.another.test/target.html");
+ fail("did not throw");
+ } catch (PlaywrightException e) {
+ }
+
+ page.navigate("http://3.non.existent.domain.for.the.test/target.html");
+ assertEquals("Served by the proxy", page.title());
+
+ context.close();
+ }
+
+ void shouldUseSocksProxy() {
+ // TODO: implement socks server
+ }
+
+ void shouldUseSocksProxyInSecondPage() {
+ // TODO: implement socks server
+ }
+
+ @Test
+ void doesLaunchWithoutAPort() {
+ BrowserContext context = browser.newContext(new Browser.NewContextOptions().setProxy()
+ .withServer("http://localhost").done());
+ context.close();
+ }
+}
diff --git a/playwright/src/test/java/com/microsoft/playwright/TestPageFill.java b/playwright/src/test/java/com/microsoft/playwright/TestPageFill.java
index a712ae3e..dbff0aa5 100644
--- a/playwright/src/test/java/com/microsoft/playwright/TestPageFill.java
+++ b/playwright/src/test/java/com/microsoft/playwright/TestPageFill.java
@@ -41,7 +41,7 @@ public class TestPageFill extends TestBase {
@Test
void shouldThrowOnUnsupportedInputs() {
page.navigate(server.PREFIX + "/input/textarea.html");
- for (String type : new String[]{"color", "file"}) {
+ for (String type : new String[]{"button", "checkbox", "file", "image", "radio", "range", "reset", "submit"}) {
page.evalOnSelector("input", "(input, type) => input.setAttribute('type', type)", type);
try {
page.fill("input", "");
diff --git a/playwright/src/test/java/com/microsoft/playwright/TestPageRoute.java b/playwright/src/test/java/com/microsoft/playwright/TestPageRoute.java
index 0a224511..a55ba70c 100644
--- a/playwright/src/test/java/com/microsoft/playwright/TestPageRoute.java
+++ b/playwright/src/test/java/com/microsoft/playwright/TestPageRoute.java
@@ -460,8 +460,15 @@ public class TestPageRoute extends TestBase {
}
@Test
- void shouldCreateARedirect() {
- page.navigate(server.PREFIX + "/empty.html");
+ @DisabledIf(value="com.microsoft.playwright.TestBase#isWebKit", disabledReason="fixme")
+ void shouldFulfillWithRedirectStatus() {
+ page.navigate(server.PREFIX + "/title.html");
+ server.setRoute("/final", exchange -> {
+ exchange.sendResponseHeaders(200, 0);
+ try (OutputStreamWriter writer = new OutputStreamWriter(exchange.getResponseBody())) {
+ writer.write("foo");
+ }
+ });
page.route("**/*", route -> {
if (!route.request().url().equals(server.PREFIX + "/redirect_this")) {
route.continue_();