Selecting Elements with cy.get()
cy.get() is the fundamental command Cypress uses to query the DOM. It accepts any valid CSS selector — tag names, classes, ids, attribute selectors, or combinators — and returns a Cypress chainable that wraps a jQuery object containing every matching element. Because it wraps jQuery under the hood, later commands like .find(), .filter(), and .eq() behave the way jQuery users already expect.
Cricket analogy: Just as a scorer calls out cy.get-style queries by scanning the scoreboard for a specific player's stats among all XI players, cy.get() scans the entire DOM using a CSS selector to return exactly the elements matching that pattern, like isolating Kohli's row from the full team sheet.
Choosing Selector Strategies
Not all selectors are equally durable. Class names and ids often exist for styling or JavaScript hooks and change whenever a developer refactors CSS or upgrades a UI library, silently breaking tests that depend on them. The Cypress team recommends adding a dedicated data-cy (or data-testid) attribute to elements you intend to test, since these attributes exist solely for testing and are far less likely to be touched during unrelated refactors.
Cricket analogy: Selecting a bowler for the death overs by his dedicated 'yorker specialist' tag rather than by his shirt number, which changes each season, is like preferring [data-cy=submit] over a CSS class, since dedicated test attributes like data-cy don't shift when a team's kit or a page's styling changes.
// Prefer a dedicated test attribute
cy.get('[data-cy=submit-button]').click();
// Fragile alternative — breaks if styling classes change
cy.get('.btn.btn-primary.mt-2').click();Narrowing Results with .find() and .contains()
cy.get() often returns more than one element, especially with broad selectors like '.item'. Chaining .find(selector) scopes the search to descendants of the current subject, letting you drill into a specific nested element without re-querying the whole page. cy.contains(text) instead filters by visible text content, which is useful when a stable class or attribute isn't available but the displayed text is predictable.
Cricket analogy: A captain first identifies the fielding team on the ground, then narrows down to just the slip cordon, the way cy.get('.team-row').find('.slip-fielder') first grabs a broad set of rows then narrows to a specific nested element within each.
Timeouts and Element Existence
If cy.get() doesn't find a matching element right away, it doesn't fail instantly. Cypress re-queries the DOM repeatedly for up to the defaultCommandTimeout (4000ms by default) before finally throwing a 'Timed out retrying' error. This built-in retry-ability is what makes Cypress resilient to elements that render asynchronously after an API call or animation completes.
Cricket analogy: A third umpire reviewing a run-out doesn't decide instantly; they wait and re-check the replay for up to a set review window before ruling, just as cy.get() doesn't fail instantly but retries checking the DOM for up to the default 4000ms timeout before declaring the element not found.
Cypress's defaultCommandTimeout (4000ms) governs how long cy.get() retries before failing. You can raise it globally in cypress.config.js or override it per command with cy.get(selector, { timeout: 10000 }).
Avoid selectors like .css-1a2b3c or div:nth-child(3) — auto-generated or positional selectors break the moment a stylesheet, component library, or markup order changes, turning a passing suite into a maintenance burden.
- cy.get() is Cypress's primary DOM query command.
- It accepts standard CSS selectors and returns matched elements.
- Prefer data-cy/data-testid attributes for resilient selectors.
- Use .find() to scope to descendants, .contains() to filter by text.
- cy.get() retries automatically until timeout (default 4000ms).
- Avoid brittle, structure-dependent or auto-generated class selectors.
Practice what you learned
1. What does cy.get() return?
2. Why prefer data-cy attributes over CSS class selectors?
3. What is the default timeout cy.get() waits before failing?
4. Which method scopes a search to descendant elements of a previously selected set?
5. What's a downside of selectors like .css-1a2b3c generated by CSS-in-JS?
Was this page helpful?
You May Also Like
Chaining and Retry-ability
Understand how Cypress commands chain together via the command queue and how built-in retry-ability makes assertions resilient to asynchronous UI changes.
Interacting with Elements (type, click, check)
Cover Cypress's core interaction commands — type(), click(), check(), select() — and the actionability checks Cypress performs before firing each one.
Assertions with should() and expect()
Learn the difference between Cypress's retrying should()/and() assertions and Chai's one-time expect() assertions, and when to use each.
Custom Commands
Learn how to extend Cypress with Cypress.Commands.add() to create reusable custom commands like cy.login(), reducing duplication across tests.