Pros / cons for using multiple locators per element in Selenium?

I am testing a website that is still under construction.

Often the element identifier, class, text, or position in the DOM will change. And then the locator that I used can no longer find the element.

But the functions are still functioning properly. I do not want several tests to fail when there is no real regression.

Therefore, instead of having one locator for each element, I have a set of locators.

public static final ArrayList<By> LOGIN_ANCHOR_LOCATORS = new ArrayList<By>(); static { LOGIN_ANCHOR_LOCATORS.add(By.id("loginLink")); LOGIN_ANCHOR_LOCATORS.add(By.linkText("Login")); LOGIN_ANCHOR_LOCATORS.add(By.xpath("/html/body/div[5]/a")); } 

My element search method is as follows:

 public WebElement locateElement(ArrayList<By> locators){ // create an element to return WebElement element = null; // until the desired element is found... while (element == null){ // loop through the locators for (By locator : locators){ // try to find by locator element = customWait.until(ExpectedConditions.presenceOfElementLocated(locator)); // if not found... if (element == null){ // log the failure logFailingLocator(locator); } } } return element; } 

It tries to find an element with the first locator in the collection, and only if it fails, try the next locator.

The collection is an ArrayList (the order is determined by the order of insertion), which means that my for loop will try each locator in the order in which they were added to the list.

I initialized the list above by adding locators in a specific order. The identifier is first, because I believe that if the position of an element in the DOM changes, but it retains its identifier, then this will be the way I will most likely find the correct element. The Xpath is the last one, because even if the text id / class / text changes, but there is still the same element type in the DOM, it is probably the right element, but can be less sure than other locators.

I use free time that ignores NoSuchElementException:

 // Wait 5 seconds for an element to be present on the page, checking // for its presence once every quarter of a second. Wait<WebDriver> customWait = new FluentWait<WebDriver>(driver) .withTimeout(5L, TimeUnit.SECONDS) .pollingEvery(250L, TimeUnit.MILLISECONDS) .ignoring(NoSuchElementException.class); 

Therefore, when one locator fails, it does not interrupt the cycle - it simply registers a failure and then continues to use the next locator.

If all locators fail, then the element will remain zero, the test will fail, and most likely the reason is the actual regression of functions / functionality.

I periodically check my logs for any element with 1 or 2 failed locators and update them in my pageObject while the tests continue to run smoothly.

What are the pros or cons of creating my project this way?

+7
source share
1 answer

This is an interesting approach, but I am concerned that you might mask other issues. I would prefer to work more closely with the developers so as not to disturb the user interface problems in the first place.

Are dynamic changes to changing identifiers? If so, see if you can get a suffix on identifiers, something like _loginlink. You may also need to work with XPath, which starts with the closest static identifier: //// div [@id = 'login_link_container' / a. (Starting from the root of the document, as shown in your example, this is a pain recipe! :))

+2
source

All Articles