test: implement https server (#19)
This commit is contained in:
@@ -0,0 +1,70 @@
|
||||
/**
|
||||
* 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 com.sun.net.httpserver.HttpsConfigurator;
|
||||
import com.sun.net.httpserver.HttpsParameters;
|
||||
|
||||
import javax.net.ssl.KeyManagerFactory;
|
||||
import javax.net.ssl.SSLContext;
|
||||
import javax.net.ssl.SSLParameters;
|
||||
import javax.net.ssl.TrustManagerFactory;
|
||||
import java.io.FileInputStream;
|
||||
import java.security.KeyStore;
|
||||
|
||||
class HttpsConfiguratorImpl extends HttpsConfigurator {
|
||||
|
||||
static HttpsConfigurator create() {
|
||||
return new HttpsConfiguratorImpl(createSSLContext());
|
||||
}
|
||||
|
||||
private HttpsConfiguratorImpl(SSLContext context) {
|
||||
super(context);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void configure(HttpsParameters params) {
|
||||
SSLContext sslContext = getSSLContext();
|
||||
SSLParameters sslParams = sslContext.getDefaultSSLParameters();
|
||||
sslParams.setNeedClientAuth(true);
|
||||
params.setNeedClientAuth(true);
|
||||
params.setSSLParameters(sslParams);
|
||||
}
|
||||
|
||||
// @see http://rememberjava.com/http/2017/04/29/simple_https_server.html
|
||||
private static SSLContext createSSLContext() {
|
||||
try{
|
||||
KeyStore ks = KeyStore.getInstance("JKS");
|
||||
String password = "password";
|
||||
// Generated via
|
||||
// keytool -genkey -keyalg RSA -validity 36500 -keysize 4096 -dname cn=Playwright,ou=Playwright,o=Playwright,c=US -keystore keystore.jks -storepass password -keypass password
|
||||
ks.load(new FileInputStream("src/test/resources/keys/keystore.jks"), password.toCharArray());
|
||||
|
||||
KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
|
||||
kmf.init(ks, password.toCharArray());
|
||||
|
||||
TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509");
|
||||
tmf.init(ks);
|
||||
|
||||
SSLContext sslContext = SSLContext.getInstance("TLS");
|
||||
sslContext.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
|
||||
return sslContext;
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -16,10 +16,7 @@
|
||||
|
||||
package com.microsoft.playwright;
|
||||
|
||||
import com.sun.net.httpserver.Headers;
|
||||
import com.sun.net.httpserver.HttpExchange;
|
||||
import com.sun.net.httpserver.HttpHandler;
|
||||
import com.sun.net.httpserver.HttpServer;
|
||||
import com.sun.net.httpserver.*;
|
||||
|
||||
import java.io.*;
|
||||
import java.net.InetSocketAddress;
|
||||
@@ -55,13 +52,28 @@ public class Server implements HttpHandler {
|
||||
}
|
||||
}
|
||||
|
||||
Server(int port) throws IOException {
|
||||
static Server createHttp(int port) throws IOException {
|
||||
return new Server(port, false);
|
||||
}
|
||||
|
||||
static Server createHttps(int port) throws IOException {
|
||||
return new Server(port, true);
|
||||
}
|
||||
|
||||
private Server(int port, boolean https) throws IOException {
|
||||
PORT = port;
|
||||
PREFIX = "http://localhost:" + PORT;
|
||||
CROSS_PROCESS_PREFIX = "http://127.0.0.1:" + PORT;
|
||||
PREFIX = "http" + (https ? "s" : "") + "://localhost:" + PORT;
|
||||
CROSS_PROCESS_PREFIX = "http" + (https ? "s" : "") + "://127.0.0.1:" + PORT;
|
||||
EMPTY_PAGE = PREFIX + "/empty.html";
|
||||
|
||||
server = HttpServer.create(new InetSocketAddress("localhost", port), 0);
|
||||
if (https) {
|
||||
HttpsServer httpsServer = HttpsServer.create(new InetSocketAddress("localhost", port), 0);
|
||||
httpsServer.setHttpsConfigurator(HttpsConfiguratorImpl.create());
|
||||
server = httpsServer;
|
||||
} else {
|
||||
server = HttpServer.create(new InetSocketAddress("localhost", port), 0);
|
||||
}
|
||||
|
||||
server.createContext("/", this);
|
||||
server.setExecutor(null); // creates a default executor
|
||||
|
||||
|
||||
@@ -45,7 +45,7 @@ public class TestCheck {
|
||||
|
||||
@BeforeAll
|
||||
static void startServer() throws IOException {
|
||||
server = new Server(8907);
|
||||
server = Server.createHttp(8907);
|
||||
}
|
||||
|
||||
@AfterAll
|
||||
|
||||
@@ -51,7 +51,7 @@ public class TestClick {
|
||||
|
||||
@BeforeAll
|
||||
static void startServer() throws IOException {
|
||||
server = new Server(8907);
|
||||
server = Server.createHttp(8907);
|
||||
}
|
||||
|
||||
@AfterAll
|
||||
|
||||
@@ -39,7 +39,7 @@ public class TestDialog {
|
||||
|
||||
@BeforeAll
|
||||
static void startServer() throws IOException {
|
||||
server = new Server(8907);
|
||||
server = Server.createHttp(8907);
|
||||
}
|
||||
|
||||
@AfterAll
|
||||
|
||||
@@ -37,7 +37,7 @@ public class TestElementHandleClick {
|
||||
|
||||
@BeforeAll
|
||||
static void startServer() throws IOException {
|
||||
server = new Server(8907);
|
||||
server = Server.createHttp(8907);
|
||||
}
|
||||
|
||||
@AfterAll
|
||||
|
||||
@@ -46,7 +46,7 @@ public class TestEvalOnSelector {
|
||||
|
||||
@BeforeAll
|
||||
static void startServer() throws IOException {
|
||||
server = new Server(8907);
|
||||
server = Server.createHttp(8907);
|
||||
}
|
||||
|
||||
@AfterAll
|
||||
|
||||
@@ -45,7 +45,7 @@ public class TestEvalOnSelectorAll {
|
||||
|
||||
@BeforeAll
|
||||
static void startServer() throws IOException {
|
||||
server = new Server(8907);
|
||||
server = Server.createHttp(8907);
|
||||
}
|
||||
|
||||
@AfterAll
|
||||
|
||||
@@ -39,7 +39,7 @@ public class TestFrameNavigate {
|
||||
|
||||
@BeforeAll
|
||||
static void startServer() throws IOException {
|
||||
server = new Server(8907);
|
||||
server = Server.createHttp(8907);
|
||||
}
|
||||
|
||||
@AfterAll
|
||||
|
||||
@@ -50,7 +50,7 @@ public class TestPageBasic {
|
||||
|
||||
@BeforeAll
|
||||
static void startServer() throws IOException {
|
||||
server = new Server(8907);
|
||||
server = Server.createHttp(8907);
|
||||
}
|
||||
|
||||
@AfterAll
|
||||
|
||||
@@ -42,7 +42,7 @@ public class TestPageFill {
|
||||
|
||||
@BeforeAll
|
||||
static void startServer() throws IOException {
|
||||
server = new Server(8907);
|
||||
server = Server.createHttp(8907);
|
||||
}
|
||||
|
||||
@AfterAll
|
||||
|
||||
@@ -46,7 +46,7 @@ public class TestPageRoute {
|
||||
|
||||
@BeforeAll
|
||||
static void startServer() throws IOException {
|
||||
server = new Server(8907);
|
||||
server = Server.createHttp(8907);
|
||||
}
|
||||
|
||||
@AfterAll
|
||||
|
||||
@@ -21,11 +21,14 @@ import org.junit.jupiter.api.*;
|
||||
import java.io.IOException;
|
||||
|
||||
import static com.microsoft.playwright.Page.EventType.FRAMENAVIGATED;
|
||||
import static com.microsoft.playwright.Utils.expectedSSLError;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
public class TestPageWaitForNavigation {
|
||||
private static Playwright playwright;
|
||||
private static Server server;
|
||||
private static Server httpsServer;
|
||||
private static BrowserType browserType;
|
||||
private static Browser browser;
|
||||
private static boolean isChromium;
|
||||
private static boolean isWebKit;
|
||||
@@ -37,7 +40,8 @@ public class TestPageWaitForNavigation {
|
||||
static void launchBrowser() {
|
||||
playwright = Playwright.create();
|
||||
BrowserType.LaunchOptions options = new BrowserType.LaunchOptions();
|
||||
browser = playwright.chromium().launch(options);
|
||||
browserType = playwright.chromium();
|
||||
browser = browserType.launch(options);
|
||||
isChromium = true;
|
||||
isWebKit = false;
|
||||
headful = false;
|
||||
@@ -45,7 +49,8 @@ public class TestPageWaitForNavigation {
|
||||
|
||||
@BeforeAll
|
||||
static void startServer() throws IOException {
|
||||
server = new Server(8907);
|
||||
server = Server.createHttp(8907);
|
||||
httpsServer = Server.createHttps(8908);
|
||||
}
|
||||
|
||||
@AfterAll
|
||||
@@ -109,17 +114,17 @@ public class TestPageWaitForNavigation {
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldWorkWithClickingOnLinksWhichDoNotCommitNavigation() {
|
||||
// TODO: https server
|
||||
// page.navigate(server.EMPTY_PAGE);
|
||||
// page.setContent("<a href='" + httpsServer.EMPTY_PAGE + "'>foobar</a>");
|
||||
// try {
|
||||
// page.waitForNavigation();
|
||||
// page.click("a");
|
||||
// fail("did not throw");
|
||||
// } catch (RuntimeException e) {
|
||||
// assertTrue(e.getMessage().contains(expectedSSLError(browserName)));
|
||||
// }
|
||||
void shouldWorkWithClickingOnLinksWhichDoNotCommitNavigation() throws InterruptedException {
|
||||
page.navigate(server.EMPTY_PAGE);
|
||||
page.setContent("<a href='" + httpsServer.EMPTY_PAGE + "'>foobar</a>");
|
||||
try {
|
||||
Deferred<Response> event = page.waitForNavigation();
|
||||
page.click("a");
|
||||
event.get();
|
||||
fail("did not throw");
|
||||
} catch (RuntimeException e) {
|
||||
assertTrue(e.getMessage().contains(expectedSSLError(browserType.name())), e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -43,7 +43,7 @@ public class TestPopup {
|
||||
|
||||
@BeforeAll
|
||||
static void startServer() throws IOException {
|
||||
server = new Server(8907);
|
||||
server = Server.createHttp(8907);
|
||||
}
|
||||
|
||||
@AfterAll
|
||||
|
||||
@@ -48,7 +48,7 @@ public class TestQuerySelector {
|
||||
|
||||
@BeforeAll
|
||||
static void startServer() throws IOException {
|
||||
server = new Server(8907);
|
||||
server = Server.createHttp(8907);
|
||||
}
|
||||
|
||||
@AfterAll
|
||||
|
||||
@@ -51,7 +51,7 @@ public class TestRequestContinue {
|
||||
|
||||
@BeforeAll
|
||||
static void startServer() throws IOException {
|
||||
server = new Server(8907);
|
||||
server = Server.createHttp(8907);
|
||||
}
|
||||
|
||||
@AfterAll
|
||||
|
||||
@@ -50,7 +50,7 @@ public class TestWorkers {
|
||||
|
||||
@BeforeAll
|
||||
static void startServer() throws IOException {
|
||||
server = new Server(8907);
|
||||
server = Server.createHttp(8907);
|
||||
}
|
||||
|
||||
@AfterAll
|
||||
|
||||
@@ -40,4 +40,42 @@ class Utils {
|
||||
return handle.asElement().contentFrame();
|
||||
}
|
||||
|
||||
enum OS { WINDOWS, MAC, LINUX, UNKNOWN }
|
||||
static OS getOS() {
|
||||
String name = System.getProperty("os.name").toLowerCase();
|
||||
if (name.contains("win")) {
|
||||
return OS.WINDOWS;
|
||||
}
|
||||
if (name.contains("linux")) {
|
||||
return OS.LINUX;
|
||||
}
|
||||
if (name.contains("mac os x")) {
|
||||
return OS.MAC;
|
||||
}
|
||||
return OS.UNKNOWN;
|
||||
}
|
||||
|
||||
static String expectedSSLError(String browserName) {
|
||||
switch (browserName) {
|
||||
case "chromium":
|
||||
switch (getOS()) {
|
||||
case MAC:
|
||||
return "net::ERR_CERT_INVALID";
|
||||
default:
|
||||
return "net::ERR_CERT_AUTHORITY_INVALID";
|
||||
}
|
||||
case "webkit": {
|
||||
switch (getOS()) {
|
||||
case MAC:
|
||||
return "The certificate for this server is invalid";
|
||||
case WINDOWS:
|
||||
return "SSL peer certificate or SSH remote key was not OK";
|
||||
default:
|
||||
return "Unacceptable TLS certificate";
|
||||
}
|
||||
}
|
||||
default:
|
||||
return "SSL_ERROR_UNKNOWN";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Binary file not shown.
Reference in New Issue
Block a user