The Agile Way

The Agile Way

Share this post

The Agile Way
The Agile Way
Case Study: A Reliable Test Statement to Locate A Non-Unique Button

Case Study: A Reliable Test Statement to Locate A Non-Unique Button

There are several ways, commonly people chose a less optimal one. This article shows a stable way, using Powerful XPath.

Courtney Zhan's avatar
Courtney Zhan
Nov 04, 2023
∙ Paid
1

Share this post

The Agile Way
The Agile Way
Case Study: A Reliable Test Statement to Locate A Non-Unique Button
Share

In web test automation, generally speaking, when there is a unique ID for the target element, we use the ID locator. However, at work, the IDs do not exist. This article show how to write a reliable automated step for a common operation where multiple buttons with the same text.

The web page below has several “Like” buttons in a table. BTW, this style of web page layout is fairly common.

Example 1. Button with Unique ID

To locate the “Like” button of TestWise.

A screenshot of the page with Playwright Recorder

The HTML fragment:

<tr>
  <td>TestWise</td>
  <td><span>2007</span></td>
  <td><a href="https://agileway.com.au/testwise">https://testwisely.com/testwise</a></td>
  <td><button id="like-testwise">Like</button></td>
</tr>

The automated test step.

Easy: use “ID” because there is one for the button.

  1. Playwright

# Playwright
page.locator("#like-testwise")

2. Selenium WebDriver

driver.find_element(:id, "like-testwise")

Example 2. Button with no unique identifier or attributes

Now try to click the “Like” button for WhenWise, which does not have an ID, or any identifiable attributes.

<tr class="service_products">
   <td>WhenWise</td>
   <td>2018</td>
   <td><a href="https://whenwise.com">https://whenwise.com</a></td>
   <td><button>Like</button></td>
  </tr>

What is the optimal test statement to locate this button?

Playwright recorder suggestion.

The Playwright recorder suggests this:

page.getByRow('row', {name: 'WhenWise 2018 https://whenwise.com Like'}).
        getByRole('button');

It works, but it is no good because it is fragile. Consider the possible changes that programmers might make in the future:

  • Text Correction, e.g. “2018” => “2019”

  • Formatting, switch the data column, e.g. The year is moving from #2 to #3.

  • Adding an extra data column

  • Adding an invisible space character, such &nbsp; or an HTML entity, that shows no visual changes.

All of the above will make the test step fail.

Some might consider this: find the cell in the 5th row, then …

This has a severe shortcoming when developers add a new row above.

Inexperienced automated testers might say, “If app changes, I will just update the test script”. This sounds acceptable but probably is not practical when maintaining a large E2E suite (like this one, a suite of 570 Selenium tests, consisting of 30000+ test steps).

The real solution, of course, is to make the test step as stable as possible, amid future app changes.

Some might say, “I will tell the programmers to add IDs”.

This is logical but often a naive thought, and testers know the answer already. The developers do not care about automated testing (unless E2E automation is doing real and well, which is rare) and don’t want to do that. This kind of request is usually get ignored, and some team members might consider the tester “incompetent”.

Keep reading with a 7-day free trial

Subscribe to The Agile Way to keep reading this post and get 7 days of free access to the full post archives.

Already a paid subscriber? Sign in
© 2025 Zhimin Zhan
Privacy ∙ Terms ∙ Collection notice
Start writingGet the app
Substack is the home for great culture

Share