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(...))
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 Selenium You 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.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.