Skip to content

Commit 2bde717

Browse files
committed
Review waitUntil implementation
1 parent 7174df9 commit 2bde717

4 files changed

Lines changed: 402 additions & 302 deletions

File tree

src/util/waitUntil.ts

Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,11 @@ const sleep = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms))
55
export type ConditionResult = { success: boolean; results: boolean[] }
66

77
/**
8-
* Wait for condition result to succeed (true) even when isNot is also true.
8+
* Wait for condition result to succeed (true) or to fail (false) when using `.not`.
99
* For a success result with isNot the condition must return false since Jest's expect inverts the result later.
1010
*
1111
* @param condition function
12-
* @param isNot https://jestjs.io/docs/expect#thisisnot
12+
* @param isNot when using `expect().not`, see https://jestjs.io/docs/expect#thisisnot
1313
* @param options wait, interval
1414
*/
1515
export const waitUntil = async (
@@ -22,14 +22,24 @@ export const waitUntil = async (
2222
const start = Date.now()
2323
let error: unknown
2424
let result: boolean | ConditionResult = false
25+
let pass: boolean = false
2526

2627
do {
2728
try {
2829
result = await condition()
2930
error = undefined
30-
if (isBoolean(result) ? result : result.success) {
31+
if (isBoolean(result)) {
32+
pass = result
33+
} else {
34+
// Waiting for all to be true. Or all to be false when using `.not` (pass=false since inverted later by Jest)
35+
pass = isNot ? !isAllFalse(result.results) : isAllTrue(result.results)
36+
}
37+
38+
// Waiting for the condition to succeed or to fail when using `.not`
39+
if (isNot ? !pass : pass) {
3140
break
3241
}
42+
3343
} catch (err) {
3444
error = err
3545
}
@@ -42,19 +52,13 @@ export const waitUntil = async (
4252

4353
if (error) { throw error }
4454

45-
if (isBoolean(result)) {
46-
return result
47-
}
48-
49-
const { results } = result
50-
51-
if (results.length === 0) {
52-
// To fails with .not, we need pass=true, so it s inverted later by Jest's expect framework
55+
// When no results were found, ensure the waitUntil return failure even with `.not`
56+
if (!isBoolean(result) && result.results.length === 0) {
57+
// To fails with .not, we need pass=true, so it's inverted later by Jest's expect framework
5358
return isNot
5459
}
5560

56-
// With isNot to succeed with need pass=false, so it s inverted later by Jest's expect framework
57-
return isNot ? !isAllFalse(results) : isAllTrue(results)
61+
return pass
5862
}
5963
const isBoolean = (value: unknown): value is boolean => typeof value === 'boolean'
6064

test/matchers/element/toBeDisabled.test.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -252,6 +252,8 @@ Expect $$(\`sel\`) not to be disabled
252252

253253
test('not - success (with wait) - pass should be false', async () => {
254254
elements.forEach(element => {
255+
vi.mocked(element.isEnabled).mockResolvedValueOnce(false)
256+
vi.mocked(element.isEnabled).mockResolvedValueOnce(false)
255257
vi.mocked(element.isEnabled).mockResolvedValue(true)
256258
})
257259

@@ -261,9 +263,8 @@ Expect $$(\`sel\`) not to be disabled
261263
wait: 500,
262264
interval: 100,
263265
})
264-
elements.forEach(element => {
265-
expect(element.isEnabled).toHaveBeenCalledTimes(5)
266-
})
266+
expect(elements[0].isEnabled).toHaveBeenCalledTimes(3)
267+
expect(elements[1].isEnabled).toHaveBeenCalledTimes(3)
267268
expect(result.pass).toBe(false) // success, boolean is inverted later because of `.not`
268269
})
269270

0 commit comments

Comments
 (0)