Breaking Changes in Selenium – how we handled them!

Breaking changes in Selenium.jpg

If you are in the business of creating Quality Software, every day can throw up a surprise or two. How one overcomes these day-to-day challenges often defines the course of your success. Here’s one such challenge we recently faced, we thought of sharing with you. We would love to hear your feedback.

Like any good software developer, we tend to treat breaking backward compatibility as a crime and work hard to protect our end-users from facing any consequences resulting from unexpected changes. That said, we live in a world where change is the only constant! It’s always a challenge to absorb the changes.

For our Scriptless Test Automation platform, we use Selenium WebDriver to interact with the Browsers. We generally use a stable version of Selenium webdriver as a base line for our own development. However, we end up supporting multiple versions and combinations of supported browsers/OS combinations, as our customers demand it. During the regression phase of a particular product update release, our QA team reported an issue that all the mouse actions (MouseHover, MouseUp, MouseDown) were not working with the Selenium WebDriver version 3.6+

We investigated the issue and figured that inside mouse actions (in the Qualitia Engine code), we use Locatable APIs. We found that these Locatable API had been refactored (as well as deprecated) by Selenium community in SE 3.6+ and the community recommended to use Actions API which they supported since SE 3.0+.

Though the challenge, henceforth, was going to be maintaining backward compatibility with Selenium versions in Qualitia (at least post SE 3.0), any of the above changes would be simple if we didn't care about backward compatibility. But then ideally we have users using various Selenium 3.x versions. We had no option but to fix this issue in Qualitia 5.0 in a manner which works across all the Selenium 3.x versions.

We also figured out that Locatable is a primitive way of accessing mouse actions so the community was forced to move to Actions API and hence, they didn't care refactoring them. This essentially caused breaking changes. After brainstorming, we could come up with a few approaches as solutions for this issue:

Potential Solution 1: The seemiingly obvious solution was to replace Locatable package statements with new package structure statements (which SE 3.6 had introduced) and compile the code with Selenium 3.6. The code would have successfully compiled. However, it would have thrown runtime exception for those mouse actions (MouseHover, MouseUp, MouseDown). This would happen since Java wouldn't find the package structure in earlier versions, which is meant for SE 3.6. We dropped this solution.

Potential Solution 2: Use Locatable APIs and write code to handle Mouse actions in Selenium version in an agnostic way. The idea was, if mouse actions fail at runtime (due to unexpected package import) catch that Exception (which means user must be using pre-SE 3.6 version) and explicitly call the Pre SE 3.6 package structure (i.e. older fully qualified Locatable package to invoke Mouse actions on Pre SE 3.6).

The pseudo code would look something as follows:

//SE 3.6 handling
Locatable driver = (Locatable) webDriver;
Mouse mouse = driver.getMouse();;
catch(RunTimeException e)
//Pre-SE 3.6- handling
com.newstructure.Locatable = (com.newstructure.Locatable) webDriver
Mouse mouse = driver.getMouse();;

This Selenium version specific exception based code and using deprecated Locatable didn’t seem to be clean and promising way. Making Selenium version assumptions for the run-time exception can turn anytime into a disaster.

Potential Solution 3: Use Actions API and change the entire implementation while maintaining the backward compatibility. Since Actions API is supported post 3.0+, it would be very safe to use them. Moreover, SE community also recommends to use them over primitive way of using Locatable mouse action. We also achieve backward comparability. There would be almost no impact to the Qualitia user, since for her, in her scriptless Qualitia steps, mouse action name and parameters would remain the same. (Although, technically speaking, the parameters would get ignored in the latest API, but that won’t break anything for the user.)

We decided to go for Solution 3. For the Qualitia User, nothing changes as we decided to live with optionally accepting the parameters, which are not used by the API. The old test cases will continue to function without any impact. The Qualitia user would blissfully be unaware of the changes happening under the hood!

With support from its vibrant community and the constantly evolving landscape of browser-based technologies, Selenium will continue to evolve! It’s also expected that once in a while we have to face breaking changes. We should strive to keep our code as much future-proof as possible and maintain backward compatibility, while doing so.

Writing Quality Software is a tough job! Especially so when the environment surrounding you is constantly evolving.

Author Name: Omkar Karmarkar