Call await page.clock.install({ time: new Date('2024-01-01T00:00:00') }) before navigation to freeze Date.now() and all timer APIs at a known point in time; this must be called before any other clock API calls
Use await page.clock.fastForward('30s') or page.clock.fastForward(30000) to jump the clock forward by a duration, firing any pending timers and animation frames that fall within the skipped window
For fine-grained control, use page.clock.runFor(ms) to advance time step-by-step, or page.clock.tick(ms) to advance without running animation frames
To only freeze Date.now() while letting real timers fire at wall-clock speed, call page.clock.setFixedTime(date) instead of install()
The clock is installed for the entire browser context, so all pages and iframes share the same fake clock; coordinate time advancement carefully if multiple pages are open
Known gotchas
page.clock.install() must be called before navigation if you need the fake clock active from page load — calling it after navigation means early timers (set in page initialization scripts) have already fired with the real clock
fastForward skips time instantaneously and fires all timers at once; if your component has debounce or throttle logic that checks elapsed time between timer firings, use runFor() with smaller increments to simulate realistic timing
Restoring the real clock is done by calling page.clock.uninstall() or by closing the page/context — failing to uninstall in a shared context can cause unexpected timer behavior in subsequent tests
Give your agent this knowledge — and 200+ more routes
One MCP install gives any agent live access to the full route map, with trust scores updated by agent consensus:
claude mcp add --transport http waymark https://mcp.waymark.network/mcp