Test automation engineers globally strive to enhance their frameworks, seeking improved stability, speed, usability, and maintainability. This continuous evolution is essential to ensure widespread framework adoption within their organizations, as outdated frameworks quickly become obsolete.
This article highlights key areas for framework updates in 2019, preparing for advancements in 2020. The focus is on addressing common “pain points” - aspects that are complex or prone to failures. Three areas identified for simplification and improvement include:
- Selenium Grid
- Waits
- Chrome DevTools
Selenium Grid, known for its setup challenges and instability, requires attention to identify potential improvements. Exploring new waits in the Selenium API can enhance test stability. Additionally, integrating Chrome DevTools, an indispensable tool for testers, with Selenium presents further optimization opportunities.
Tip #1: Dockerize Your Selenium Grid
Setting up, maintaining, and deploying Selenium Grid, especially within a CI pipeline, can be cumbersome. Utilizing pre-built Selenium Docker images provides a significantly easier, more stable, and manageable solution.
Note: The primary limitation of this approach is the lack of Internet Explorer (IE) support, as containerizing the Windows operating system remains infeasible.
Getting Set Up
To begin, ensure you have Docker and Docker Compose installed on your system. For Windows 10 or Mac users, both are typically included within the Docker Desktop.
Starting Your Grid
The official Selenium repository on Docker Hub offers pre-built Docker images for the Selenium Hub, along with Firefox and Chrome Nodes.
A straightforward way to leverage these components locally is by creating a Docker Compose file (docker-compose.yml) in your project’s root directory.
Below is an example demonstrating the creation of a Grid comprising:
- A single Selenium Hub
- One Chrome node
- One Firefox node
| |
The Docker Compose file defines your Grid’s configuration. Refer to the official documentation for detailed information on creating such files.
To launch your Grid, execute the following command in a terminal (PowerShell or Command Prompt on Windows) from your project’s root directory:
| |
Connecting to the Grid
Connecting to your Selenium Grid follows the standard procedure, with the Hub listening on port 4444 of your local machine. The example below illustrates setting up a Driver to utilize the Chrome Node.
| |
Subsequently, utilize the TestNG library to execute tests on multiple nodes concurrently.
While running multiple browsers on a single node is technically possible, it’s not recommended. Best practice dictates using one browser per node for optimal performance.
Additional Tips and Tricks
For debugging purposes, consider a debug variant of your docker-compose.yml file that retrieves the debug browser nodes. These versions include a VNC server, enabling you to monitor browser activity during test execution.
Running browsers headlessly enhances speed, and Selenium provides base images for building custom images if additional software is required.
To ensure CI pipeline stability, deploy your Grid onto Kubernetes or Swarm. This facilitates rapid Docker restoration or replacement in case of failures.
Tip #2: Smart Waits
Waits are fundamental to test automation framework stability. They eliminate the need for sleeps or pauses, mitigating slow network and cross-browser issues while enhancing test speed.
Java Automation Testing Tutorial #2: Logical Operators in Waits: Be Specific with Your Waits
The comprehensive ExpectedConditions class offers a wide range of scenarios. While ExpectedConditions.presenceOfElementLocated(locator) often suffices, prioritize methods within this class to handle every user action by integrating them into your Actions.java class. This approach strengthens tests against most cross-browser and website performance issues.
For instance, when clicking a link opens a new tab, employ ExpectedConditions.numberOfWindowsToBe(2) to ensure the tab’s availability before switching.
Utilize a wait to guarantee capturing all elements on a page during findElements usage, particularly beneficial for search result pages. For example, this line:
| |
might yield an empty List if search results are pending. Instead, leverage the numberOfElementsToBeMoreThan expected condition to wait for results exceeding zero. For example:
| |
Now, findElements executes only after search results populate.
This wait is valuable when dealing with front-end frameworks that pose challenges to Selenium, such as Angular websites. A method like this enhances test stability:
| |
You can even wait for elements to disappear from visibility. This proves useful when awaiting a pop-up’s disappearance after clicking OK or Save before proceeding.
| |
The official documentation provides a comprehensive list of methods, including those discussed. Reviewing these possibilities can significantly enhance your framework’s stability.
Java Automation Testing Tutorial #2: Logical Operators in Waits
Enhance wait resilience using logical operators. For instance, to verify an element’s presence and clickability, use the following (these examples return a boolean):
| |
The OR operator is suitable when uncertain about page title changes. Include a URL check if the initial condition fails to confirm the correct page:
| |
Use the NOT operator to ensure a checkbox is disabled after an action:
| |
Operators contribute to more resilient and less brittle waits.
Tip #3: Chrome DevTools: Simulating Network Conditions
Testing solely on localhost or local networks provides an inaccurate representation of real-world performance. Simulating varying upload and download speeds offers a realistic perspective on internet performance, where timeouts can lead to action failures. Chrome DevTools empowers such simulations.
The following code demonstrates accessing the Toptal homepage under different network conditions. First, define speeds using a TestNG data provider:
| |
Note: Upload and download throttling are in kb/s, while latency is in ms.
This data facilitates testing under diverse network conditions. Within the test, the CommandExecutor executes commands in the browser’s current session. This activates the necessary settings in Chrome’s Developer Tools functionality to simulate the slow network. Include the code within the if statement in a @BeforeClass method when running test suites.
| |
Bonus Tip: How to Manage Your Cookies
Browser cookies can lead to behavioral inconsistencies in your application based on their presence from previous sessions, like automatic user logins. Clearing cookies before test runs mitigates potential issues.
The following snippet deletes all cookies:
| |
You can delete a cookie by name:
| |
Retrieve a cookie’s content:
| |
Or get all cookies:
| |
Test Automation in 2020: Looking to the Future
Selenium 4, expected shortly, introduces significant improvements. While still under development, the availability of an alpha version warrants exploration.
Note: Track progress through the roadmap.
W3C WebDriver Standardization
Selenium 4 eliminates the JSON wire protocol for browser communication, enabling direct interaction between automated tests and browsers. This addresses Selenium’s flakiness, including browser upgrade issues, potentially boosting test speed.
A Simpler Selenium Grid
Selenium Grid becomes more stable, manageable, and easier to set up. The combined node and hub setup eliminates separate configurations. Enhanced Docker support, native parallel testing, an informative UI, and request tracing with Hooks enhance debugging capabilities.
Documentation
The Selenium documentation receives a much-needed update, addressing its stagnation since Selenium 2.0.
Changes to the API
Opera and PhantomJS browser support is discontinued. Headless execution is possible with Chrome or Firefox, with Opera’s Chromium base deemed sufficient for testing.
WebElement.getSize() and WebElement.getLocation() are consolidated into WebElement.getRect(). An API command for capturing element screenshots is also introduced.
For WebDriver Window, getPosition and getSize are replaced by getRect, while setPosition and setSize are replaced by setRect. fullscreen and minimize methods facilitate these actions within tests.
Other Notable Changes:
- Browser-specific
Optionsclasses now extend theCapabilitiesclass. driver.switchTo().parentFrame()simplifies frame navigation.nicelocators, a subclass ofBy, offer higher-level operations.- The
DevToolsAPI implementation unlocks Chrome Debugging Protocol features (and equivalents in other browsers), including:- Complete page screenshots, including off-screen elements.
- Log streaming.
- Waiting for mutation events.
- Deprecated methods and classes are removed.
Note: An Alpha version of Selenium 4 is available from the Maven repository. Testing this against your current framework (ideally in a sandbox) is recommended to prepare for the upgrade.
Conclusion
This article outlines several test automation framework improvements for enhanced stability and usability, positively impacting the software delivery lifecycle.
While these changes are beneficial, a comprehensive framework review for “pain points” is highly recommended. For instance, are you leveraging WebDriver Manager for driver management, or are manual updates still prevalent?
Regular framework reviews, at least annually or ideally biannually, are crucial. Familiarize yourself with the upcoming changes in Selenium 4.0 using the alpha releases. Be prepared for these impactful changes.
Share any novel methods or techniques discovered during your framework review in the comments section below to benefit fellow readers.
For insights into automated tests in Selenium and using Page Object models for maintainable and reusable test routines, explore “Automation in Selenium: Page Object Model and Page Factory.”