Documentation
HomepageLog InRegisterPricingWhy DogQ
  • Documentation
    • Get started
    • Scenario steps
    • Selectors
      • Selectors in DogQ
      • Beginner's Guide to XPath
      • CSS Selectors 101
    • Reserved words
    • Interacting with JS Popups
    • Editing tests
    • Organizing tests
    • Macros
    • Workflow tips
    • AI-powered tools
      • AI Step generator
      • AI Healer
      • AI Suggester
    • Scheduling
    • Team
      • Squads
    • Recordings (beta)
    • Integrations
      • CI/CD
      • Slack
    • DogQ User-Agent
  • Use Cases
    • Component testing
    • Transient elements
    • Select-option dropdowns
  • FAQ
Powered by GitBook
On this page
  • CSS Selectors in testing
  • Basic selectors
  • Compound selectors
  • Complex selectors
  • Substring search

Was this helpful?

  1. Documentation
  2. Selectors

CSS Selectors 101

Follow this guide for a brief overview of CSS selectors in testing, their syntax and use cases.

PreviousBeginner's Guide to XPathNextReserved words

Last updated 1 month ago

Was this helpful?

CSS barely needs an introduction. In web development it's used for selecting and styling HTML elements. In this guide we will only be discussing the usage of CSS selectors in the testing realm.

CSS Syntax Cheat Sheet

Basic selectors

  • element - selects all elements with the given tag name

  • .class - selects all elements by class name

  • #id - selects all elements with the given id

  • [attribute="value"] - selects all elements with the given attribute-value pair

Compound selectors

  • [attribute1="value"][attribute2="value"]

  • .class1.class2.class3

  • .class#id

  • element#id[attribute=value]

Combinators

  • A B - selects descendant B of parent A at any level, i.e. child, grandchild, etc.

  • A > B - selects descendant B of parent A at child level, i.e. not further

  • A + B - selects element B that immediately follows its sibling A

  • A ~ B - selects element B that follows its sibling A (not necessarily immediately)

Operators

  • [attribute=value] - exact matching

  • [attribute*=value] - partial matching (substring)

  • [attribute^=value] - matching substring at the start of the value

  • [attribute$=value] - matching substring at the end of the value

CSS Selectors in testing

Every element that you interact with in an automated test (whether it’s clicking, typing, asserting, etc.) needs to be uniquely identified so that it can be located during the test run. CSS selectors allow automated testing frameworks to do just that. In addition to targeting an element, they can also be used as assertions to verify an element's state or behavior.


Basic selectors

As versatile and robust as they are, CSS selectors are at the same time really easy to learn and read. The four most common selector types in practice are type, .class, #id, and [attribute] selectors.

Selector
Result

input

selects all <input> elements

.typography5

selects all elements that have typography5 class

#submit-btn

selects all elements that have id with the value of 'submit-btn'

[type="password"]

selects all elements that have type attribute with the value of 'password'

Type selector can be replaced with a universal * one that matches every element type on the page. It's a wildcard that is too broad and greedy on its own but can be useful when combined with other selectors in certain edge-cases. For example when you don't care about the element type or don't know anything about the element but its position.


Compound selectors

It's not uncommon that elements don't have any unique identifiers or attributes, which makes targeting them harder. This is when we need to explore compound and complex selectors. A compound selector combines multiple predicates of a single element, which makes for a more precise and refined selection.

Selector
Result

input[type="password"]

selects all <input> elements that have type attribute with the value of 'password'

button#confirm

selects all <button> elements that have id with the value of 'confirm'

.prim-color#submit

selects all elements that have prim-color class and id with the value of 'submit'

.secondary[data-testid="affiliateLink"]

selects all elements that have secondary class and data-testid attribute with the value of 'affiliateLink'

However, narrowing selectors can also lead to tests becoming more brittle towards DOM changes. So it is recommended to prioritize stable and predictable attributes like data-testid over dynamic, auto-generated or position-based ones.


Complex selectors

While compound selectors use multiple attributes for enhanced precision, complex selectors include combinators and are based on the relationships between elements or DOM hierarchy. Such selectors can also be called positional and are generally not recommended as they can be susceptible to breakage when DOM changes get introduced. However there are cases where we still need them. It may have to do with the lack of unique attributes of the targeted element or the layout itself may be the object of verification.

The four main types of combinators are:

  • descendant combinator A B - selects descendant B (children, grandchildren, etc.) of parent A

  • child combinator A > B - selects direct descendant B (children, NOT grandchildren and further) of parent A

  • next-sibling combinator A + B - selects element B that immediately follows its sibling A

  • sibling combinator A ~ B - selects element B that follows its sibling A (not necessarily immediately)

Some typical examples:

Selector
Result

li a

selects all <a> elements that are descendants of the <li> element

footer > #footer-controls

selects all direct descendants (children) of the <footer> element that have id with the value of 'footer-controls'

li + li[data-testid="ecommerceLink"]

selects all <li> elements that have data-testid attribute with the value of 'ecommerceLink' and which immediately follow another <li> element (sibling)

div ~ button#confirmBtn

selects all <button> elements that have id with the value of 'confirmBtn' and which follow <div> element (sibling)

To summarize, a simple selector targets an element by one of its properties #confirm

A compound selector uses multiple properties of an element for more precision button#confirm

A complex selector puts elements in the context of relationships #checkout-modal > button#confirm


Substring search

CSS also possesses a powerful toolkit of attribute selector operators for crafting selectors that can match a portion of an attribute. For the majority of cases in testing we will only need these four:

  • (equals) = - matches the attribute exactly

  • (contains) *= - matches a part of the attribute, regardless of its position

  • (starts with) ^= - matches a part of the attribute at the start of the value

  • (ends with) $= - matches a part of the attribute at the end of the value

Partial match selectors are incredibly useful for targeting elements when you don’t know the exact value but want to match based on patterns — something that can be very handy in numerous automated testing scenarios. For instance, imagine we need to select an <img> element that has just been inserted into DOM and [src] is its only predictable attribute, but it gets an auto-generated suffix attached at the end, e.g., <img src="shop-item-bcuk8j002.jpg">. Since the auto-generated portion can't be predicted, we can use the (starts with) ^= operator to target this element by the part that is constant.

Here are some more examples:

Selector
Result

[alt*="cart-image"]

selects all elements that have substring 'cart-image' in their alt attribute

[for*="socials-link"]

selects all elements that have substring 'socials-link' in their for attribute

button[id$="-mui-14"]

selects all <button> elements that have IDs ending with substring '-mui-14'

a[href^=https://docs"]

selects all <a> elements that have href attribute starting with substring 'https://docs'

Even though class can be used with this notation [class*="btn-primary"], simply listing dot-separated classes does the same thing and may be easier on the eyes.

This step asserts that an element with ID 'confirmBtnDisabled' exists on the page.
This selector will match the first descendant of the element with main-content class regardless of what this element may be.
Ideally, every element in your tests should have its own unique data-testid attribute.
This will match an element that is a child of an element with nav-item class and has href attribute with the value of '/pricing/'.
This will match all <img> elements that have src attributes starting with 'shop-item'
Both selectors do the same.