Skip to main content
aaronwilliams.me logo

Cypress Filtering Query Commands

This post runs through some of the ways you can filter what has been yielded from a Cypress query command.

.filter() by Class Name

A good example of using .filter() is checking whether a navigation link is correctly showing active styling.

To do this we can query for all list items within a nav element then filter by CSS class:

cy.get("nav li")
  .filter(".active")
  .should("have.text", "Home");

In this example the .get() command yields multiple list items and filter(".active") removes all others.

This test will fail if multiple items remain after the filter as Cypress will assert the concatenated text of all matched items.

If you do have to filter to a multiple result set you can pick a singular item you need to work with using one of the examples below:

.filter()
  .first()
 
.filter()
  .last()
 
filter()
  .eq(1)
 
.filter()
  .contains("Home")

Or you can use a function for more control:

cy.get("nav li")
  .filter(".active")
  .filter((_, el) => el.innerText.includes("Home"))
  .should("be.visible");

.filter() vs .find()

Notice the difference?

ℹ️ .filter() works on the current set of elements, narrowing them down.

ℹ️ .find() starts a new query inside each element of the current subject.

Use .filter() to work at the current level. Use .find() to search within children.

.filter() by CSS Pseudo-classes

Instead of class names you can use CSS pseudo-classes.

For example if you have 2 nav elements, one for desktop, one for mobile and the mobile one is hidden on desktop you can target only the visible one.

cy.get("nav")
  .filter(":visible")
  .find("li a")
  .first()
  .should("have.text", "HOME");

Other useful pseudo-classes:

:checked — for checkboxes or radios

:disabled — for buttons

:nth-child(n) & :nth-of-type(n)

.filter() by jQuery :contains("text")

If you want to filter multiple results by text content, use jQuery’s :contains()

<ul>
  <li>RTX 5090 32 GB</li>
  <li>RTX 5090 32 GB</li>
  <li>GeForce 210 512MB</li>
</ul>

✅ This yields both RTX 5090 items:

cy.get("li")
  .filter(':contains("RTX 5090")')
  .should("have.length", 2);

❌ This yields the first match because .contains() always returns 1 element:

cy.get("li")
  .contains("RTX 5090")
  .should("have.length", 2);

not()

Works the same as .filter() but the in reverse. It removes elements that match the selector.

For example to filter out all buttons not disabled:

cy.get("button")
  .not(":disabled")
  .should("have.text", "Full Path Tracing");