Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

When Cypress reports Timed out retrying after ... Expected to find element ... but never found it, the selector matched nothing in the application document before the applicable timeout expired. Check the rendered markup and document scope first, then verify that the app has finished booting and that any required network work has completed. Increase a timeout only when the element is legitimately slow to appear; it cannot repair a misspelled or out-of-scope selector.

What the “cannot find any elements” error means

A command such as cy.get('[data-cy=todo-item]') queries the application-under-test document for matching DOM nodes. Cypress automatically retries the query while it waits for matching elements or for a chained assertion to pass. If no match exists when the command’s timeout expires, the test fails with an error similar to:

Timed out retrying after 4000ms: Expected to find element: '[data-cy=todo-item]', but never found it.

The number in the message is not necessarily four seconds. It reflects the configured defaultCommandTimeout or a command-level override. Treat the failure as a diagnosis of one of five separate conditions: the selector is wrong, the application is not ready, the query is aimed at the wrong document, the timeout is too short for a real delay, or the test found a node but failed a later actionability check.

Use this triage order

  1. Inspect the live DOM. Open the Cypress runner’s browser tools at the moment of failure and find the element manually. Compare its tag, attributes, text, and nesting with the selector in the test.
  2. Confirm the command’s scope. A normal cy.get() searches the application document. It does not automatically enter an iframe document.
  3. Check application readiness. Look for framework boot errors, an unanswered request, a loading state, or an animation that has not finished.
  4. Check retry placement. Put expectations that must become true inside a Cypress chain, not inside a one-time callback.
  5. Adjust timing only after the preceding checks. Use a per-command timeout for a known, legitimate delay.
  6. Classify the failure. “No element found” and “element found but not actionable” require different fixes.

Verify that the selector matches the rendered markup

cy.get(selector) uses a selector to filter elements in the current application document. A selector that was correct for a static mockup can fail after a component changes its attribute, adds a prefix, or renders a different branch for the test’s data.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Compare the selector with the actual node

  • Check spelling, punctuation, and case-sensitive attribute values.
  • Confirm that the test is on the expected route and that a previous command did not navigate away.
  • Check whether the element is rendered only after a condition such as an authenticated user, selected option, feature flag, or nonempty API response.
  • Prefer a stable test attribute that your application intentionally keeps for tests. If the markup uses data-cy="todo-item", the command must use the same attribute and value.
cy.get('[data-cy=todo-item]')
  .should('have.length', 3)

The length assertion belongs in the chain. Cypress will retry the query and assertion together until three matching nodes exist or the timeout expires.

Watch for a selector that is valid but too broad or too narrow

A selector can match a different element than the one you intended, or no element after a component was refactored. Use the smallest selector that expresses the user-visible contract, then assert the relevant text, role, value, or count. Do not “fix” a failure by adding arbitrary descendants until the command happens to pass; that makes the test dependent on implementation details.

Wait for the application’s real ready state

Cypress retries queries, but it cannot make an application render a component that is blocked by an error or by unfinished work. The DOM may not have loaded yet, a framework may still be bootstrapping, an XHR request may be unanswered, or an animation may still be in progress.

Make readiness observable

Choose a state that proves the page is ready instead of inserting a fixed sleep. For example, assert a loading indicator disappears or wait for the element that the application renders after its data arrives:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
cy.get('[data-cy=loading]').should('not.exist')
cy.get('[data-cy=todo-item]').should('have.length', 3)

If your test controls the request, alias the relevant network operation and wait for that operation before querying the resulting UI. The important distinction is that the wait must represent the application’s dependency; a delay that merely guesses at network speed will be slow and still flaky.

Rank #2
Sale
HTML and CSS: Design and Build Websites
  • HTML CSS Design and Build Web Sites
  • Comes with secure packaging
  • It can be a gift option

Keep assertions retryable

A Cypress assertion chained with should() is retried with the query. An assertion executed inside .then() runs once against the value available at that instant:

// Retryable: the query and assertion can run again
cy.get('[data-cy=todo-item]').should('have.length', 3)

// One-time callback: this does not provide the same retry behavior
cy.get('[data-cy=todo-item]').then(($items) => {
  expect($items).to.have.length(3)
})

Use .then() when you intentionally need a one-time transformation or inspection. Use a chained Cypress assertion when the UI is expected to change.

Check document boundaries, especially iframes

Ordinary cy.get() searches the application document in which the test is running. It does not automatically search inside an iframe. If the missing node is inside a same-origin iframe, first obtain the iframe’s document and query that document according to Cypress’s iframe guidance. A selector that is perfect in the top-level page will still return no elements when the target lives in a separate document.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Confirm the boundary before changing the selector

  • In browser tools, inspect whether the target appears under an <iframe> element.
  • Determine whether the iframe is same-origin; cross-origin documents have additional browser and Cypress restrictions.
  • Make the iframe document ready before querying its contents.
  • Keep the boundary handling in a reusable custom command if many tests use the same embedded application.

If the element is in the top-level document but appears only after a component mounts, return to the readiness checks instead of treating it as an iframe problem.

Use a timeout for a real delay, not a wrong query

You can override the timeout for an individual command:

cy.get('.my-slow-selector', { timeout: 10000 })
  .should('be.visible')

This is appropriate when the element is expected to appear after a known, legitimate delay, such as a slow but required initialization step. It does not help when the selector is misspelled, the application rendered a different route, or the target is inside an iframe. A longer timeout only postpones the same failure in those cases and can make the suite slower.

Prefer narrow overrides

Keep an exceptional timeout next to the command that needs it so other tests still fail promptly. Changing the global defaultCommandTimeout can conceal regressions across the entire suite and makes the duration in future error messages harder to interpret. If a component routinely needs a long wait, investigate its loading behavior and expose a deterministic ready state rather than continually increasing the number.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Separate missing elements from actionability failures

A missing-node timeout means the query returned no matching element. A different class of Cypress failure occurs when a node exists but cannot be interacted with. Cypress checks whether an element is in an actionable state, including conditions such as visibility, coverage by another element, and disabled state.

Express the actual requirement

If the test requires visibility before a click, make that requirement explicit and retryable:

cy.get('[data-cy=save]').should('be.visible').click()

If the command finds the node but reports that it is covered, disabled, or otherwise not actionable, fix the application state, overlay, or test flow. Do not apply a missing-element fix such as changing the selector when the selector is already returning the intended node.

Rank #4
Sale
Web Design with HTML, CSS, JavaScript and jQuery Set
  • Brand: Wiley
  • Set of 2 Volumes
  • A handy two-book set that uniquely combines related technologies Highly visual format and accessible language makes these books highly effective learning tools Perfect for beginning web designers and front-end developers

Inspect application errors and malformed markup

When the selector, timing, and scope look correct, inspect the browser console and Cypress runner for application or component errors. A JavaScript exception during bootstrapping can prevent the component from rendering at all. Malformed HTML can also affect how the browser constructs the document; Cypress’s error guidance notes that document.querySelector() may not find elements that appear after malformed markup.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

A practical inspection sequence

  1. Reload the test and watch the console before the failing command runs.
  2. Check the network panel for a request that remains pending or fails.
  3. Inspect the rendered DOM, not only the component source or fixture.
  4. Check the runner’s command log for an earlier navigation, uncaught exception, or failed setup command.
  5. Reduce the test to the smallest route and selector that reproduces the problem.

If the page is blank or partially rendered, repair the application error first. Cypress cannot locate a node that the browser never created.

Common symptoms and the right fix

Symptom Likely cause First fix
The selector never appears, even after a long wait Wrong attribute, route, fixture, or feature state Inspect the live DOM and compare it with the selector.
The element appears shortly after the failure Legitimate asynchronous rendering Wait on the application’s ready condition or use a narrow command timeout.
The page shows a spinner forever Unanswered or failed request, or an app boot error Inspect console and network failures; fix the blocked dependency.
The target is visible in an embedded page The node is inside an iframe document Handle the same-origin iframe document before querying inside it.
The command finds a node but click or type fails Visibility, coverage, disabled state, or another actionability condition Assert the required state and correct the overlay or application state.
Elements after a particular tag are missing Malformed HTML changed the parsed document Validate and repair the markup, then rerun the selector.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Build tests that remain reliable

Use stable contracts

Keep test attributes deliberate and consistent. A selector tied to a product contract is less likely to break than one tied to a layout class. When a component legitimately changes its markup, update the test and the contract together rather than adding fallback selectors that hide the change.

Wait on causes, not elapsed time

Network completion, disappearance of a loading state, and a retryable assertion provide evidence that the UI can be tested. Fixed delays add latency and still fail on a slower environment.

Keep failures diagnosable

Log the route, relevant fixture state, and the selector being exercised. Capture the rendered markup at failure when your CI system supports it. A screenshot can show what a user saw, but it cannot replace a DOM assertion: visual output may look correct while the wrong element, document, or accessibility state is being tested.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Or skip the browser setup

If your immediate goal is a clean visual capture of a page while you investigate a rendering problem, ScreenshotNeo provides a website screenshot API. It accepts consent banners before capture and removes more than 60 known consent platforms, newsletter popups, and chat widgets; each step can be disabled. Bot checks, CAPTCHAs, blank pages, timeouts, failed loads, and cache hits are not billed, and each response reports the page verdict and billing status in X-Page-Verdict and X-Billed headers.

One GET request returns PNG, JPEG, WebP, or PDF. The API also supports full-page captures with lazy images loaded, CSS-selector element capture, dark mode, device presets and custom viewports, retina scale, custom CSS and JavaScript, clicks before capture, hidden selectors, waits for selectors, delays or network idle, request and resource blocking, custom headers, cookies, user agents and authorization, timezone and geolocation, transparent backgrounds, resizing, TTL-based caching, signed image links, asynchronous jobs with signed webhooks, bulk capture of up to 100 URLs per call, usage reporting, and an OpenAPI specification. Parameter names used by other screenshot APIs also work, which can simplify migration.

cURL

See the ScreenshotNeo documentation for the complete option list.

curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp

Python

import requests

r = requests.get(
    "https://api.screenshotneo.com/v1/shot",
    params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"},
    timeout=90,
)
r.raise_for_status()
open("shot.webp", "wb").write(r.content)

Node.js

const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
if (!res.ok) throw new Error(`Screenshot failed: ${res.status}`);
const buffer = Buffer.from(await res.arrayBuffer());
await import('node:fs/promises').then(fs => fs.writeFile('shot.webp', buffer));

ScreenshotNeo also exposes an MCP server with take_screenshot, get_page_info, and capture_pdf tools for Claude, Cursor, and other MCP clients. The Free plan includes 1,000 shots per month without a card; paid plans start at $5 for 3,000 shots. Use it as a visual diagnostic or reporting tool alongside Cypress, not as a substitute for Cypress’s DOM and interaction assertions.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Create a free ScreenshotNeo account to get 1,000 screenshots a month with no card.

When to escalate a reproducible failure

If the documented checks do not explain the failure, reduce it to a reproducible example. Include the failing Cypress command, the exact selector, rendered markup around the expected node, test type, route and fixture state, Cypress configuration relevant to timeouts, console and network errors, and the complete error text. Cypress’s troubleshooting guidance recommends using its support resources and opening an issue with a reproducible example when documentation and local diagnosis do not resolve the problem. Avoid sending only a screenshot of the error; the DOM and timing context are what distinguish selector, readiness, scope, and actionability failures.

Frequently Asked Questions

Can a longer timeout make Cypress miss fewer elements?

Only when the element is expected to appear after a genuine, finite delay. It does not correct a selector that matches nothing, a wrong document, or an application error, and broad global increases can slow unrelated failures.

Can a ScreenshotNeo image prove that a Cypress selector is correct?

No. ScreenshotNeo captures the rendered visual page or PDF. It can document what appeared, while Cypress remains responsible for querying the DOM and verifying interaction and state.

What’s actually slowing this PC down?

Pick the symptom - the matching free tool is one click away.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.