镜像站点 · 本页由第三方 GitHub 只读镜像提供,非 GitHub 官方站点,不接受任何登录或凭据输入。前往 github.com
Skip to content

Commit fbe37c0

Browse files
authored
fix(browser): clear screenshot stability timeout (#11659)
1 parent e2e9c64 commit fbe37c0

3 files changed

Lines changed: 56 additions & 13 deletions

File tree

‎packages/browser/src/node/commands/screenshotMatcher/index.ts‎

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -428,14 +428,20 @@ async function waitForStableScreenshot(
428428

429429
const stableScreenshot = getStableScreenshot(options, abortController.signal)
430430

431-
const result = await (timeout === 0
432-
? stableScreenshot
433-
: Promise.race([
434-
stableScreenshot,
435-
asyncTimeout(timeout).finally(() => abortController.abort()),
436-
]))
437-
438-
return result
431+
if (timeout === 0) {
432+
return stableScreenshot
433+
}
434+
435+
const stabilityTimeout = asyncTimeout(timeout)
436+
437+
try {
438+
return await Promise.race([
439+
stableScreenshot,
440+
stabilityTimeout.promise.finally(() => abortController.abort()),
441+
])
442+
} finally {
443+
stabilityTimeout.clear()
444+
}
439445
}
440446

441447
/**

‎packages/browser/src/node/commands/screenshotMatcher/utils.ts‎

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -275,15 +275,21 @@ export function takeDecodedScreenshot({
275275
* Creates a promise that resolves to `null` after the specified timeout.
276276
* If the timeout is `0`, the promise resolves immediately.
277277
*
278+
* Call `clear` once the result is not needed, otherwise the timer keeps the process alive until it fires.
279+
*
278280
* @param timeout - The delay in milliseconds before the promise resolves
279-
* @returns `Promise` that resolves to `null` after the timeout
281+
* @returns The `promise` and a `clear` function that stops the timer
280282
*/
281-
export function asyncTimeout(timeout: number): Promise<null> {
282-
return new Promise((resolve) => {
283+
export function asyncTimeout(timeout: number): { promise: Promise<null>; clear: () => void } {
284+
let timer: NodeJS.Timeout | undefined
285+
286+
const promise = new Promise<null>((resolve) => {
283287
if (timeout === 0) {
284288
resolve(null)
285289
} else {
286-
setTimeout(resolve, timeout, null)
290+
timer = setTimeout(resolve, timeout, null)
287291
}
288292
})
293+
294+
return { promise, clear: () => clearTimeout(timer) }
289295
}

‎test/browser/specs/to-match-screenshot.test.ts‎

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import type { ViteUserConfig } from 'vitest/config'
33
import type { TestFsStructure } from '../../test-utils'
44
import { platform } from 'node:os'
55
import { describe, expect, test } from 'vitest'
6-
import { runInlineTests } from '../../test-utils'
6+
import { runInlineTests, runVitestCli, useTmpFS } from '../../test-utils'
77
import { extractToMatchScreenshotPaths } from '../fixtures/expect-dom/utils'
88
import utilsContent from '../fixtures/expect-dom/utils?raw'
99
import { instances, provider } from '../settings'
@@ -322,3 +322,34 @@ test.for([{ option: 'retry' }, { option: 'repeats' }] as const)(
322322
)
323323
},
324324
)
325+
326+
test('does not keep the process alive until the stability timeout elapses', async () => {
327+
const { root } = useTmpFS({
328+
[testFilename]: testContent.replace(
329+
'toMatchScreenshot()',
330+
'toMatchScreenshot({ timeout: 30_000 })',
331+
),
332+
'utils.ts': utilsContent,
333+
'vitest.config.js': /* ts */ `
334+
import { instances, provider } from '../settings'
335+
336+
export default {
337+
test: {
338+
teardownTimeout: 5_000,
339+
browser: {
340+
enabled: true,
341+
ui: false,
342+
headless: true,
343+
provider,
344+
instances: [instances[0]],
345+
viewport: { width: 400, height: 200 },
346+
},
347+
},
348+
}`,
349+
})
350+
351+
const { stderr, exitCode } = await runVitestCli('--root', root, '--run', '--update')
352+
353+
expect(stderr).toMatchInlineSnapshot(`""`)
354+
expect(exitCode).toBe(0)
355+
})

0 commit comments

Comments
 (0)