Q28 of 48 · Cypress
How do you mock the system clock in Cypress?
Short answer
Short answer: Use `cy.clock()` to override `Date.now`, `setTimeout`, and `setInterval` in the application's window. Advance time with `cy.tick(ms)`. Restore with `cy.clock().then((c) => c.restore())`. Essential for testing scheduled UI, debounce, polling, and time-based business logic.
Detail
cy.clock() patches the browser's clock from the test, freezing time and giving you control over advancement. Without it, time-dependent UI (a "5 minutes ago" label, a debounced search input, a scheduled notification) can't be tested deterministically.
The core API:
cy.clock(); // freezes Date.now() at current time, freezes timers
cy.clock(new Date('2026-01-01').getTime()); // freezes at a specific time
cy.tick(1000); // advances 1 second; runs any timers that fire
Important: cy.clock() must be called before the page sets up timers — typically before cy.visit. Set it, visit, then tick to advance.
Common scenarios:
- Debounced inputs — type,
cy.tick(300)past the debounce, assert the request fires. - Polling — assert the first request fires immediately,
cy.tick(intervalMs)to verify subsequent ones. - Time-relative UI — set the clock to a specific moment, assert "2 hours ago" labels are correct.
- Scheduled state — set up a future-fire scenario, tick past it, assert the side effect.
The functions to override are configurable: cy.clock(timestamp, ['Date', 'setTimeout']) to leave setInterval real, for instance.
Restoration is automatic at the end of each test under testIsolation: true. If you want to restore mid-test, cy.clock().then((c) => c.restore()).
// EXAMPLE
debounce.cy.ts
it('debounces search input by 300ms', () => {
cy.intercept('GET', '/api/search*').as('search');
cy.clock();
cy.visit('/');
cy.get('[data-test=search]').type('apple');
// No request yet
cy.tick(200);
cy.get('@search.all').should('have.length', 0);
// Past the 300ms debounce
cy.tick(150);
cy.wait('@search').its('request.url').should('include', 'q=apple');
});
it('shows "2 hours ago" for a 2h-old comment', () => {
cy.clock(new Date('2026-05-10T15:00:00Z').getTime());
cy.intercept('GET', '/api/comments', {
body: [{ id: 1, createdAt: '2026-05-10T13:00:00Z', text: 'Nice' }],
});
cy.visit('/comments');
cy.get('[data-test=comment-time]').should('have.text', '2 hours ago');
});