Skip to content

fix: ensure that current retry is maintained properly when tests fail prior to top changing#32888

Merged
ryanthemanuel merged 8 commits intodevelopfrom
ryanm/fix/retries-before-top-change
Nov 7, 2025
Merged

fix: ensure that current retry is maintained properly when tests fail prior to top changing#32888
ryanthemanuel merged 8 commits intodevelopfrom
ryanm/fix/retries-before-top-change

Conversation

@ryanthemanuel
Copy link
Copy Markdown
Collaborator

@ryanthemanuel ryanthemanuel commented Nov 4, 2025

Additional details

When tests fail and then retry and top needs to change on a retry, we were previously not saving the state of the retry, so from the test runner's perspective you might end up seeing something like "Attempt 1 of 3", "Attempt 1 of 3", Success instead of "Attempt 1 of 3", "Attempt 2 of 3", Success. We fix this issue by saving the retry (in addition to the test id) when we save state right before a top change and then rehydrate that when we resume. This ensures that the retry number remains consistent.

In addition, when this happens, we end up wiping the entire test in terms of what is sent to test replay instead of only the retry that triggered the top change. We fix this by sending the retry on a resert to protocol and protocol only deletes the test/retry combination from the database.

Steps to test

How has the user experience changed?

PR Tasks


Note

Ensure the current test retry is saved/restored across top changes and propagated to protocol reset, with tests and types updated.

  • Runner/Driver:
    • Persist retry state by adding currentRetry to RunState in cypress.preserveRunState and resuming via Cypress.runner.resumeAtTest(id, currentRetry, emissions).
    • Update runner.resumeAtTest to accept currentRetry and set test._currentRetry when resuming.
  • Server/Protocol:
    • Extend protocol resetTest(testId, currentRetry?) and invoke it with currentRetry from cached run state in socket-base.ts.
    • Update ProtocolManager.resetTest signature and underlying types.
  • Types:
    • Add currentRetry?: number | null to RunState and to protocol interfaces.
  • Tests:
    • Add/adjust unit tests for protocol reset and socket cached state; add system test + snapshot to verify correct attempt numbering in reporter.
  • Docs/Changelog:
    • Add changelog bugfix entry describing retry numbering and Test Replay attempt handling.

Written by Cursor Bugbot for commit 664916c. This will update automatically on new commits. Configure here.

Copy link
Copy Markdown

@cursor cursor Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bug: Guard Against Null Runnable in currentRetry Access

The currentRetry getter accesses this.cy.state('runnable').ctx without checking if this.cy.state('runnable') is null/undefined first. This will throw a TypeError if runnable is nullish. The currentTest getter above (lines 930-948) properly handles this case with a null check. The getter should be:

get currentRetry (): number {
  const r = this.cy.state('runnable')
  
  if (!r) {
    return 0
  }
  
  const ctx = r.ctx
  return ctx?.currentTest?._currentRetry || ctx?.test?._currentRetry || 0
}

This is particularly relevant since preserveRunState now calls this.currentRetry (line 864) during cross-origin navigations, where the runnable state might not be guaranteed to be set.

packages/driver/src/cypress.ts#L949-L954

get currentRetry (): number {
const ctx = this.cy.state('runnable').ctx
return ctx?.currentTest?._currentRetry || ctx?.test?._currentRetry
}

Fix in Cursor Fix in Web


@cypress
Copy link
Copy Markdown

cypress Bot commented Nov 4, 2025

cypress    Run #67222

Run Properties:  status check passed Passed #67222  •  git commit 664916c6d2: merge develop
Project cypress
Branch Review ryanm/fix/retries-before-top-change
Run status status check passed Passed #67222
Run duration 19m 17s
Commit git commit 664916c6d2: merge develop
Committer Ryan Manuel
View all properties for this run ↗︎

Test results
Tests that failed  Failures 0
Tests that were flaky  Flaky 9
Tests that did not run due to a developer annotating a test with .skip  Pending 1098
Tests that did not run due to a failure in a mocha hook  Skipped 4
Tests that passed  Passing 26530
View all changes introduced in this branch ↗︎

Warning

Partial Report: The results for the Application Quality reports may be incomplete.

UI Coverage  45.48%
  Untested elements 188  
  Tested elements 161  
Accessibility  97.98%
  Failed rules  4 critical   8 serious   2 moderate   2 minor
  Failed elements 101  

Comment thread packages/driver/src/cypress/runner.ts Outdated
Comment thread packages/server/lib/socket-base.ts Outdated
Comment thread packages/server/test/unit/socket_spec.js Outdated
ryanthemanuel and others added 2 commits November 7, 2025 13:41
Co-authored-by: Bill Glesias <bglesias@gmail.com>
@ryanthemanuel ryanthemanuel merged commit 81b6a86 into develop Nov 7, 2025
90 of 92 checks passed
@ryanthemanuel ryanthemanuel deleted the ryanm/fix/retries-before-top-change branch November 7, 2025 22:23
@cypress-bot
Copy link
Copy Markdown
Contributor

cypress-bot Bot commented Nov 19, 2025

Released in 15.7.0.

This comment thread has been locked. If you are still experiencing this issue after upgrading to
Cypress v15.7.0, please open a new issue.

@cypress-bot cypress-bot Bot locked as resolved and limited conversation to collaborators Nov 19, 2025
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants