Skip to content

Commit 146a775

Browse files
committed
fix: update the timeout logic to consider also the checkFunction duration
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
1 parent d396e15 commit 146a775

File tree

2 files changed

+34
-3
lines changed

2 files changed

+34
-3
lines changed

cypress/e2e/plugin.spec.js

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,38 @@ context('Cypress Wait Until', () => {
3939
})
4040
})
4141

42+
it('Should run once if waitUntil timeout is less than checkFunction execution time', () => {
43+
let checks = 0
44+
const checkFunction = () => {
45+
cy.wait(500).then(() => {
46+
checks++
47+
return false
48+
})
49+
}
50+
51+
cy.once('fail', () => {
52+
expect(checks).to.equal(1)
53+
})
54+
55+
cy.waitUntil(checkFunction, { timeout: 400 })
56+
})
57+
58+
it('Should run 3 times if checkFunction + interval is 2s and timeout is 5s', () => {
59+
let checks = 0
60+
const checkFunction = () => {
61+
cy.wait(1500).then(() => {
62+
checks++
63+
return false
64+
})
65+
}
66+
67+
cy.once('fail', () => {
68+
expect(checks).to.equal(3)
69+
})
70+
71+
cy.waitUntil(checkFunction, { timeout: 5000, interval: 500 })
72+
})
73+
4274
it('Should apply options correctly', () => {
4375
const COOKIE_NAME = 'after-a-while-cookie'
4476
const EXPECTED_COOKIE_VALUE = 'Set'

src/index.js

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ const waitUntil = (subject, checkFunction, originalOptions = {}) => {
4747
// filter out a falsy passed "customMessage" value
4848
options.customMessage = [options.customMessage, originalOptions].filter(Boolean)
4949

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

5252
logCommand({ options, originalOptions })
5353

@@ -56,13 +56,12 @@ const waitUntil = (subject, checkFunction, originalOptions = {}) => {
5656
if (result) {
5757
return result
5858
}
59-
if (retries < 1) {
59+
if (Date.now() >= endTime) {
6060
const msg =
6161
options.errorMsg instanceof Function ? options.errorMsg(result, options) : options.errorMsg
6262
throw new Error(msg)
6363
}
6464
cy.wait(options.interval, { log: false }).then(() => {
65-
retries--
6665
return resolveValue()
6766
})
6867
}

0 commit comments

Comments
 (0)