I use selenium for end-to-end test with chromeDriver. The websites to test require an ssl certificate. When I manually open the browser, there is a popup that lets me select an installed certificate. Different tests access different URLs and also need different certificates. However, if I run the tests in headless mode, there is no popup. So I need a way to programatically set a certificate (eg. set a .pem
file) to be used for the current test.
How can I achieve this? I tried setting up a browserMob proxy which I then configured as a proxy in selenium - however, this does not seem to do anything... Are there better approaches? What am I doing wrong? Here's what I tried:
PemFileCertificateSource pemFileCertificateSource = new PemFileCertificateSource(
new File("myCertificate.pem"),
new File("myPrivateKey.pem"),
"myPrivateKeyPassword");
ImpersonatingMitmManager mitmManager = ImpersonatingMitmManager.builder()
.rootCertificateSource(pemFileCertificateSource)
.build();
BrowserMobProxy browserMobProxy = new BrowserMobProxyServer();
browserMobProxy.setTrustAllServers(true);
browserMobProxy.setMitmManager(mitmManager);
browserMobProxy.start(8080);
ChromeOptions chromeOptions = new ChromeOptions();
chromeOptions.setProxy(ClientUtil.createSeleniumProxy(browserMobProxy));
WebDriver webDriver = new ChromeDriver(chromeOptions);
// use the webdriver for tests, e.g. assertEquals("foo", webDriver.findElement(...))
Selenium webdriver is capable of handling SSL certificate in the Safari browser. This is done with the help of the DesiredCapabilities class. We shall create an object of this class. Then apply the setCapability method on it and set the value of property CapabilityType.
We can handle SSL certificate with Selenium webdriver in Chrome browser. A SSL is the standardized protocol used to create a connection between the browser and server. The information exchanged via a SSL certificate is encrypted and it verifies if the information is sent to the correct server.
In the Websites and Domains section for the domain name you want to use, click SSL/TLS Certificates. Click Add SSL Certificate. Enter a Certificate name, complete the fields in the Settings section, and then click Request. Click the name of the certificate you added to Plesk.
So apparantly this is not possible with BrowserMob out of the box. I therefore wrote a proxy extension SeleniumSslProxy
that can be plugged into Selenium and adds certificate based authentication to create a HTTPS connection.
This is how it works:
SSLContext
given a certificate (.pfx file) and password Response
to a netty FullHttpResponse
so it can be handled by SeleniumYou can find the code on github. Here's an example how it can be used in Selenium end-to-end tests (also works in headless mode):
@Before
public void setup() {
ClassLoader classLoader = ClassLoader.getSystemClassLoader();
File clientSslCertificate = new File(
classLoader.getResource("certificates/some-certificate.pfx").getFile());
String certificatePassword = "superSecret";
this.proxy = new SeleniumSslProxy(clientSslCertificate, certificatePassword);
this.proxy.start();
ChromeOptions chromeOptions = new ChromeOptions();
chromeOptions.setProxy(proxy);
this.webDriver = new ChromeDriver(chromeOptions);
}
@Test
public void pageTitleIsFoo() {
// given
String url = "http://myurl.lol";
// NOTE: do not use https in the URL here. It will be converted to https by the proxy.
// when
this.webDriver.get(url);
this.webDriver.manage().timeouts().implicitlyWait(5, SECONDS);
// then
WebElement title = this.webDriver.findElement(By.className("title"));
assertEquals("Foo", title.getText());
}
@After
public void teardown() {
this.webDriver.quit();
this.proxy.stop();
}
Note that I only used chromeDriver and never tested it with other drivers. Minor adjustments to the SeleniumSslProxy
might be necessary to be used with other drivers.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With