feat: automatically advance fake timers in Jest and Vitest - #1324
Draft
TrevorBurnham wants to merge 1 commit into
Draft
feat: automatically advance fake timers in Jest and Vitest#1324TrevorBurnham wants to merge 1 commit into
TrevorBurnham wants to merge 1 commit into
Conversation
Both frameworks install `@sinonjs/fake-timers`, which exposes the clock on each timer function it replaces. Ticking that clock advances fake timers whichever framework installed them - and only while they are installed, so real timers are untouched. Fixes testing-library#1115
TrevorBurnham
force-pushed
the
fix-fake-timers-clock-detection
branch
from
August 15, 2026 23:16
812e1c9 to
9e85866
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Alternative to #1304. Same goal:
userEventshould advance fake timers withoutadvanceTimersbeing configured manually. Different detection mechanism, because detecting thejest/viglobals doesn't hold up.Fixes #1115
Why not detect framework globals
#1304 reads
globalThis.jestandglobalThis.vi. Verified against Vitest 4.1.10 and Jest 30.4.1:jestinto each module's scope, not ontoglobalThis. Inside a test filetypeof jest === 'object'whileglobalThis.jestisundefined, so the Jest branch never fires.globalThis.vionly exists withglobals: true, which defaults tofalse. Users whoimport {vi} from 'vitest'get no detection.globals: trueand real timers it is worse than inert.advanceTimersruns on every API call, andvi.advanceTimersByTime()throws when timers are not mocked, soawait user.click(button)fails withA function to advance timers was called but the timers APIs are not mocked.What this does instead
Jest's modern fake timers and Vitest's fake timers are both built on
@sinonjs/fake-timers, which exposes the installed clock on each timer function it replaces. So tick that clock when it is present:This works however the framework is imported, and only while fake timers are installed, so real timers are never touched. It is the same signal
@testing-library/domuses injestFakeTimersAreEnabled().Detection happens per
wait()rather than once increateConfig(), so callinguserEvent.setup()in abeforeEachbeforeuseFakeTimers()also works. An explicitadvanceTimersoption still takes precedence.Verification
Two scratch projects, Vitest 4.1.10 and Jest 30.4.1, both on jsdom 30, run against packed builds of this branch and of #1304:
globals: false(default)globals: trueCovered: click and delayed
type()under fake timers with no options, fake timers installed aftersetup(),toFake: ['Date']only, explicitadvanceTimersstill honored, real timers clean, Jest legacy timers.This repo's test env installs
@sinonjs/fake-timersthe same way Jest and Vitest do, so the unit tests exercise the real mechanism instead of hand-assigned globals.Notes for review
setTimeout.clockis undocumented@sinonjs/fake-timersinternals.@testing-library/domalready relies on it, so the risk is shared, but it is a dependency on an implementation detail.advanceTimers, unchanged from today.waitForin@testing-library/domsniffs thejestglobal separately, so Vitest users under fake timers may still need theglobalThis.jestshim forfindBy*queries. Out of scope here.advanceTimers. Happy to send a docs PR alongside this.