Very often, a web page has many elements that use the same formats and styles. One locator may identify more than one element, making it more difficult for developers to identify unique elements. See the example below:
In the example above, there are three ‘Select’ buttons, three ‘Outstanding’ hyperlinks, and other elements presented with the same labels or icons. If you use the ‘Select’ button as the locator, then at least three elements are identified. So the problem is how to deal with such situations to locate elements accurately.
The first option you might consider is using Absolute XPath:
This option works. However, it is unable to identify which 'Select' button to locate; or if the order of the list has changed, users are very likely to click the wrong 'Select' button.
Relative XPath for groups of elements
Let’s look at the page again. You can see there are three grouped elements (three blocks) on the list. The structure of each item looks similar to that of one another. There are three ‘Select’ buttons and three ‘Outstanding’ links—however, these items are not the same. Users decide which ‘Select’ button and ‘Outstanding’ link to choose based on the associated name of the hotel. The hotels’ names are unique elements and can be good candidates for locators.
Here is the HTML code (I simplified it to demonstrate the case) of an item in the example.
<li class='hotel-link hotel-link-l clearfix' data-hotelid='995079'>
<div class='hotel-info map-info'>
<a href='/mandarin-orchard-singapore' title='Mandarin Orchard Singapore'>
Mandarin Orchard Singapore
<a href='/mandarin-orchard-singapore' target='_blank' class='hotel-review'>
<span class='review-link' data-reviewlab='Reviews'>(1,465 Reviews)</span>
<a data-index='1' href='/mandarin-orchard-singapore' target='_blank' >Select</a>
In order to define the boundary of a group of elements, you may need to find the element that encloses the group. In this example, the boundary is
<li> and all of the elements are inside the
Then, you need to determine a locator for this boundary. As a result, it is easier to locate the elements inside, which are now unique to each boundary.
//li[.//a[contains(., 'Mandarin Orchard Singapore')]]
(the locator of the 'Outstanding' link)
//li[.//a[contains(., 'Mandarin Orchard Singapore')]]//a[contains(., 'Outstanding')]
(the locator of the 'Select' button)
//li[.//a[contains(., 'Mandarin Orchard Singapore')]]//a[contains(., 'Select')]
Now, if you want to locate elements in another hotel, replace the hotel’s name with the one you want to access. Since there is no index being used, the locators still work well if the order of the hotels in the list is changed. This makes our locators more stable and easier to maintain.
Making a group of elements into a unique block is an essential task in Web UI testing. These groups of elements appear in many places in Web applications with different displays. For example:
Issue list in JIRA
Unique block: Each row in the table is a unique block Key is a good candidate for unique identifier
- Each instance of the control is a unique block
- Control’s label is a good candidate for unique identifier
This article discusses the strategies of locating Web Elements on a webpage in different situations. These locator strategies reflect the mindset of a tester when performing UI automation tests: first, think about simple static locators, then gradually increase the complexity of the solution when simple methods are no longer feasible.
It is important to mention that this following principle must be held in deciding locators: a locator must be unique, readable, and maintainable. If a locator does not uniquely represent the target element, problems will arise during the maintenance phase as there is no way to know which locator should be changed.
Trong Bui - QAA at KMS-Technology