Skip to main content
Cypress App

find

Get the descendant DOM elements that match a selector.

.find() searches every level below the subject, as opposed to .children(), which only looks one level down.

Syntax​

.find(selector)
.find(selector, options)

Usage​

Correct Usage

cy.get('.article').find('footer') // Yield 'footer' within '.article'

Incorrect Usage

cy.find('.progress') // Errors, cannot be chained off 'cy'
cy.clock().find('li') // Errors, 'clock' does not yield DOM elements

Arguments​

selector (String selector)

A selector used to match descendant DOM elements.

options (Object)

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

OptionDefaultDescription
logtrueDisplays the command in the Command log
timeoutdefaultCommandTimeoutTime to wait for .find() to resolve before timing out
includeShadowDomincludeShadowDom config option valueWhether to also search inside the shadow roots of the subject and its descendants, including nested shadow roots.

Yields ​

  • .find() yields the new DOM element(s) it found.
  • .find() is a query, and it is safe to chain further commands.

Examples​

Selector​

Find the li elements inside a parent with .find()​

index.html
<ul id="parent">
<li class="first"></li>
<li class="second"></li>
</ul>
spec.cy.js
// yields [<li class="first"></li>, <li class="second"></li>]
cy.get('#parent').find('li')

Find direct children with a leading > in .find()​

Start the selector with > to match only direct children of the subject. The result is the same as .children('li').

index.html
<ul class="nav">
<li>Home</li>
<li>
Docs
<ul>
<li>API</li>
</ul>
</li>
</ul>
spec.cy.js
// yields [<li>Home</li>, <li>Docs<ul>…</ul></li>]
cy.get('.nav').find('> li')

// yields all 3 li elements, including the nested one
cy.get('.nav').find('li')

Assertions​

Assert on the number of elements .find() yields​

When .find() is chained off another query such as cy.get(), Cypress reruns the whole chain until the assertion passes, so the count stays current as the page updates.

cy.get('[data-cy=cart]').find('[data-cy=cart-item]').should('have.length', 3)

Assert that .find() no longer finds an element​

Chain .should('not.exist') to wait for an element, such as a loading spinner, to leave the subject.

cy.get('[data-cy=results]').find('.spinner').should('not.exist')

Options​

Wait longer for slow content with timeout​

Pass timeout to give .find() more time than defaultCommandTimeout to locate its elements.

cy.get('[data-cy=report]').find('table', { timeout: 10000 })

Find elements inside a shadow root with includeShadowDom​

By default, .find() does not search inside shadow roots. Pass includeShadowDom: true to search them, or set the includeShadowDom configuration option to search them in every query.

index.html
<checkout-panel>
#shadow-root
<button>Checkout</button>
</checkout-panel>
spec.cy.js
// yields [<button>Checkout</button>]
cy.get('checkout-panel').find('button', { includeShadowDom: true })

Notes​

.find() only searches below the subject​

.find() matches descendants of the subject, never the subject itself. An element that matches the selector is left out of the result when it is the subject. To search from the root of the page instead, use cy.get(), and see how cy.get() and .find() differ.

index.html
<div class="card">
<div class="card">Nested</div>
</div>
spec.cy.js
// yields [<div class="card">Nested</div>], not the outer .card
cy.get('.card').first().find('.card')

Subjects with multiple elements​

When the subject holds more than one element, .find() searches inside each one and yields a single set, in document order, with any duplicates removed.

index.html
<ul>
<li><a href="/home">Home</a></li>
<li><a href="/docs">Docs</a></li>
</ul>
spec.cy.js
// yields [<a href="/home">Home</a>, <a href="/docs">Docs</a>]
cy.get('li').find('a')

.find() compared to .within()​

Chain .find() when you run one query inside an element. .within() scopes every command in its callback to the subject, which reads better when you run several commands against the same region.

// Option 1: one query
cy.get('[data-cy=login-form]').find('[data-cy=submit]').click()

// Option 2: several commands in the same region
cy.get('[data-cy=login-form]').within(() => {
cy.get('[data-cy=email]').type('[email protected]')
cy.get('[data-cy=password]').type('secret')
cy.get('[data-cy=submit]').click()
})

Reading a .find() timeout error​

When .find() times out without finding its elements, the error names the selector and lists the queries that produced its subject. The chain shows whether the problem is the .find() selector or an earlier query that yielded a different element than you expected.

cy.get('[data-cy=cart]').find('.total')
Timed out retrying after 4000ms: Expected to find element: `.total`, but never found it. Queried from:

> cy.get([data-cy=cart])

Shadow DOM boundaries and .find()​

Without includeShadowDom, .find() stops at a shadow boundary: it searches the markup written inside a shadow host, not the host's shadow root. Chained off an element that is already inside a shadow root, it searches that shadow tree normally, with or without the option. To search one shadow root only, traverse into it with .shadow() first:

cy.get('checkout-panel').shadow().find('button')

Rules​

Requirements ​

  • .find() requires being chained off a command that yields DOM element(s) or a document.

Assertions ​

  • .find() will automatically retry until the element(s) exist in the DOM.
  • .find() will automatically retry until all chained assertions have passed.

Timeouts ​

  • .find() can time out waiting for the element(s) to exist in the DOM.
  • .find() can time out waiting for assertions you've added to pass.

Command Log​

Find the li elements within the nav

cy.get('.left-nav>.nav').find('>li')

The commands above display in the Command Log as:

Command Log where the find entry for the >li selector reports a count of 8

Clicking the find command in the Command Log outputs the selector, the element(s) it was applied to, the yielded elements, and the number of elements found to the console:

Console output for find, listing the 8 li elements found under ul.nav

History​

VersionChanges
12.6.0Overwrite .find() with Cypress.Commands.overwriteQuery() rather than Cypress.Commands.overwrite().
12.0.0.find() is now a query.
5.2.0Added includeShadowDom option.

See also​