Changes to Dropdown Components

In Salesforce’s Winter ’23 release, there is a small change to some dropdown components that may cause large failures in your automation scripts.  How will this affect your automation scripts, you may ask? 

In the lightning components, some of the dropdowns used were of a “button” type.  These specific dropdowns have now been changed to “input” types.  Of course that means that the locators for these have changed.  

If, for instance, the XPath locator you had for an Address Type dropdown was something like:

//button[@name=’automationType’]

The new locator to grab that same element will be:

//input[@name=’automationType’]

Seems like a pretty simple and small change, but you may be asking:

“Why would that cause large failures in my automation scripts?”

Where is your project in production?
And how were the locators implemented?

As with previous releases, this change may have a super simple solution, or it may be something that you have to go through every test and update.  Similar to the Spring ’21 release, the time needed to update these will vary based on how these locators were implemented, and where the project is in production.  We covered where the project is in production in our previous Spring ’21 blog post, so for this post we’ll cover where the locators were implemented. 

Likely this will be in two different scenarios:

  1. The locator was stored “globally” (in a wrapper class or at the top of each object’s page)
  2. The locator was stored “locally” (calling and passing the xpath when using it directly in your tests)

Locally stored locators

The most difficult, and time consuming, will be if the locator was stored “locally” (i.e. when you go to use the element, you make the call right there in the code).  In this scenario, you would need to go through all your test case’s code and find every instance of where you used that button type locator for the dropdowns, and change each findElement(By.xpath(“//button[…]”)) to findElement(By.xPath(“//input[…]”)).  While this strategy is probably fine for a small project that only uses that element a handful of times, the better way to accomplish this is by having your elements “globally” located.

Globally stored locators

The easy fix solution for “globally” keeping the locators can be done in multiple ways:

  • You may have used a practice of declaring these locators at the top of each object’s class as ‘public static By’ calls.  
  • Another practice could be to use a class filled with ‘@FindBy()’ above a public WebElement.  

Either way makes a quick way to locate and update the broken locators since you only reference them in one area of your code, and you would just replace the ‘button’ to an ‘input’ in those few locations of your code and be done.

Using In-progress with an automation script?

If you are currently In-Progress with an automation script, then updating these (either way) shouldn’t be a big issue.  The fixes will happen as part of the process of building the scripts, and if you haven’t even used that element yet, adding it for the first time wouldn’t even be noticed as from now on it is an “input” type.  For these new builds (and for any new projects), I would highly recommend to build a wrapper class for calls where you would pass a ‘By’ in the parameters, and use the good-practices of keeping these locators in one area.  This will help keep your code updates to as few places as possible so that you won’t have to dig through the code to find all your fixes in the future.

Using a UI interface automation?

For those of you using a UI interface automation (like Provar or others), this change will also affect you (at least I confirmed this with Provar).  Since the type changed, many of those automation tools will not automatically update to find the element.  You will need to use their “Refresh locator” tool, or manually update their class files to have the correct locators.  These tools generally have the advantage of keeping those locators all in one class file for you, so changing these should be as easy as just updating in one place (you shouldn’t have to update every test).

One final suggestion

If possible, using an asterisk in place of button or input would have kept your scripts from even seeing this change (i.e. By.xpath(“//*[…]”)).  Unfortunately we can’t always use that, as it could bring up multiple elements with our xpath, but where you can (for instance if you have a specific id only for that field), using asterisk can future proof your script to where changes like this won’t be noticed in your automation.

While changes to the DOM like this are not necessarily fun (especially when they break our automation scripts), these do happen, and you’ll always need to have a basic maintenance to our code, anyway.  Salesforce tries to not impact us too harshly with any changes, but in this case they may have.  My suggestion is to keep with the best practices of globally keeping your locators, and using * where able, so that small changes like this don’t have a huge time sync to fix.

Good luck, and happy coding!

Kyle Leister, Senior Quality Engineer