Skip to content

Commit 22eff98

Browse files
committed
fix(browser): run toMatchScreenshot only once when used with expect.element
1 parent f97ac39 commit 22eff98

2 files changed

Lines changed: 30 additions & 12 deletions

File tree

packages/browser/src/client/tester/expect-element.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,11 @@ function element<T extends HTMLElement | SVGElement | null | Locator>(elementOrL
2929
return elementOrLocator.elements() as unknown as HTMLElement
3030
}
3131

32+
if (name === 'toMatchScreenshot' && !chai.util.flag(this, '_poll.assert_once')) {
33+
// `toMatchScreenshot` should only run once after the element resolves
34+
chai.util.flag(this, '_poll.assert_once', true)
35+
}
36+
3237
// element selector uses prettyDOM under the hood, which is an expensive call
3338
// that should not be called on each failed locator attempt to avoid memory leak:
3439
// https://github.com/vitest-dev/vitest/issues/7139

packages/vitest/src/integrations/chai/poll.ts

Lines changed: 25 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -69,12 +69,36 @@ export function createExpectPoll(expect: ExpectStatic): ExpectStatic['poll'] {
6969
let timeoutId: any
7070
let lastError: any
7171
const { setTimeout, clearTimeout } = getSafeTimers()
72+
const rejectWithCause = (error: any) => {
73+
if (error.cause == null) {
74+
error.cause = new Error('Matcher did not succeed in time.')
75+
}
76+
reject(
77+
copyStackTrace(
78+
error,
79+
STACK_TRACE_ERROR,
80+
),
81+
)
82+
}
7283
const check = async () => {
7384
try {
7485
chai.util.flag(assertion, '_name', key)
7586
const obj = await fn()
7687
chai.util.flag(assertion, 'object', obj)
77-
resolve(await assertionFunction.call(assertion, ...args))
88+
try {
89+
resolve(await assertionFunction.call(assertion, ...args))
90+
}
91+
catch (err) {
92+
if (chai.util.flag(assertion, '_poll.assert_once')) {
93+
clearTimeout(intervalId)
94+
clearTimeout(timeoutId)
95+
96+
rejectWithCause(err)
97+
}
98+
else {
99+
throw err
100+
}
101+
}
78102
clearTimeout(intervalId)
79103
clearTimeout(timeoutId)
80104
}
@@ -88,17 +112,6 @@ export function createExpectPoll(expect: ExpectStatic): ExpectStatic['poll'] {
88112
timeoutId = setTimeout(() => {
89113
clearTimeout(intervalId)
90114
chai.util.flag(assertion, '_isLastPollAttempt', true)
91-
const rejectWithCause = (error: any) => {
92-
if (error.cause == null) {
93-
error.cause = new Error('Matcher did not succeed in time.')
94-
}
95-
reject(
96-
copyStackTrace(
97-
error,
98-
STACK_TRACE_ERROR,
99-
),
100-
)
101-
}
102115
check()
103116
.then(() => rejectWithCause(lastError))
104117
.catch(e => rejectWithCause(e))

0 commit comments

Comments
 (0)