Common selectors issues

How to create good selectors for apps with tables and interactive lists?

Here's a typical problem to solve: you have an app with list of orders in a table. Each row has a checkbox in it. You want to create a test automation that clicks the checkbox in the second row.

The above example comes from an open-source demo app

The problem is that there is no way to write a unique selector directly to this checkbox. There are more checkboxes on the list and we don't want to rely on the order of elements. We don't want the second checkbox, we want a specific checkbox.

There is nothing unique in the HTML element itself. Wait, is that class attribute unique? It is, but it's not good for test automation selectors. It's a random string that changes with every app deployment.

‍XPath traversing comes to the rescue! We will guide you step by step how to create a reliable selector, that first identifies the right row in the table and then finds the checkbox inside. The result selector will "traverse" the parents and children in 3 steps.

  1. Find a specific text in the table

  1. Find the parent table row by searching ancestors of the element from step 1

  1. Find the checkbox inside the row

Here's how to do this with our no-code tool. You need to use "Then find..." button and connect these 3 steps into one sophisticated and powerful XPath selector:

//*[contains(text(), "KYDGHM") ]/ancestor::tr/descendant::input[​@type="checkbox"]

You can apply the same technique to multiple other test cases.

Capitalization of selectors values matters

Make sure your selector uses the same capitalisation of characters as in the page. Pay attention to uppercase and lowercase letters! Ideally copy-paste the text from HTML via Chrome developer tools.

My selector works on desktop but doesn't work on mobile. Why?

Your app may have 2 different button "duplicates", one dedicated for desktop and one for mobile. One is always hidden, depending on the window width.

In such situation, the best solution is to create 2 separate tests for mobile and desktop with 2 different selectors.

Or try refactoring the code so that there is only one button present at a time - not hiding, but removing the button from the document.

You can also try to write a clunky selector that matches the 2 buttons, but somehow remove the hidden button with the not operator, for example:

//button[contains(text(), "Example") and not(ancestor::div[contains(@style, 'display:none')]) and not(ancestor::div[contains(@style, 'display:none')])]

How to check if your selector works in Chrome?

In the above example we created a selector, now we should check if it works.

  1. Open this demo app and login with "demo / demo", then go to "Orders" tab

  2. Open Chrome developer tools

  3. Click Ctrl+F to open the "Find" box (Cmd+F on Mac)

  4. Paste the selector

  5. Click enter

  6. The matching element will be highlighted

  7. Click enter several times to make sure that this is the only element that has a match

Here's a quick video that shows the whole XPath selector verification process in Chrome:

Last updated

Was this helpful?