CSS and XPath Selectors for Autotests

Maria Golubeva
JAGAAD Digital Solutions
7 min readJun 6, 2023

What is a selector?

A selector is plain text that can be used to identify elements on a web page in order to interact with them in automated tests.

In the case of CSS, the selector includes a set of unique element attributes, and in the case of XPath, it is the DOM path to the element.

Each web-page is made up of the HTML elements

A good AQA Engineer should ideally be able to find readable and concise selectors on the page.

Where to start searching for the path to an element on the page?

1.Open in browser: View -> Developer -> Developer Tool or press F12 or press the right mouse button -> Inspect.

2. Open the Elements tab.

3. Press Command + F to open the “Find by string, selector, or XPath” search input.

4. Press the “Select an element in the page to inspect it”.

5. Press the element on the page and look for the highlighted element in the HTML.

6. Search for the identifier (unique properties).

7. Check your selector in the “Find by string, selector or XPath” search input.

Where to start searching for the path to an element on the page

Next, I will tell you what these unique properties can be and how to efficiently write selectors using the example of the https://www.wikipedia.org/ page, to slightly expand on the topic of my previous articles, where we already had to use selectors:

  1. The first E2E test with TestCafe.
  2. E2E tests project structure organizing.

CSS selectors

Many browsers implement a CSS engine so that developers can use CSS tables in their projects. That allows to share the content of the page with its design. CSS has patterns according to which the styles created by the developer are applied to the elements of the page (DOM). These patterns are called selectors. Many automation frameworks (in our case, TestCafe) use the same principle to find elements. And it’s much faster than searching for elements based on XPath, which we’ll cover in a moment.

CSS Selector

Let’s look at a few basic CSS usage examples:

Universal selector

  • Selector: *
  • Description: Selects all elements.

Type selector

  • Selector: element
  • Example: div
  • Description: Selects all <div> elements.

ID selector

  • Selector: #id
  • Example: #search-form
  • Description: Selects the element with id=”search-form”.
#search-form

Class selector

  • Selector: .class
  • Example: .other-projects
  • Description: Selects all elements with class=”other-projects”.
.other-projects

Attribute selectors

Attribute selector

  • Selector: [attribute=value]
  • Example: [type=”submit”]
  • Description: Selects all elements with type=”submit”.

Attribute selector

  • Selector: [attribute~=value]
  • Example: [data-el-section~=”languages”]
  • Description: Selects all elements with a data-el-section attribute containing the word “languages”.
[data-el-section~=”languages”]

Attribute selector

  • Selector: [attribute^=value]
  • Example: [href^=”https”]
  • Description: Selects all elements whose href attribute value begins with “https”.

Attribute selector

  • Selector: [attribute$=value]
  • Example: [href$=”.png”]
  • Description: Selects all elements whose href attribute value ends with “.png”.

Combinators

Descendant combinator

  • Selector: element element
  • Example: .footer div
  • Description: Selects all <div> elements inside an element with class=“footer”.
.footer div

Child combinator

  • Selector: element>element
  • Example: .footer > div
  • Description: Selects all <div> elements where the parent is an element with class=“footer”.

General sibling combinator

  • Selector: element~element
  • Example: [name=”viewport”] ~ link
  • Description: Selects siblings. This means that the second element follows the first (though not necessarily immediately), and both share the same parent.

Adjacent sibling combinator

  • Selector: element+element
  • Example: [name=”viewport”] + link
  • Description: Matches the second element only if it immediately follows the first element.

Pseudo-classes

The “:” allows the selection of elements based on state information that is not contained in the document tree.

  • Selector: element:enabled
  • Example: input:enabled
  • Description: Selects every enabled <input> element.
input:enabled
  • Selector: element:nth-child(n)
  • Example: #js-lang-list-button:nth-child(2)
  • Description: Selects every element that is the second child of parent with id=“js-lang-list-button”.

How to use CSS selectors in TestCafe

In the previous article, we used CSS selectors. Selector filters the DOM and returns page elements that match your criteria.

To assign a selector to an element from the Search Wikipedia page, do the following:

elementOnThePage = Selector([SELECTOR_VALUE]);

Example: searchButton = Selector(“[.oo-ui-actionFieldLayout-button]”);

XPath selectors

XPath is the language used when looking up XML (Extensible Markup Language) nodes. Since HTML can be thought of as an implementation of XML, we can also use XPath to locate HTML elements.

XPath Selector

Let’s look at the possibilities of describing selectors using XPath.

Universal selector

  • Selector: //*
  • Description: Selects all elements.

Type selector

  • Selector: //tagname
  • Example: //div
  • Description: Selects all <div> elements.
//div

ID selector

  • Selector: //tagname[@id=”value”]
  • Example: //*[@id=”search-form”]
  • Description: Selects the element with id=”search-form”.

Class selector

  • Selector: //tagname[@class=”value”]
  • Example: //*[@class=”other-projects”]
  • Description: Selects all elements with class=”other-projects”.

Attribute selector

  • Selector: //tagname[@attribute=”value”]
  • Example: //*[@type=”submit”]
  • Description: Selects all elements with type=”submit”.

Finding an immediate child element

  • Selector: //element//element
  • Example: //fieldset//input
  • Description: Selects all <input> elements inside an element <fieldset>.
//fieldset//input

Finding a child element of any level

  • Selector: //element/element
  • Example: //fieldset/input
  • Description: Selects all <input> elements where the parent is an element <fieldset>.

Search for an element by text

  • Selector: //tagname[text()=”value”]
  • Example: //*[text()=”Wikivoyage”]
  • Description: Selects all elements where the text is the “Wikivoyage”.
//*[text()=”Wikivoyage”]

Finding the parent element

  • Selector: //tagname/..
  • Example: //a[@id=”js-link-box-fr”]/..
  • Description: Selects every parent element of the element with id=”js-link-box-fr”.
//a[@id=”js-link-box-fr”]/..

Combining Multiple Properties

  • Example: //*[@class=”link-box”][@id=”js-link-box-en”]
  • Description: Selects the element with class=”link-box” and id=”js-link-box-en”.

Using starts-with()

  • Selector: //tagname[starts-with(@attribute, value”)]
  • Example: //*[@class=”link-box”][starts-with(@title, “English”)]
  • Description: Selects the element with class=”link-box” and the title property starts with “English”.
//*[@class=”link-box”][starts-with(@title, “English”)]

Using the contains

  • Selector: //tagname[contains(@attribute, value”)]
  • Example: //*[contains(@name, “search”)]
  • Description: Selects all the elements from which the name contains the string.
//*[contains(@name, “search”)]

Using the “AND” Statement

  • Selector: //tagname[@attribute1=value1” and @attribute2=value2”]
  • Example: //*[@class=”link-box” and @id=”js-link-box-en”]
  • Description: Selects elements with both attributes.

Using the “OR” Statement

  • Selector: //tagname[@attribute1=value1” or @attribute2=value2”]
  • Example: //*[@id=”js-link-box-ru” or @id=”js-link-box-en”]
  • Description: Selects elements with one of the attributes.

How to use XPath selectors in TestCafe

In the previous article, we used only CSS selectors. But we mentioned, that to use the Xpath selector we need a helper:

import { Selector } from 'testcafe';

const getElementsByXPath = Selector((xpath) => {
const iterator = document.evaluate(
xpath,
document,
null,
XPathResult.UNORDERED_NODE_ITERATOR_TYPE,
null
);
const items = [];

let item = iterator.iterateNext();

while (item) {
items.push(item);
item = iterator.iterateNext();
}

return items;
});

export default function (xpath) {
return Selector(getElementsByXPath(xpath));
}

To assign an XPath selector to an element from the Search Wikipedia page, do the following:

elementOnThePage = XPathSelector([SELECTOR_VALUE]);

Example: searchButton = XPathSelector(“//*[@class=”oo-ui-actionFieldLayout-button”]”);

Absolute/Relative path

An absolute path is a direct way to find an element, starting at the root node and describing each subsequent HTML element.

Example of the absolute CSS Selector: body div[class=”central-featured”] div a strong

The disadvantage of an absolute path is that if at least one element on the path to the required one changes, the selector stops working.

A relative path starts at any level of the HTML DOM structure, which means it can look for the element anywhere on the web page, making it more resilient and robust.

Example of the relative CSS Selector: div[class=”central-featured”] strong

The main practices for creating a quality selector

  1. Search selectors for elements in order:
  • Identifier.
  • Class name.
  • CSS selector with properties.
  • Xpath without text body.
  • Xpath with text.

2. Use parent web elements as anchors if they have original IDs.

3. Try to avoid Xpath containing text, because page content is the least stable part of the implementation.

4. Selectors should be readable, concise and meaningful.

Pros and cons of using CSS and XPath Selectors

To summarize XPath and CSS selectors — are great tools for parsing HTML though CSS selectors are briefer and easier to use while XPath is more powerful but more verbose and complex.

Pros and cons of using CSS and XPath Selectors

--

--

Maria Golubeva
JAGAAD Digital Solutions

Belarusian | QA Engineer in Italian company | Mentor in Tech | Web Automation | Travel lover