Skip to content

Commit

Permalink
fix: update the timeout logic to consider also the checkFunction dura…
Browse files Browse the repository at this point in the history
…tion

Before this commit, the number of retries was calculated ignoring the checkFunction duration.

As a result, a 5s timeout with a 0.5s interval resulted in 10 retries.
If the checkFunction takes 10 seconds, 10 retries mean waiting for 100 seconds, violating the 5s timeout.

This commit fixes the problem by checking, after each checkFunction invocation, what is the elapsed time and stops retrying in case the timeout is over.

BREAKING CHANGE: The timeout is now respected even if checkFunction takes a long time. As a result,
you could face that your checkFunction runs less times.

fix #464
  • Loading branch information
NoriSte committed Jun 14, 2023
1 parent d396e15 commit 146a775
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 3 deletions.
32 changes: 32 additions & 0 deletions cypress/e2e/plugin.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,38 @@ context('Cypress Wait Until', () => {
})
})

it('Should run once if waitUntil timeout is less than checkFunction execution time', () => {
let checks = 0
const checkFunction = () => {
cy.wait(500).then(() => {
checks++
return false
})
}

cy.once('fail', () => {
expect(checks).to.equal(1)
})

cy.waitUntil(checkFunction, { timeout: 400 })
})

it('Should run 3 times if checkFunction + interval is 2s and timeout is 5s', () => {
let checks = 0
const checkFunction = () => {
cy.wait(1500).then(() => {
checks++
return false
})
}

cy.once('fail', () => {
expect(checks).to.equal(3)
})

cy.waitUntil(checkFunction, { timeout: 5000, interval: 500 })
})

it('Should apply options correctly', () => {
const COOKIE_NAME = 'after-a-while-cookie'
const EXPECTED_COOKIE_VALUE = 'Set'
Expand Down
5 changes: 2 additions & 3 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ const waitUntil = (subject, checkFunction, originalOptions = {}) => {
// filter out a falsy passed "customMessage" value
options.customMessage = [options.customMessage, originalOptions].filter(Boolean)

let retries = Math.floor(options.timeout / options.interval)
const endTime = Date.now() + options.timeout

logCommand({ options, originalOptions })

Expand All @@ -56,13 +56,12 @@ const waitUntil = (subject, checkFunction, originalOptions = {}) => {
if (result) {
return result
}
if (retries < 1) {
if (Date.now() >= endTime) {
const msg =
options.errorMsg instanceof Function ? options.errorMsg(result, options) : options.errorMsg
throw new Error(msg)
}
cy.wait(options.interval, { log: false }).then(() => {
retries--
return resolveValue()
})
}
Expand Down

0 comments on commit 146a775

Please sign in to comment.