Clock Mocking
TestClock lets you freeze or advance the browser's Date object so you can test time-sensitive UI without touching the database or the system clock.
How it works
clock().set(isoString) injects a Date override into the active browser page. Every subsequent new Date() and Date.now() call in client-side JavaScript returns the mocked time. The real Date is saved under window.__sbOriginalDate and restored automatically at the end of each test.
Quick example
public class TrialBannerTest extends BaseTest {
@Test
public void showsExpiredBanner_when30DaysPast() {
open("/dashboard");
clock().set("2030-06-01T00:00:00Z"); // trial expired 30 days ago
getDriver().navigate().refresh(); // page re-renders with mocked time
assertThat(By.id("trial-banner")).hasText("Your trial expired 30 days ago");
}
}
open() firstclock().set() requires an active page because it injects JavaScript. Call open() first, then set the clock, then trigger any client-side re-render (refresh, SPA navigation, or a click that fetches dates).
API reference
clock().set(String isoDateTime)
Overrides new Date() and Date.now() in the browser to the given instant.
clock().set("2030-01-01T00:00:00Z");
- Accepts any ISO 8601 UTC string (
Instant.parsecompatible) - Returns
thisfor chaining
clock().advance(Duration duration)
Advances the mocked time by duration from the current mock. If no mock is active, advances from the real current time.
clock().set("2030-01-01T00:00:00Z");
clock().advance(Duration.ofDays(30)); // now mocked to 2030-01-31
Returns this for chaining. Common durations:
Duration.ofSeconds(30)
Duration.ofMinutes(5)
Duration.ofHours(1)
Duration.ofDays(90)
clock().reset()
Restores the real Date implementation in the browser. Called automatically after each test — explicit calls are optional.
clock().set("2030-01-01T00:00:00Z");
// ... assertions ...
clock().reset(); // optional — framework does this automatically
clock().getMockedTimeMs()
Returns the currently mocked time as epoch milliseconds, or null if no mock is active.