Clock Steps

Time-dependent UI is hard to test in real time: a "5 minutes ago" label takes 5 minutes to verify, and a session-timeout warning sits idle for 14 minutes before firing. The clock steps wrap Playwright's page.clock API in BDD phrasings so scenarios can freeze and advance virtual time at full speed - scheduled emails, expirations, countdowns, and relative timestamps are all covered without slowing down CI with real waits.

Once a fake clock is installed, Date.now() inside the page returns the fake time, and pending setTimeout / setInterval callbacks queue but do not fire until you advance the clock. Each advance then fires every timer scheduled within the new interval, in order, instantly. Because the clock lives on the page, you must have a page open (for example via Given I am on "/path") before installing it - the steps raise a friendly error with that hint if you forget.

Reach for these steps together with wait steps and web-first assertions: instead of waiting a real 30 seconds for a countdown, install the clock, advance it 30 seconds, and assert the new state immediately.

Quick reference

StepWhat it does
Given the system time is "2026-05-08T10:00:00Z"Install a fake clock anchored at an ISO 8601 instant.
When I advance the clock by 500 msAdvance the fake clock forward by N milliseconds.
When I advance the clock by 30 secondsAdvance the fake clock forward by N seconds.
When I advance the clock by 5 minutesAdvance the fake clock forward by N minutes.
When I pause the clockPause the fake clock at its current value.
When I resume the clockResume the paused fake clock.
When I set the system time to "2026-05-08T12:30:00Z"Jump the fake clock to a specific time without firing skipped timers.

Steps in detail

Given the system time is "<ISO 8601>"

Installs a fake clock anchored at the given instant via page.clock.install(). The parameter must be a valid ISO 8601 date such as 2026-05-08T10:00:00Z; timezone offsets like 2026-07-04T12:00:00-04:00 work too. An unparseable date fails immediately with a hint showing the expected format, and installing without an open page fails with a hint to navigate first.

Install the clock before loading the page under test if you need its scripts to see the fake time on their first execution.

Given I am on "/date.html"
  And the system time is "2026-05-08T10:00:00Z"
 Then I should see ""

When I advance the clock by <N> ms / seconds / minutes

Three unit variants of the same operation: they call page.clock.runFor() with the interval converted to milliseconds. Every timer scheduled within the advanced window fires, in order, instantly - so a 15-minute session timer completes in a fraction of a second. Singular forms (1 second, 1 minute) and the we pronoun are accepted. If no fake clock is installed yet, the step fails with a hint to run Given the system time is "..." first.

When I advance the clock by 500 ms
 And I advance the clock by 30 seconds
 And I advance the clock by 5 minutes
Then "<.timestamp>" should have text "5 minutes ago"

When I pause the clock / When I resume the clock

pause freezes time at the current value (page.clock.pauseAt() with the page's current Date.now()), which is useful for asserting a countdown mid-flight without it ticking away underneath the assertion. resume lets time flow again; it expects a previously paused clock and hints accordingly if there is none.

When I pause the clock
Then the element ".countdown" should be displayed
When I resume the clock

When I set the system time to "<ISO 8601>"

Jumps the fake clock to a new instant via page.clock.setSystemTime() without firing the timers scheduled in between - use an advance step instead if you want them to fire. Like the install step, it validates the ISO 8601 format up front and requires the fake clock to already be installed.

Given the system time is "2026-12-31T23:59:55Z"
When I set the system time to "2027-01-01T00:00:00Z"
Then I should see "Happy New Year"

Complete example

Feature: Session timeout warning

  Scenario: Idle warning fires at 14 minutes
    Given the system time is "2026-05-08T10:00:00Z"
      And I restore the auth state from "tests/auth/admin.json"
      And I am on "/dashboard"
     When I advance the clock by 14 minutes
     Then "<#session-warning>" should be visible

  Scenario: "5 minutes ago" updates as time passes
    Given the system time is "2026-05-08T10:00:00Z"
      And I am on "/feed"
      And "<.timestamp>" should have text "just now"
     When I advance the clock by 5 minutes
     Then "<.timestamp>" should have text "5 minutes ago"

Tips

  • requestAnimationFrame and MutationObserver are not on the fake clock - animations driven by rAF keep playing in real time.
  • The Date constructor reads the fake clock, but server timestamps embedded in the HTML at page load do not change.
  • Install the clock before navigating if page scripts must see the fake time on first execution.
  • set the system time skips intermediate timers; advance the clock fires them.

Back to all step groups