Using Lists to get UI elements with nearly impossible selectors

if you have a list of elements with identical selectors. The element you are interested in is an element of that list. But it does not always appear in the same place in the list. Sometimes it might be the third element in the list, other times it might be the second, or the fourth, and so on. You only know that using getText() on the element returns a known text.

if the element you are searching for has a different selector each time you open the page. You know only the type of element it is (whether it is a button, or an a element representing a link, or an img element) and what text should be displayed on that element.

if the element you are looking for does not even have any attached attributes. That means it is only a tag, without an id or class, or anything else except for the tag name (tag being ‘a’ for links, ‘img’ for images, and so on). You know what getText() should return when applied to that element.

In fact, this approach can be used when the only constant about the element is that using getText() on it will return the same text every time, a text known in advance. So you are looking for an element whose displayed text is known.

What can you do in such a situation? You can use an approach based on identifying the element you are searching for as being the nth element in a List. Remember my post on lists? It will help understand what i am proposing below.

As an example, let’s assume that the element is part of a group of elements that can be identified by the same CSS or XPATH selector. I will not go into what the “commonSelector” is. It might be a class, it might be something more complex. For the sake of simplicity, right now, consider it to be whatever selector that applies to the group of elements out of which you need to choose the one you need.

Normally when you wanted to search for an element with a given text displayed on it, you would manually identify, maybe with Firebug, the unique selector of the element, then you would probably check for its’ text.

In this case, since you have no unique selector for your element, you will extract the list of elements having the same “commonSelector”. From a code perspective that means:

Now, let’s assume that what you are interested in is an element out of this list that displays a certain label. Therefore, that the ‘getText’ method, called on that element, will return the expected text. Let’s name it “expectedText”.

In order to identify which element out of the list is the correct one, an iteration will be done over the list. For each of the elements of the list, the result of getText() applied on the element will be compared to “expectedText”. If an element out of the list matches this condition, that is the one you are interested in, so identifying the element requires identifying which element in the list displays the label you are looking for.

Example

In the test method of this class, the first step is calling another method that generates an HTML that illustrates the approach of this post. The HTML represents a list of elements (a bunch of <li> elements) that display random text, except for one element that displays “My favourite element”, which is the one the test is looking for. Each time the test is run, this element is found at a different position in the list. Each element also has a random class attribute that is different every time the test runs.

Basically i wrote a little bit of code that generates a different HTML each time you run the test, just to show the beauty of this approach. This HTML is stored to a local file, which is then opened in the browser.

So, let’s assume that the test is run. The resulting HTML that will be opened in the browser and tested is the following:

This is some random text HsKWWCmhxyoUjPHzeuMl

This is some random text jNYTerIGPEoTsPMGLJgz

This is some random text rSnwgJVGmZmFADJUdcQv

This is some random text YQLDuLTjsrWUdhMhBaLZ

This is some random text BTGmotkpicHXXcjnqhCJ

This is some random text AOsUPosiXxOgxGlQwBcX

This is some random text QSslncKlDdVaUYVAFMns

This is some random text flQKLrDBkLQNtKTkdCrI

This is some random text IVpMNKNiDSynSQtAbmXY

My favourite element

This is some random text ABaPYQzYqWTdNWLCfszM

So, since “My favourite element” appears at random places each the time the test is run, identifying it will be done as follows:

since all the elements have the <li> tag, but a different class attribute each time the test runs, a List (Java list) will be used to store the WebElements of the page (all the <li> elements):

@FindBy(how=How.CSS, using=“li“) publicList<WebElement> listElements;

the list is then iterated.

for (int i=0; i< page.listElements.size(); i++) {

for each element of the list, a call to getText() is made to check for the text displayed for each element.

if the result of getText() is “My favourite” element, the index at which the element is found in the list is displayed, together with the randomly generated class attribute of the element. Of course, in real tests, you might want to somehow interact with that element (maybe click on it). But for the sake of this post, just identifying where the required element is found is enough.

For best understanding the example, take a look at the code. It is all rather simple: store the elements with the commons selector in a Java List, iterate over it, and compare the result of getText() on each list element to the text you are looking for, and you found your element.

Of course, take into consideration the case when several elements have the same displayed text, and treat this case accordingly.