Skip to content

Commit

Permalink
Add examples for http_client java and python
Browse files Browse the repository at this point in the history
Signed-off-by: Viet Nguyen Duc <[email protected]>
  • Loading branch information
VietND96 committed Nov 5, 2024
1 parent e2defad commit b52ac53
Show file tree
Hide file tree
Showing 13 changed files with 394 additions and 4 deletions.
13 changes: 10 additions & 3 deletions .github/workflows/java-examples.yml
Original file line number Diff line number Diff line change
Expand Up @@ -45,10 +45,17 @@ jobs:
if: matrix.os == 'ubuntu'
run: Xvfb :99 &
- name: Set up Java
id: java
uses: actions/setup-java@v4
with:
distribution: 'temurin'
java-version: 17
- name: Import test cert non-Windows
if: matrix.os != 'windows'
run: sudo keytool -import -noprompt -trustcacerts -alias SeleniumHQ -file examples/java/src/test/resources/tls.crt -keystore ${{ steps.java.outputs.path }}/lib/security/cacerts -storepass changeit
- name: Import test cert Windows
if: matrix.os == 'windows'
run: keytool -import -noprompt -trustcacerts -alias SeleniumHQ -file examples/java/src/test/resources/tls.crt -keystore ${{ steps.java.outputs.path }}/lib/security/cacerts -storepass changeit
- name: Run Tests Stable
if: matrix.release == 'stable'
uses: nick-invision/[email protected]
Expand All @@ -57,7 +64,7 @@ jobs:
max_attempts: 3
command: |
cd examples/java
mvn -B test
mvn -B test -D"jdk.internal.httpclient.disableHostnameVerification=true"
- name: Run Tests Nightly Linux/macOS
if: matrix.release == 'nightly' && matrix.os != 'windows'
uses: nick-invision/[email protected]
Expand All @@ -70,7 +77,7 @@ jobs:
latest_snapshot=$(echo "$xml_content" | xq '.content.data."content-item"' | jq -r 'sort_by(.lastModified) | last | .text')
echo "Latest Selenium Snapshot: $latest_snapshot"
cd examples/java
mvn -B -U test -Dselenium.version="$latest_snapshot"
mvn -B -U test -D"jdk.internal.httpclient.disableHostnameVerification=true"
- name: Run Tests Nightly Windows
if: matrix.release == 'nightly' && matrix.os == 'windows'
Expand All @@ -84,4 +91,4 @@ jobs:
$latest_snapshot = $xml_content.Content | xq '.content.data.\"content-item\"' | jq -r 'sort_by(.lastModified) | last | .text'
Write-Output "Latest Selenium Snapshot: $latest_snapshot"
cd examples/java
mvn -B -U test "-Dselenium.version=$latest_snapshot"
mvn -B -U test -D"jdk.internal.httpclient.disableHostnameVerification=true"
36 changes: 36 additions & 0 deletions examples/java/src/test/java/dev/selenium/BaseTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import java.io.IOException;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Path;
import java.time.Duration;
import java.util.Arrays;
import java.util.logging.Level;
Expand All @@ -26,6 +27,9 @@ public class BaseTest {
protected WebDriverWait wait;
protected File driverPath;
protected File browserPath;
protected String username = "admin";
protected String password = "myStrongPassword";
protected String trustStorePassword = "seleniumkeystore";

public WebElement getLocatedElement(WebDriver driver, By by) {
WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(5));
Expand Down Expand Up @@ -98,6 +102,38 @@ protected URL startStandaloneGrid() {
}
}

protected URL startStandaloneGridAdvanced() {
int port = PortProber.findFreePort();
try {
System.setProperty("javax.net.ssl.trustStore", Path.of("src/test/resources/server.jks").toAbsolutePath().toString());
System.setProperty("javax.net.ssl.trustStorePassword", trustStorePassword);
System.setProperty("jdk.internal.httpclient.disableHostnameVerification", "true");
Main.main(
new String[] {
"standalone",
"--port",
String.valueOf(port),
"--selenium-manager",
"true",
"--enable-managed-downloads",
"true",
"--log-level",
"WARNING",
"--username",
username,
"--password",
password,
"--https-certificate",
Path.of("src/test/resources/tls.crt").toAbsolutePath().toString(),
"--https-private-key",
Path.of("src/test/resources/tls.key").toAbsolutePath().toString()
});
return new URL("https://localhost:" + port);
} catch (Exception e) {
throw new RuntimeException(e);
}
}

protected void enableLogging() {
Logger logger = Logger.getLogger("");
logger.setLevel(Level.FINE);
Expand Down
102 changes: 102 additions & 0 deletions examples/java/src/test/java/dev/selenium/drivers/HttpClientTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,108 @@

import dev.selenium.BaseTest;

import org.openqa.selenium.remote.http.ClientConfig;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.remote.RemoteWebDriver;

import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.TrustManagerFactory;
import javax.net.ssl.X509TrustManager;
import java.io.FileInputStream;
import java.net.URL;
import java.nio.file.Path;
import java.security.KeyStore;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.time.Duration;

import org.openqa.selenium.UsernameAndPassword;

import static java.net.http.HttpClient.Version.HTTP_1_1;

public class HttpClientTest extends BaseTest {
URL gridUrl;

@BeforeEach
public void startGrid() {
gridUrl = startStandaloneGridAdvanced();
}

@Test
public void remoteWebDriverWithClientConfig() throws Exception {
ClientConfig clientConfig = ClientConfig.defaultConfig()
.withRetries()
.sslContext(createSSLContextWithCA(Path.of("src/test/resources/tls.crt").toAbsolutePath().toString()))
.connectionTimeout(Duration.ofSeconds(300))
.readTimeout(Duration.ofSeconds(3600))
.authenticateAs(new UsernameAndPassword("admin", "myStrongPassword"))
.version(HTTP_1_1.toString());
ChromeOptions options = new ChromeOptions();
options.setEnableDownloads(true);
driver = RemoteWebDriver.builder()
.oneOf(options)
.address(gridUrl)
.config(clientConfig)
.build();
driver.quit();
}

@Test
public void remoteWebDriverIgnoreSSL() throws Exception {
ClientConfig clientConfig = ClientConfig.defaultConfig()
.withRetries()
.sslContext(createIgnoreSSLContext())
.connectionTimeout(Duration.ofSeconds(300))
.readTimeout(Duration.ofSeconds(3600))
.authenticateAs(new UsernameAndPassword("admin", "myStrongPassword"))
.version(HTTP_1_1.toString());
ChromeOptions options = new ChromeOptions();
options.setEnableDownloads(true);
driver = RemoteWebDriver.builder()
.oneOf(options)
.address(gridUrl)
.config(clientConfig)
.build();
driver.quit();
}

private SSLContext createSSLContextWithCA(String caCertPath) throws Exception {
// Load the CA certificate
FileInputStream fis = new FileInputStream(caCertPath);
CertificateFactory cf = CertificateFactory.getInstance("X.509");
X509Certificate caCert = (X509Certificate) cf.generateCertificate(fis);
// Create a KeyStore and load the CA certificate
KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
keyStore.load(null, null);
keyStore.setCertificateEntry("caCert", caCert);
// Initialize a TrustManagerFactory with the KeyStore
TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
tmf.init(keyStore);
// Create and initialize an SSLContext with the TrustManagerFactory
SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(null, tmf.getTrustManagers(), null);
return sslContext;
}

public static SSLContext createIgnoreSSLContext() throws Exception {
TrustManager[] trustAllCerts = new TrustManager[]{
new X509TrustManager() {
public X509Certificate[] getAcceptedIssuers() {
return null;
}

public void checkClientTrusted(X509Certificate[] certs, String authType) {
}

public void checkServerTrusted(X509Certificate[] certs, String authType) {
}
}
};
SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(null, trustAllCerts, new java.security.SecureRandom());
return sslContext;
}
}
Binary file added examples/java/src/test/resources/server.jks
Binary file not shown.
24 changes: 24 additions & 0 deletions examples/java/src/test/resources/tls.crt
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
-----BEGIN CERTIFICATE-----
MIIEAzCCAuugAwIBAgIIPgWI/2ppJPowDQYJKoZIhvcNAQELBQAwgYcxEDAOBgNV
BAYTB1Vua25vd24xEDAOBgNVBAgTB1Vua25vd24xEDAOBgNVBAcTB1Vua25vd24x
EzARBgNVBAoTClNlbGVuaXVtSFExJTAjBgNVBAsTHFNvZnR3YXJlIEZyZWVkb20g
Q29uc2VydmFuY3kxEzARBgNVBAMTClNlbGVuaXVtSFEwHhcNMjQxMTAzMDkwMDUz
WhcNMzQxMTAxMDkwMDUzWjCBhzEQMA4GA1UEBhMHVW5rbm93bjEQMA4GA1UECBMH
VW5rbm93bjEQMA4GA1UEBxMHVW5rbm93bjETMBEGA1UEChMKU2VsZW5pdW1IUTEl
MCMGA1UECxMcU29mdHdhcmUgRnJlZWRvbSBDb25zZXJ2YW5jeTETMBEGA1UEAxMK
U2VsZW5pdW1IUTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKVTx0e5
6/75QgE5E6rTYPlTkIxDjZylOMT2YBNuB8vIFZkSaCtLEqto0XTVV6dQc8Ge41QV
rkt7DID1oN40rvWZdla9/2bVhCsWsRiXlvrKDbjoUi5kiLcfKJW+erUWs28xnLOw
bvGNLLAjEUitKKGpR1vsSMOuvMN9VnsSkn9smAHLT2y41CjKpvdkq+OCUdnqfYju
vV6OthRPXFMsDb1fYqZfE7fZhLc806Rg31qLssNVPwxt6VeNYi1/e5cWYeKIJQoj
sFkqIdvu7xHtR7Qu1tNdeQoiDhMS7VLdZDsnAAtQLHvyAVEBicBX95VrGnOTlKdk
+UDwyOP6djCISzUCAwEAAaNxMG8wHQYDVR0OBBYEFNrLCgZ7d2vfurWaJ4wa8O/T
PfXPME4GA1UdEQEB/wREMEKCCWxvY2FsaG9zdIITc2VsZW5pdW0tZ3JpZC5sb2Nh
bIISc2VsZW5pdW0tZ3JpZC5wcm9kggxzZWxlbml1bS5kZXYwDQYJKoZIhvcNAQEL
BQADggEBABtxoPrVrPO5ELzUuSXbvYKHQG9YEuoAisXsiOWmldXRRvT/yTr3nzJn
bC4dJywMW5unPdq1NoMxza0AF0KBFp1GzLDW5/KcA26R4IQi2xfQKVyRzb4vu0CY
BDbnzF7Bisj50sSI4WThtF4xLEHVmzJ2GWNp6SgAScIrdGeB320aTqUIDO8YHH+y
oeSu6qQfEcDiBWh3KD85vCIx0+L4AM3WKkP5nDq2FL6nwCdxqV7bo5/BZJEODMiW
xv/hw0r1OBn2T2Z6o3pRI92zu9sjj6PzPP80DUPl7+fqAaRlLFglXd8b+Qxojm9o
B0QN+gEM717L6WqmJGr1VC6HWQCvcCc=
-----END CERTIFICATE-----
28 changes: 28 additions & 0 deletions examples/java/src/test/resources/tls.key
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
-----BEGIN PRIVATE KEY-----
MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQClU8dHuev++UIB
OROq02D5U5CMQ42cpTjE9mATbgfLyBWZEmgrSxKraNF01VenUHPBnuNUFa5LewyA
9aDeNK71mXZWvf9m1YQrFrEYl5b6yg246FIuZIi3HyiVvnq1FrNvMZyzsG7xjSyw
IxFIrSihqUdb7EjDrrzDfVZ7EpJ/bJgBy09suNQoyqb3ZKvjglHZ6n2I7r1ejrYU
T1xTLA29X2KmXxO32YS3PNOkYN9ai7LDVT8MbelXjWItf3uXFmHiiCUKI7BZKiHb
7u8R7Ue0LtbTXXkKIg4TEu1S3WQ7JwALUCx78gFRAYnAV/eVaxpzk5SnZPlA8Mjj
+nYwiEs1AgMBAAECggEAA2D+tT3SGlmG9Tube2CLaRUW4shSVDBWmcSXn+teBUFv
MDwdfRMGoZJdw4eaXWz0wgaItV7QZjJbMKXfK44ZQaOTtP/4QLuzkjuKE4tXloO7
e5BjS5eaPrSIPGU9S0cDPvjH2oP22dYi4sJYt6ry+2ODC0Mn6o3p8Dc3Ja1HvrXA
SNImimok7YemXVMbdPyaqbu2eXjPvWAA8W9/OW2L1n4U4neM0S5Nt3tVl5sMELj5
iFC7Z+M3ZLon/54137h3xPmHYQMiPIX+PulaRLOJYSbR0dtMHhPMyWtR7GwEK4Aw
EgtDLKfa6qMv5BYsI2E0bPHRDaj39UXGeWX5/2xzyQKBgQDcMUL3sEbRmeBKhYlT
xv5ea2P4P247DDWObTDw5jLhwfmOycFcJVlaiXICpGR6hqWY8wI7kKxbQQVKFob6
JVpIHmkkRqsV8JfXVAcaH1thlKAS4NVZsOJIVBHO3JdPaCUFq7HHbBA3436aJLtC
HiINkuiNXd2dDMuDwOsfhsRFzQKBgQDANnK1P7sZSP7dJHinA2sPSbGAK8ZTbYWD
8oe/lYlLkw6qM9i8vIKCfTpfi4vh4qfjQUczdy1w2zFbxriC2+uxhEqDN2tud3/P
0CYrO0SGQKYCROrYUh0Pl1MswBeu8yT5AdrIBK3t92wfYqTWK7VUZQaUQ7YJWfXS
usbz5qIzCQKBgH8ICHt+/gxUOtqjWYu0pPFyATWp2n1EWO13PyHrnHU0BDaFXQE9
JuSdoOG3V6R8Y7Lul14n49etllCc2Hgd7ozmxn/AKVm5+M+oUYSXjI+qQANEJLHe
410Y60EtcDnGen1gBWtog57KpzJkeIf3fGvaUkGkYoMFa6/yL3N7u2YNAoGADH29
WKAKpasDvRVYrenf9D9ixKSTn+pXKesB/WZXZMzqwA7cf+90P8yplXn5HjXfmTot
yV9uWY41F/TDGuX13DRvrzVTyvsDGFs7j8WrP1pGL5GQ/XvgnZnE8vyMzXbJqVEA
ic0cDIHuyd9cPPrcLt7d3ZbE5ris7APtV/5d/hkCgYAMFCYoKcCh+9/2HOgwQ1b6
16CS71TvDBCx7+D1V3WXrIOWkNzW2SIZtnhQwglU9L7PFw6ViJAY4sB2p9hDDtcZ
e7Lotmnbrb75QQpWUyaoZMsw8l23MOGPzHKPqNiT57uOorjcFrePi9EOdERSG9+4
lRKqCFhaNBUwQ4idzO0rWA==
-----END PRIVATE KEY-----
1 change: 1 addition & 0 deletions examples/python/requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@ pytest
trio
pytest-trio
flake8
requests
87 changes: 87 additions & 0 deletions examples/python/tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
from selenium.webdriver.common.utils import free_port
from datetime import datetime
from urllib.request import urlopen
import requests
from requests.auth import HTTPBasicAuth

import pytest
from selenium import webdriver
Expand Down Expand Up @@ -236,3 +238,88 @@ def wait_for_server(url, timeout=60):
process.wait(timeout=10)
except subprocess.TimeoutExpired:
process.kill()


def _get_resource_path(file_name: str):
if os.path.abspath("").endswith("tests"):
path = os.path.abspath(f"resources/{file_name}")
else:
path = os.path.join(
os.path.dirname(
os.path.dirname(
os.path.abspath(__file__)
)
),
f"tests/resources/{file_name}",
)
return path


@pytest.fixture(scope="function")
def grid_server():
_host = "localhost"
_port = free_port()
_username = "admin"
_password = "myStrongPassword"
_path_cert = _get_resource_path("tls.crt")
_path_key = _get_resource_path("tls.key")
_path_jks = _get_resource_path("server.jks")
_truststore_pass = "seleniumkeystore"
_path = os.path.join(
os.path.dirname(
os.path.dirname(
os.path.dirname(
os.path.abspath(__file__)
)
)
),
"selenium-server-4.26.0.jar",
)

args = [
"java",
f"-Djavax.net.ssl.trustStore={_path_jks}",
f"-Djavax.net.ssl.trustStorePassword={_truststore_pass}",
"-Djdk.internal.httpclient.disableHostnameVerification=true",
"-jar",
_path,
"standalone",
"--port",
str(_port),
"--selenium-manager",
"true",
"--enable-managed-downloads",
"true",
"--username",
_username,
"--password",
_password,
"--https-certificate",
_path_cert,
"--https-private-key",
_path_key,
]

process = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE)

def wait_for_server(url, timeout=60):
start = time.time()
while time.time() - start < timeout:
try:
requests.get(url, verify=_path_cert, auth=HTTPBasicAuth(_username, _password))
return True
except OSError as e:
print(e)
time.sleep(0.2)
return False

if not wait_for_server(f"https://{_host}:{_port}/status"):
raise RuntimeError(f"Selenium server did not start within the allotted time.")

yield f"https://{_host}:{_port}"

process.terminate()
try:
process.wait(timeout=10)
except subprocess.TimeoutExpired:
process.kill()
Loading

0 comments on commit b52ac53

Please sign in to comment.