How To Access Basic Auth with Selenium
The Problem
Sometimes you'll work with applications that are secured behind Basic HTTP Authentication ( Basic Auth). In order to access them you'll need to pass credentials to the site when requesting a page. Otherwise you'll get a system level pop-up prompting you for a username and password -- rendering Selenium helpless.
Before Selenium 2 we were able to accomplish this by injecting credentials into a custom header. But now the cool kid way to do it it was something like BrowserMob Proxy. Some people are solving this with browser specific configurations too.
But all of this feels heavy. Instead, let's look at a simple approach that is browser agnostic and quick to setup.
A Solution
By specifying the username and password in the URL when visiting a page with Selenium, we can a side-step the system level dialog box from Basic Auth and avoid the need to set up a proxy server. This approach will work for both HTTP or HTTPS pages.
Let's take a look at an example.
An Example
First let's import our requisite classes (for annotations (e.g.,
org.junit.After
, etc.), driving the browser with Selenium (e.g.,org.openqa.selenium.WebDriver
, etc.), and matchers for our assertions (e.g., org.hamcrest.CoreMatchers
, etc.)) and start our class with some setup and teardown methods.// filename: WorkWithBasicAuth.java import org.junit.After; import org.junit.Before; import org.junit.Test; import org.openqa.selenium.WebDriver; import org.openqa.selenium.By; import org.openqa.selenium.firefox.FirefoxDriver; import static org.hamcrest.CoreMatchers.*; import static org.hamcrest.MatcherAssert.ass ertThat; public class WorkWithBasicAuth { WebDriver driver; @Before public void setUp() throws Exception { driver = new FirefoxDriver(); } @After public void tearDown() throws Exception { driver.quit(); }
Now to add our test.
// filename: WorkWithBasicAuth.java // ... @Test public void workWithBasicAuthTest() { driver.get("http://admin:admin@the-internet.herokuapp. com/basic_auth"); String pageMessage = driver.findElement(By.cssSelec tor("p")).getText(); assertThat(pageMessage, containsString(" Congratulations!")); } } In the test we're loading the page by passing in the username and password in the front of the URL (e.g.,http://admin:admin@
). Once it loads we grab text from the page to make sure we ended up in the right place.Alternatively, we could have accessed this page as part of the test setup (after creating an instance of Selenium). This would have cached the Basic Auth session in the browser, enabling us to visit the page again without having to specify credentials. This is particularly useful if you have numerous pages behind Basic Auth.Here's what that would look like.// filename: WorkWithBasicAuth2.java import org.junit.After; import org.junit.Before; import org.junit.Test; import org.openqa.selenium.WebDriver; import org.openqa.selenium.By; import org.openqa.selenium.firefox.FirefoxDriver; import static org.hamcrest.CoreMatchers.*; import static org.hamcrest.MatcherAssert.ass ertThat; public class WorkWithBasicAuth2 { WebDriver driver; @Before public void setUp() throws Exception { driver = new FirefoxDriver(); driver.get("http://admin: admin@the-internet.herokuapp. com/basic_auth"); } @After public void tearDown() throws Exception { driver.quit(); } @Test public void workWithBasicAuthTest2() { driver.get("http://the- internet.herokuapp.com/basic_ auth"); String pageMessage = driver.findElement(By.cssSelec tor("p")).getText(); assertThat(pageMessage, containsString(" Congratulations!")); } } NOTE: If your application serves both HTTP and HTTPS pages from behind Basic Auth then you will need to load one of each type before executing your test steps. Otherwise you will get authorization errors when switching between HTTP and HTTPS because the browser can't use Basic Auth credentials interchangeably (e.g. HTTP for HTTPS and vice versa).
Comments
Post a Comment