Bird
Raised Fist0
Cypresstesting~15 mins

Automatic retry mechanism in Cypress - Deep Dive

Choose your learning style10 modes available
Overview - Automatic retry mechanism
What is it?
The automatic retry mechanism in Cypress is a feature that tries to run certain commands or checks again if they fail at first. It helps tests wait for things like page elements or data to appear before deciding if the test passed or failed. This means tests are more stable and less likely to fail because of small delays or timing issues. It works behind the scenes without extra code from the tester.
Why it matters
Without automatic retries, tests might fail just because a page took a moment longer to load or an element was slow to appear. This causes frustration and wastes time fixing tests that are actually fine. Automatic retries make tests more reliable and save developers and testers from chasing false errors. It helps teams trust their tests and catch real problems faster.
Where it fits
Before learning automatic retries, you should understand basic Cypress commands and assertions. After this, you can explore advanced waiting strategies and custom retry logic. This concept fits into making tests more robust and is a foundation for handling asynchronous web behavior in testing.
Mental Model
Core Idea
Automatic retry means Cypress keeps trying a command or check until it succeeds or a timeout happens, making tests wait smartly for the right conditions.
Think of it like...
It's like knocking on a door repeatedly until someone answers, instead of giving up after the first try.
┌───────────────────────────────┐
│ Start Test Command            │
├───────────────┬───────────────┤
│ Command Runs │ Assertion Runs │
├───────┬───────┴───────┬───────┤
│ Fail? │ Retry Until    │ Pass  │
│       │ Timeout       │       │
└───────┴───────────────┴───────┘
Build-Up - 6 Steps
1
FoundationWhat is Automatic Retry in Cypress
🤔
Concept: Introduce the basic idea that Cypress automatically retries commands and assertions.
Cypress automatically repeats certain commands and checks if they fail at first. For example, if you ask Cypress to find a button on the page, it will keep looking for a short time before saying it can't find it. This helps when the page is still loading or changing.
Result
Tests become less flaky because Cypress waits for elements or conditions instead of failing immediately.
Understanding that Cypress retries commands helps you trust that tests handle slow or changing pages gracefully.
2
FoundationWhich Commands Automatically Retry
🤔
Concept: Learn which Cypress commands and assertions use automatic retry.
Commands like cy.get(), cy.contains(), and assertions like .should() automatically retry until they pass or timeout. Commands that change state, like cy.click(), do not retry automatically.
Result
You know when Cypress will retry and when it won't, helping you write better tests.
Knowing which commands retry prevents confusion about why some tests wait and others fail fast.
3
IntermediateHow Cypress Decides to Retry
🤔Before reading on: Do you think Cypress retries commands only on failure, or also on success? Commit to your answer.
Concept: Understand the conditions that trigger retries in Cypress commands and assertions.
Cypress retries commands only when the assertion or command fails. If the command passes, it moves on immediately. It retries until the command passes or the default timeout (usually 4 seconds) is reached.
Result
Tests wait just enough time for conditions to be true, improving speed and reliability.
Understanding retry triggers helps you avoid unnecessary waits and write efficient tests.
4
IntermediateTimeouts and Customizing Retry Behavior
🤔Before reading on: Can you guess if you can change how long Cypress retries commands? Commit to yes or no.
Concept: Learn how to adjust the retry timeout settings for commands and assertions.
Cypress lets you change the timeout for retries using options like { timeout: 10000 } to wait longer or shorter. You can set this globally or per command. This helps when some elements take longer to appear.
Result
You can fine-tune test waiting times to balance speed and reliability.
Knowing how to customize timeouts prevents tests from failing too soon or waiting too long unnecessarily.
5
AdvancedRetry Behavior with Custom Commands and Non-Retry Commands
🤔Before reading on: Do you think custom Cypress commands automatically retry like built-in ones? Commit to your answer.
Concept: Explore how retries work with custom commands and commands that do not retry automatically.
Custom commands do not retry automatically unless they include retryable commands inside. Commands like cy.click() do not retry, so you must handle timing issues differently, for example by waiting for elements first.
Result
You understand when you need to add explicit waits or retries in your custom code.
Knowing retry limits helps avoid flaky tests caused by commands that don't wait for conditions.
6
ExpertHow Automatic Retry Affects Test Design and Debugging
🤔Before reading on: Does automatic retry always make debugging easier, or can it sometimes hide problems? Commit to your answer.
Concept: Understand the impact of automatic retry on writing tests and diagnosing failures.
Automatic retry improves test stability but can hide timing issues or cause tests to pass when they shouldn't. It can also make tests slower if timeouts are too long. Knowing when retries happen helps you write clearer tests and debug failures faster by using logs and screenshots.
Result
You can balance retry benefits with clear, fast, and reliable tests.
Understanding retry tradeoffs helps you avoid false positives and maintain test quality in complex projects.
Under the Hood
Cypress runs commands inside a controlled event loop. When a command or assertion fails, Cypress schedules a retry after a short delay, repeating this until success or timeout. It tracks command state and uses promises to manage asynchronous retries seamlessly, without user code needing to handle timing.
Why designed this way?
This design was chosen to simplify asynchronous testing by hiding complex waiting logic from users. It avoids flaky tests caused by race conditions and slow page loads. Alternatives like manual waits were error-prone and verbose, so automatic retry improves developer experience and test reliability.
┌───────────────┐
│ Start Command │
└───────┬───────┘
        │
        ▼
┌───────────────┐
│ Run Command   │
│ & Assertion   │
└───────┬───────┘
        │
   Success? ──▶ Yes ──▶ Continue Test
        │
        No
        │
┌───────▼───────┐
│ Wait Short    │
│ Delay        │
└───────┬───────┘
        │
        ▼
┌───────────────┐
│ Retry Command │
└───────┬───────┘
        │
   Timeout? ──▶ No ──▶ Run Command
        │
        Yes
        │
┌───────▼───────┐
│ Fail Test     │
└───────────────┘
Myth Busters - 4 Common Misconceptions
Quick: Does Cypress retry commands that change page state like clicks? Commit to yes or no.
Common Belief:Cypress retries all commands automatically, including clicks and typing.
Tap to reveal reality
Reality:Only commands that query or assert elements retry automatically. Commands that cause actions like clicks do not retry.
Why it matters:Assuming clicks retry can cause tests to fail if elements are not ready, leading to flaky tests.
Quick: Do you think automatic retry makes tests always faster? Commit to yes or no.
Common Belief:Automatic retry always speeds up tests by waiting smartly.
Tap to reveal reality
Reality:Retries can add time if commands keep failing until timeout, making tests slower if timeouts are too long.
Why it matters:Ignoring this can cause slow test suites and wasted developer time.
Quick: Does automatic retry guarantee tests never fail due to timing? Commit to yes or no.
Common Belief:Automatic retry makes tests completely immune to timing issues.
Tap to reveal reality
Reality:Retries reduce timing problems but cannot fix all asynchronous issues, especially if timeouts are too short or commands don't retry.
Why it matters:Overreliance on retries can hide real bugs or cause false confidence in test stability.
Quick: Can custom Cypress commands retry automatically without special code? Commit to yes or no.
Common Belief:All custom commands automatically retry like built-in ones.
Tap to reveal reality
Reality:Custom commands only retry if they include retryable commands inside; otherwise, they do not retry automatically.
Why it matters:Misunderstanding this leads to flaky custom commands and unreliable tests.
Expert Zone
1
Automatic retry only applies to commands that query or assert elements, not to commands that perform actions or change state.
2
Retries use a smart polling mechanism with short delays, balancing speed and reliability without user intervention.
3
Timeouts can be customized globally or per command, but setting them too high or too low can cause slow tests or flaky failures.
When NOT to use
Automatic retry is not suitable for commands that change application state or for tests requiring precise timing control. In such cases, explicit waits, event listeners, or custom retry logic should be used instead.
Production Patterns
In real projects, testers combine automatic retries with custom commands that include retryable queries, use timeout tuning for slow pages, and add explicit waits only when necessary to handle complex asynchronous behavior.
Connections
Polling in Networking
Both use repeated checks until a condition is met or timeout occurs.
Understanding retry in Cypress is like understanding polling in networks, where repeated requests wait for a response, helping grasp asynchronous waiting.
Circuit Breaker Pattern in Software Design
Both manage retries and failures to improve system stability.
Knowing how retries work in Cypress helps understand how circuit breakers retry operations carefully to avoid overload and failure.
Human Patience in Waiting for Responses
Retrying commands is like a person patiently waiting and checking repeatedly for a response before giving up.
This connection shows how retry mechanisms mimic natural human patience in uncertain situations.
Common Pitfalls
#1Assuming cy.click() retries automatically and writing tests without waiting for elements.
Wrong approach:cy.get('#submit').click();
Correct approach:cy.get('#submit').should('be.visible').click();
Root cause:Misunderstanding that action commands like click do not retry, so clicking an invisible element causes failure.
#2Setting very long global timeouts causing slow test runs.
Wrong approach:Cypress.config('defaultCommandTimeout', 30000);
Correct approach:cy.get('#slow-element', { timeout: 10000 }).should('be.visible');
Root cause:Applying long timeouts globally instead of per command leads to unnecessary delays in fast tests.
#3Writing custom commands without including retryable commands inside, expecting automatic retry.
Wrong approach:Cypress.Commands.add('customCheck', () => { cy.get('#item').then(...); });
Correct approach:Cypress.Commands.add('customCheck', () => { return cy.get('#item').should('exist'); });
Root cause:Not returning or including retryable assertions inside custom commands prevents automatic retry.
Key Takeaways
Cypress automatically retries commands that query or assert elements until they pass or timeout, improving test stability.
Not all commands retry automatically; action commands like clicks do not, so tests must handle timing explicitly for them.
Timeouts for retries can be customized globally or per command to balance speed and reliability.
Understanding retry behavior helps write efficient, reliable tests and avoid common flaky test pitfalls.
Automatic retry simplifies asynchronous testing but requires careful use to avoid hiding real issues or slowing tests.

Practice

(1/5)
1. What does Cypress's automatic retry mechanism do during test execution?
easy
A. It requires manual loops to retry commands.
B. It skips failed tests automatically without retrying.
C. It keeps trying commands and assertions until they pass or timeout.
D. It only retries tests when explicitly told by the user.

Solution

  1. Step 1: Understand Cypress retry behavior

    Cypress automatically retries commands and assertions until they pass or the timeout is reached.
  2. Step 2: Compare options with this behavior

    Only the option stating "It keeps trying commands and assertions until they pass or timeout." correctly describes this automatic retry mechanism without manual intervention.
  3. Final Answer:

    It keeps trying commands and assertions until they pass or timeout. -> Option C
  4. Quick Check:

    Automatic retry = keeps trying until pass [OK]
Hint: Remember: Cypress retries commands/assertions automatically [OK]
Common Mistakes:
  • Thinking retries happen only on user command
  • Believing Cypress skips failed tests without retry
  • Assuming manual loops are needed for retries
2. Which of the following is the correct syntax to assert that an element with id submit-btn is visible, leveraging Cypress's automatic retry?
easy
A. cy.get('#submit-btn').assertVisible()
B. cy.get('#submit-btn').should('be.visible')
C. cy.find('#submit-btn').should('visible')
D. cy.getElement('#submit-btn').isVisible()

Solution

  1. Step 1: Identify correct Cypress command and assertion

    The correct command to select an element is cy.get() and the assertion to check visibility is should('be.visible').
  2. Step 2: Validate syntax correctness

    cy.get('#submit-btn').should('be.visible') uses the correct syntax and leverages automatic retry on the assertion. Other options use invalid commands or incorrect assertion syntax.
  3. Final Answer:

    cy.get('#submit-btn').should('be.visible') -> Option B
  4. Quick Check:

    Correct syntax = cy.get + should('be.visible') [OK]
Hint: Use cy.get() with should() for retries on assertions [OK]
Common Mistakes:
  • Using non-existent commands like assertVisible()
  • Incorrect assertion strings like 'visible' instead of 'be.visible'
  • Using cy.find() instead of cy.get()
3. Consider the following Cypress test code:
cy.get('.loading').should('not.exist')
cy.get('#data').should('contain', 'Success')

What will happen if the element with class loading disappears after 3 seconds but the default timeout is 4 seconds?
medium
A. The test will fail immediately because the element exists at first.
B. The test will pass only if manual wait is added before assertions.
C. The test will timeout and fail because Cypress does not retry on should('not.exist').
D. The test will pass because Cypress retries until the element disappears within timeout.

Solution

  1. Step 1: Understand retry on should('not.exist')

    Cypress automatically retries assertions like should('not.exist') until the element disappears or timeout.
  2. Step 2: Analyze timing and retry behavior

    The element disappears after 3 seconds, which is before the 4-second timeout, so the assertion will eventually pass.
  3. Final Answer:

    The test will pass because Cypress retries until the element disappears within timeout. -> Option D
  4. Quick Check:

    Retry waits for condition until timeout [OK]
Hint: Remember: should('not.exist') retries until element gone [OK]
Common Mistakes:
  • Assuming immediate failure if element exists initially
  • Believing manual waits are always needed
  • Thinking Cypress does not retry negative assertions
4. You wrote this Cypress test:
cy.get('#submit').click()
cy.get('#result').should('contain', 'Done')

But the test fails because #result text updates slowly. Which fix uses Cypress's automatic retry correctly?
medium
A. Use cy.get('#result', { timeout: 7000 }).should('contain', 'Done') to increase timeout.
B. Change to cy.get('#result').should('contain', 'Done') as is (no change).
C. Replace should with then for immediate check.
D. Add cy.wait(5000) before the assertion.

Solution

  1. Step 1: Identify problem with slow update

    The element #result updates slowly, so default timeout may be too short.
  2. Step 2: Use automatic retry with increased timeout

    Use cy.get('#result', { timeout: 7000 }).should('contain', 'Done') to increase the timeout, letting Cypress retry the assertion longer until it passes.
  3. Final Answer:

    Use cy.get('#result', { timeout: 7000 }).should('contain', 'Done') -> Option A
  4. Quick Check:

    Increase timeout to let retry succeed [OK]
Hint: Increase timeout to extend retry duration [OK]
Common Mistakes:
  • Using fixed waits instead of timeout options
  • Not changing anything and expecting success
  • Replacing should with then, which disables retry
5. You want to test a button that becomes enabled only after an API call completes. The button has id submit-btn. Which Cypress code best uses automatic retry to wait for the button to be enabled before clicking it?
hard
A. cy.get('#submit-btn').should('be.enabled').click()
B. cy.get('#submit-btn').click()
C. cy.wait(3000); cy.get('#submit-btn').click()
D. cy.get('#submit-btn').then($btn => { if ($btn.is(':enabled')) { $btn.click() } })

Solution

  1. Step 1: Understand button enabling timing

    The button becomes enabled after an API call, so it may be disabled initially.
  2. Step 2: Use automatic retry on enabled state

    cy.get('#submit-btn').should('be.enabled').click() uses should('be.enabled') which retries until the button is enabled, then clicks it.
  3. Final Answer:

    cy.get('#submit-btn').should('be.enabled').click() -> Option A
  4. Quick Check:

    Use should('be.enabled') to wait before click [OK]
Hint: Chain should('be.enabled') before click to wait [OK]
Common Mistakes:
  • Clicking immediately without waiting
  • Using fixed wait instead of retry
  • Using then() which disables retry and may fail
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard