contains

Improve this doc

Get the DOM element containing the text. DOM elements can contain more than the desired text and still match. Additionally, Cypress prefers some DOM elements over the deepest element found.

Syntax

.contains(content)
.contains(selector, content)
.contains(selector, content, options)

// ---or---

cy.contains(content)
cy.contains(selector, content)
cy.contains(selector, content, options)

Usage

Correct Usage

cy.get('.nav').contains('About')  // Yield el in .nav containing 'About'
cy.contains('Hello')              // Yield first el in document containing 'Hello'

Incorrect Usage

cy.title().contains('My App')        // Errors, 'title' does not yield DOM element
cy.getCookies().contains('_key')     // Errors, 'getCookies' does not yield DOM element

Arguments

content (String, Number, RegExp)

Get the DOM element containing the content.

selector (String selector)

Specify a selector to filter DOM elements containing the text. Cypress will ignore its default preference order for the specified selector. Using a selector allows you to return more shallow elements (higher in the tree) that contain the specific text.

options (Object)

Pass in an options object to change the default behavior of .contains().

Option Default Description
log true Displays the command in the Command Log
timeout defaultCommandTimeout Time to wait for .contains() to resolve before timing out

Yields

  • .contains() yields the new DOM element it found.

Examples

Content

Find the first element containing some text

<ul>
  <li>apples</li>
  <li>oranges</li>
  <li>bananas</li>
</ul>
// yields <li>apples</li>
cy.contains('apples')

Find the input[type=’submit’] by value

Get the form element and search in its descendants for the content “submit the form!”

<div id="main">
  <form>
    <div>
      <label>name</label>
      <input name="name" />
    </div>
    <div>
      <label>age</label>
      <input name="age" />
    </div>
    <input type="submit" value="submit the form!" />
  </form>
</div>
// yields input[type='submit'] element then clicks it
cy.get('form').contains('submit the form!').click()

Number

Find the first element containing a number

Even though the <span> is the deepest element that contains a “4”, Cypress automatically yields <button> elements over spans.

<button class="btn btn-primary" type="button">
  Messages <span class="badge">4</span>
</button>
// yields <button>
cy.contains(4)

Regular Expression

Find the first element with text matching the regular expression

<ul>
  <li>apples</li>
  <li>oranges</li>
  <li>bananas</li>
</ul>
// yields <li>bananas</li>
cy.contains(/^b\w+/)

Selector

Specify a selector to return a specific element

Technically the <html>, <body>, <ul>, and first <li> in the example below all contain “apples”.

Normally Cypress would return the first <li> since that is the deepest element that contains: “apples”

To override the element that is yielded, we can pass ‘ul’ as the selector.

<html>
  <body>
    <ul>
      <li>apples</li>
      <li>oranges</li>
      <li>bananas</li>
    </ul>
  </body>
</html>
// yields <ul>...</ul>
cy.contains('ul', 'apples')

Notes

Scopes

.contains() acts differently whether it’s starting a series of commands or being chained off of an existing.

When starting a series of commands:

This queries the entire document for the content.

cy.contains('Log In')

When chained to an existing series of commands:

This will query inside of the <#checkout-container> element.

cy.get('#checkout-container').contains('Buy Now')

Be wary of chaining multiple contains

Let’s imagine a scenario where you click a button to delete a user and a dialog appears asking you to confirm this deletion.

// This doesn't work as intended
cy.contains('Delete User').click().contains('Yes, Delete!').click()

Because the second .contains() is chained off of a command that yielded the <button>, Cypress will look inside of the <button> for the new content.

In other words, Cypress will look inside of the <button> containing “Delete User” for the content: “Yes, Delete!”, which is not what we intended.

What you want to do is call cy again, which automatically creates a new chain scoped to the document.

cy.contains('Delete User').click()
cy.contains('Yes, Delete!').click()

Single Element

Only the first matched element will be returned

<ul id="header">
  <li>Welcome, Jane Lane</li>
</ul>
<div id="main">
  <span>These users have 10 connections with Jane Lane</span>
  <ul>
    <li>Jamal</li>
    <li>Patricia</li>
  </ul>
</div>

The below example will return the <li> in the #header since that is the first element that contains the text “Jane Lane”.

// yields #header li
cy.contains('Jane Lane')

If you wanted to select the <span> instead, you could narrow the elements yielded before the .contains().

// yields <span>
cy.get('#main').contains('Jane Lane')

Preferences

Element preference order

.contains() will always prefer elements higher in the tree when they are:

  • input[type='submit']
  • button
  • a
  • label

Favor of <button> over other deeper elements

Even though the <span> is the deepest element that contains “Search”, Cypress yields <button> elements over spans.

<form>
  <button>
    <i class="fa fa-search"></i>
    <span>Search</span>
  </button>
</form>
// yields <button>
cy.contains('Search').children('i').should('have.class', 'fa-search')

Favor of <a> over other deeper elements

Even though the <span> is the deepest element that contains “Sign Out”, Cypress yields anchor elements over spans.

<nav>
  <a href="/users">
    <span>Users</span>
  </a>
  <a href="/signout">
    <span>Sign Out</span>
  </a>
</nav>
// yields <a>
cy.get('nav').contains('Sign Out').should('have.attr', 'href', '/signout')

Favor of <label> over other deeper elements

Even though the <span> is the deepest element that contains “Age”, Cypress yields <label> elements over <span>.

<form>
  <label>
    <span>Name:</span>
    <input name="name" />
  </label>
  <label>
    <span>Age:</span>
    <input name="age" />
  </label>
</form>
// yields label
cy.contains('Age').find('input').type('29')

Rules

Requirements

  • .contains() can be chained off of cy or off a command that yields DOM element(s).

Assertions

  • .contains() will automatically retry itself until the element(s) exist in the DOM.

  • .contains() will automatically retry itself until assertions you've chained all pass.

Timeouts

  • .contains() can time out waiting for the element(s) to exist in the DOM.

  • .contains() can time out waiting for assertions you've added to pass.

Command Log

Element contains text “New User”

cy.get('h1').contains('New User')

The commands above will display in the command log as:

Command Log contains

When clicking on the contains command within the command log, the console outputs the following:

console.log contains

See also