In the realm of web testing, encountering sites with basic authentication is commonplace. Handling basic authentication seamlessly within test scenarios is essential for comprehensive testing coverage. Selenium offers various approaches to tackle basic authentication challenges. This blog delves into the nuances of working with basic authentication using Selenium’s uriPredicate function, exploring different strategies and techniques to ensure smooth authentication integration within your test suite.
Understanding Basic Authentication
Basic authentication is a simple authentication scheme built into the HTTP protocol. It involves sending a username and password in the HTTP request header. When accessing a protected resource on a website, the server prompts the client to provide credentials, typically via a login dialog box. Once authenticated, the client can access the resource. This type of dialogue box cannot be handled directly using locators, hence we need to use other strategies to handle it.
Approaches to Handle Basic Authentication
Selenium offers multiple strategies to handle basic authentication seamlessly during testing:
1. Exploring Selenium’s uriPredicate Function
Using URI Predicate Function: Selenium’s uriPredicate function allows you to intercept network requests and modify them before they are sent. This function is particularly useful for adding authentication credentials to URLs that require basic authentication.
public class BasicAuthenticationURI { public static void main(String[] args) { //chrome driver automatically WebDriverManager.chromedriver().setup(); WebDriver driver = new ChromeDriver(); //predicate URI Predicate<URI> predicatURI = uri -> uri.getHost().contains("the-internet.herokuapp.com"); //wrap driver with authentication ((HasAuthentication)driver).register(predicatURI, UsernameAndPassword.of("admin", "admin")); // test driver.get("https://the-internet.herokuapp.com/"); driver.findElement(By.linkText("Basic Auth")).click(); } }
Predicate<URI>
-
- This part of the code defines a predicate, which is a functional interface in Java’s
java.util.function
package. A predicate represents a boolean-valued function that takes an argument and returns true or false. - Here, the predicate operates on
URI
objects.
- This part of the code defines a predicate, which is a functional interface in Java’s
uri -> uri.getHost().contains("the-internet.herokuapp.com")
-
- This is a lambda expression, which is a concise way to represent an anonymous function.
- The input parameter of the lambda expression is, which represents an
URI
object. - The body of the lambda expression contains the logic to determine if the given URI meets certain criteria.
"uri.getHost()"
retrieves the host part of the URI, which typically represents the domain name.".contains("the-internet.herokuapp.com")"
checks if the host contains the specified substring “the-internet.herokuapp.com”.
The "predicateURI"
is essentially defining a condition for when the basic authentication credentials should be applied.
In this case, it checks if the host part of the URI contains “the-internet.herokuapp.com”. If it does, the predicate evaluates to true, indicating that the authentication credentials should be used.
This approach allows us to selectively apply authentication based on the host/domain of the URI. In other words, the authentication will only be triggered when navigating to pages within the “the-internet.herokuapp.com” domain.
In summary, the "predicateURI"
predicate defines the condition under which the basic authentication credentials will be applied. It checks if the host part of the URI matches a specified domain name, providing a flexible way to handle authentication based on the URL of the web page.
Registering Authentication Credentials
We then wrap the WebDriver instance with basic authentication credentials using the "register"
method. This method is part of the "HasAuthentication"
interface, which allows WebDriver instances to handle authentication. We provide the predicateURI and the credentials (username and password) using the "UsernameAndPassword.of"
method.
Testing
After setting up the authentication, we navigate to the target website (https://the-internet.herokuapp.com/
) using “driver.get()"
. Then, we interact with the page by clicking on a link with the text “Basic Auth”.
The "register"
method is particularly interesting as it allows us to selectively apply authentication based on the URI of the web page. This can be useful when dealing with multiple domains or when we only want to apply authentication under specific conditions.
2. Browser Capabilities
Some browsers, such as Chrome, support passing basic authentication credentials directly in the browser URL. By embedding the username and password in the URL itself, Selenium can navigate directly to the authenticated page without the need for additional prompts.
public class BasicAuthentication { public static void main(String[] args) { //initialize chrome driver WebDriverManager.chromedriver().setup(); WebDriver driver = new ChromeDriver(); // add credentials username = admin, password = admin //Syntax to embed creds in the URL > "https://" + USERNAME + ":" + PASSWORD + "@the-internet.herokuapp.com/" driver.get("https://admin:admin@the-internet.herokuapp.com/"); driver.findElement(By.linkText("Basic Auth")).click(); } }
3. Third-Party Tools and Libraries: AutoIT
Various third-party tools and libraries integrate seamlessly with Selenium to handle basic authentication. For example, libraries like AutoIT offer functionalities to interact with authentication dialogs, enabling automated login processes. AutoIT is a powerful scripting language and automation tool primarily designed for Windows operating systems. While Selenium is proficient in web automation tasks, AutoIT specializes in automating Windows-based interactions, including handling authentication dialog boxes. By integrating AutoIT scripts into Selenium workflows, users can seamlessly perform various automation tasks like File Operations, Keyboard and Mouse Input, interacting with GUI elements such as buttons, text fields, and dialog boxes, and more
To use AutoIT, we need to perform installation and configurations. Hence, we will discuss the detailed process of using AutoIT with Selenium for basic authentication, file upload from local, and file download. Stay tuned for it!
4. Headless Browser Authentication
Headless browsers like Headless Chrome or PhantomJS can handle basic authentication without the need for visible browser windows. Selenium can leverage these headless browsers to execute tests involving basic authentication in a streamlined manner.
Conclusion
Handling basic authentication seamlessly within Selenium tests is crucial for robust and comprehensive web testing. By leveraging Selenium’s uriPredicate function and exploring alternative approaches, testers can streamline the authentication process and ensure smooth test execution. Stay tuned for more insights as we continue to explore advanced web testing techniques with Selenium and Chrome DevTools Protocol. Happy testing!