3 July 2024 Leave a comment QA
When using Selenium WebDriver to test web applications, you might encounter scenarios where the site requires Basic Authentication. This presents a challenge, as Selenium WebDriver does not natively support sending custom headers in HTTP requests. However, there are several solutions to bypass this limitation.
Using the URL with Embedded Credentials
One common method is embedding the credentials directly into the URL. This technique is simple and effective:
self.base_url = "http://user:pass@host"
In Java, this can be implemented as follows:
public void login(String username, String password){
WebDriver driver = getDriver();
String URL = "http://" + username + ":" + password + "@" + "link";
driver.get(URL);
driver.manage().window().maximize();
}
This approach works well for initial requests but may have limitations with subsequent AJAX calls or other HTTP requests.
Configuring FirefoxProfile for Basic Authentication
Another method involves configuring the FirefoxProfile to handle Basic Authentication:
FirefoxProfile profile = new FirefoxProfile();
profile.setPreference("network.http.phishy-userpass-length", 255);
driver = new FirefoxDriver(profile);
driver.get("http://username:password@host");
This configuration prevents Firefox from prompting for credentials and directly uses the provided username and password.
Using Chrome Extension for Headers
For Chrome, a more recent solution involves creating a tiny Chrome extension to add the necessary headers:
File authExtension = new SeleniumChromeAuthExtensionBuilder()
.withBasicAuth("Ali Baba", "Open sesame")
.withBaseUrl("https://example.org/*")
.build();
try {
ChromeOptions chromeOptions = new ChromeOptions();
chromeOptions = chromeOptions.addExtensions(authExtension);
webDriver = new ChromeDriver(chromeOptions);
} finally {
authExtension.delete();
}
This approach is highly flexible and ensures that all requests to the specified base URL include the authentication headers.
Setting Up a Proxy
Another advanced method is setting up a proxy to handle the headers for your test. This can be done using tools like Proxy Py:
from proxy.http.proxy import HttpProxyBasePlugin
from proxy.http.parser import HttpParser
from typing import Optional
import base64
class BasicAuthorizationPlugin(HttpProxyBasePlugin):
def before_upstream_connection(self, request: HttpParser) -> Optional[HttpParser]:
return request
def handle_client_request(self, request: HttpParser) -> Optional[HttpParser]:
basic_auth_header = 'Basic ' + base64.b64encode('webelement:click'.encode('utf-8')).decode('utf-8')
request.add_header('Authorization'.encode('utf-8'), basic_auth_header.encode('utf-8'))
return request
def on_upstream_connection_close(self) -> None:
pass
def handle_upstream_chunk(self, chunk: memoryview) -> memoryview:
return chunk
This method is particularly useful for handling HTTPS traffic and offers a high degree of customization.
Conclusion
While Selenium WebDriver does not natively support sending custom headers, there are several workarounds to handle Basic Authentication. Whether you choose to embed credentials in the URL, configure browser profiles, use Chrome extensions, or set up a proxy, each method has its own benefits and limitations.
For those looking for a more streamlined solution, consider using Repeato, a no-code test automation tool for iOS and Android. Repeato simplifies the process of creating, running, and maintaining automated tests for your apps, leveraging computer vision and AI to ensure efficient and effective testing. For more information, visit our documentation page.