Using CSS selectors effectively
  • 13 Sep 2023
  • 6 Minutes to read
  • Contributors
  • Dark
    Light

Using CSS selectors effectively

  • Dark
    Light

Article Summary

When testing web applications, you will often use CSS selectors to select elements.
Most of the time, you will not be aware of the CSS selector when using Autify Recorder to record [Scenarios]. However, when using the [Locator] or [JS Step] , there are times when you will need to write a CSS selector.

As explained in the [Locator] article, you can easily obtain a CSS selector for a given element by using Developer Tools on Google Chrome. However, the CSS selector obtained from Developer Tools may not work correctly in the [Locator] or [JS Step] (the details are explained below).

In this article, you will learn about how to select a CSS selector.

1. Basic CSS Selectors

This section outlines some of the most commonly used CSS selectors for selecting basic elements.

1.1 Basic selectors

Selection methodExample
Select by tagdiv, a
Select by class.main, .sub
Select by id#a123, #b456
Select with a combination of tag, class, and iddiv#a123.main, a.sub

1.2 Frequently used selectors

Selection methodExample
Descendant element.main .sub, div a
Immediate child element.main > .sub, div > a
First child elementdiv:first-child
Last child elementdiv:last-child
Nth child elementli:nth-child(n)

1.3 Good to know selectors

Selection methodExample
Select by an attributea[href="https://example.com/index.html"], p[class="main"]
Elements with a partially matching attributea[href*="example.com"], p[class*="ai"]
Elements with an attribute that matches at the beginninga[href^="https://"], p[class^="ma"]
Elements with an attribute that matches at the enda[href$="index.html"], p[class$="in"]
Disabled stateinput:disabled, textarea:disabled

1.4 Selectors related to forms

Selection methodExample
Text entry fieldinput[type="text"]
text areatextarea
Drop-down (select box)select
Nth option in a drop-down listoption:nth-child(n)
Checkboxinput[type="checkbox"]
Radio buttoninput[type="radio"]
Checkboxes or radio button is checkedinput[type="checkbox"]:checked, input[type="radio"]:checked
Submit buttoninput[type="submit"]
Disabled stateinput[type="text"]:disabled

2. How to use the CSS selector effectively

With CSS selectors, there can be more than one way to select an element. In automated testing, it’s important to select a method that:

  • reflects your intentions,
  • can identify the target without ambiguity,
  • is concise and does not break easily (is resistant to changes in page structure)

even when there is more than one way to select.

Below, we look at how to write a CSS selector that selects <li>Hello! C2</li> in a page with the following HTML structure:

<html>
  <body>
    ...
    <div class="aaaaa ccccc">
      ...
      <div id="#bbbbb">
        ...
        <section class="ccccc">
          ...
          <ul>
            <li>Hello! A1</li>
            <li>Hello! A2</li>
            <li>Hello! A3</li>
          </ul>
          <ul>
            <li>Hello! B1</li>
            <li>Hello! B2</li>
            <li>Hello! B3</li>
          </ul>
          <ul>
            <li>Hello! C1</li>
            <li>Hello! C2</li>
            <li>Hello! C3</li>
          </ul>
          ...
        </section>
        ...
      </div>
      ...
    </div>
    ...
  </body>
</html>

The HTML hierarchy is shown below.

2.1. Select all the immediate parent elements in order along the HTML hierarchy

If you were to select the immediate parent elements until the tag in order of the HTML hierarchy of the target element, it would look like this:

body > div.aaaaa.ccccc > div#bbbbb > section.ccccc > ul:last-child > li:nth-child(2)

This is not versatile because the ancestor elements and class/id are selected too strictly. Following situations may occur when managing a website:

  • Change in class/id
    Example: the style of <div class="aaaaa ccccc"> changed to <div class="aaaaa bbbbb"> because of a design change.
  • Change in HTML structure
    Example: <li>Hello! C0</li> was added before <li>Hello! C2</li>, making it the third item instead of the second.

These situations have a high chance of breaking CSS selector and it can no longer select the target element.

2.2. Select by tag only

Consider a CSS selector that selects all the immediate parent elements in order along the HTML hierarchy. If you omit the class/id of the <div> tag and <section> tag and select only using elements, it would look like this:

body > div > div > section > ul:last-child > li:nth-child(2)

In this case, “div > div > section” becomes a condition for “<div> tag and <section> tag that match the HTML hierarchy.”

If the class/id of your website tends to change frequently, you may want to omit the class/id of the <div> tag and <section> tag and select by elements only.

2.3. Select by class/id only

Elements that have a class/id can also be written only with class/id.

Consider a CSS selector which selects all the immediate parent elements in order along the HTML hierarchy. If you select <div> tags and <section> tags that have a class/id by only using class/id, it would look like this:

body > .aaaaa.ccccc > #bbbbb >.ccccc > ul:last-child > li:nth-child(2)

In this case, “.aaaaa.ccccc > #bbbbb >.ccccc” is a condition for “all elements with the corresponding class/id set that match the HTML hierarchy”.

2.4. Select the immediate child element

div.aaaaa > section > ul:last-child > li:nth-child(2)

With above CSS selector, <div class="aaaaa"> does not have a <section> tag which could be a child element immediately under it. Therefore, there is no element that is selected by this CSS selector.

2.5. Select the descendant element

In “select the immediate child element”, <div class="aaaa"> did not have a <section> tag immediately under it, so there was no element to be selected. However, by changing “div.aaaaa > section” (select the immediate child element) to “div.aaaaa section” (select the descendant element), there is a <section> tag that is a descendant element of <div class="aaaaa">.

div.aaaaa section > ul:last-child > li:nth-child(2)

In the above CSS selector, the target element is the second <li> element immediately under the last <ul> out of the <ul> descendant elements of the <div> tag with class name "aaaaa". The selected target is <li>Hello! C2</li>.

 

2.6. Shorten the CSS selector

As mentioned above, the CSS selector shown in “Select all the immediate parent elements in order along the HTML hierarchy,” there is has a high risk of it not being able to select the target element, such as when the HTML structure changes due to page update or when class/id changes due to design change.

You can reduce this risk by keeping your CSS selectors short and simple.

Let’s take the CSS selector to select all the immediate parent elements in order along the HTML hierarchy. It can be broken down based on the selection condition.

body > div.aaaaa.ccccc > div#bbbbb > section.ccccc > ul:last-child > li:nth-child(2)
  1. body > div.aaaaa.ccccc > div#bbbbb > section.ccccc > ul > li
    • The target are elements that match the HTML hierarchy.
  2. ul:last-child
    • The target is the last <ul> tag out of the <ul> tags that match condition 1.
  3. li:nth-child(2)
    • The target is the second <li> tag out of the </li><li> tags that match condition 1.

HTML hierarchy 1 can be shortened as long as the target element can be selected.

For example, if the <section> tag exists only in this part of the page, <section> is a unique element in this page. Therefore, the CSS selector that selects the parent elements up to the <section> tag will work (shown below).

section > ul:last-child > li:nth-child(2)

In the case of the above selector, the target element is the second <li> element immediately under the last <ul> out of the children <ul> immediately under <section>. The selected target is <li>Hello! C2</li>.

Note that W3C advises that the value of the id attribute must be unique within a single document. If an element has an id, it is likely to be unique within a page.

2.7. If you shorten the CSS selector too much...

Please be aware that shortening the CSS selector too much may cause the target element to be ambiguous, or the target element cannot be selected.

2.7.1. There is more than one selected target (1)

section > ul > li:nth-child(2)

In the above selector, the target element is the second <li> elements immediately under the children <ul> immediately under <section>. The selected targets are <li>Hello! A2</li>, <li>Hello! B2</li>, <li>Hello! C2</li>.

2.7.2. There is more than one selected target (2)

section li

In the above selector, the target elements are <section>’s descendant elements <li>, so the selected targets are </li><li>Hello! A1</li>, <li>Hello! A2</li>, <li>Hello! A3</li>, <li>Hello! B1</li>, <li>Hello! B2</li>, <li>Hello! B3</li>, <li>Hello! C1</li>, <li>Hello! C2</li>, <li>Hello! C3</li>.

2.7.3. Target does not exist

section > li:nth-child(2)

In the above selector, the target element is the second immediate child element <li> of <section>, so there is no target element.

2.7.4. An unintended element is selected

section li:nth-child(2)

In the above selector, the target element is the second <li> of <section>’s descendant elements. Therefore, the target element is <li>Hello! A2</li>.


Was this article helpful?

Changing your password will log you out immediately. Use the new password to log back in.
First name must have atleast 2 characters. Numbers and special characters are not allowed.
Last name must have atleast 1 characters. Numbers and special characters are not allowed.
Enter a valid email
Enter a valid password
Your profile has been successfully updated.