--- id: clock title: "Clock" --- ## Introduction Accurately simulating time-dependent behavior is essential for verifying the correctness of applications. Utilizing [Clock] functionality allows developers to manipulate and control time within tests, enabling the precise validation of features such as rendering time, timeouts, scheduled tasks without the delays and variability of real-time execution. [`property: Page.clock`] overrides native global classes and functions related to time allowing them to be manually controlled: - `Date` - `setTimeout` - `clearTimeout` - `setInterval` - `clearInterval` - `requestAnimationFrame` - `cancelAnimationFrame` - `requestIdleCallback` - `cancelIdleCallback` By default, the clock starts at the unix epoch (timestamp of 0). You can override it using the `now` option. ```js await page.clock.setTime(new Date('2020-02-02')); await page.clock.installFakeTimers(new Date('2020-02-02')); ``` ## Mock Date.now Most of the time, you only need to fake `Date.now` and no other time-related functions. That way the time flows naturally, but `Date.now` returns a fixed value. ```html
``` ```js await page.clock.setTime(new Date('2024-02-02T10:00:00')); await page.goto('http://localhost:3333'); await expect(page.getByTestId('current-time')).toHaveText('2/2/2024, 10:00:00 AM'); await page.clock.setTime(new Date('2024-02-02T10:30:00')); await expect(page.getByTestId('current-time')).toHaveText('2/2/2024, 10:30:00 AM'); ``` ```python async page.clock.set_time(datetime.datetime(2024, 2, 2, 10, 0, 0, tzinfo=datetime.timezone.pst)) await page.goto('http://localhost:3333') locator = page.get_by_test_id('current-time') await expect(locator).to_have_text('2/2/2024, 10:00:00 AM') page.clock.set_time(datetime.datetime(2024, 2, 2, 10, 30, 0, tzinfo=datetime.timezone.pst)) await expect(locator).to_have_text('2/2/2024, 10:30:00 AM') ``` ```python sync page.clock.set_time(datetime.datetime(2024, 2, 2, 10, 0, 0, tzinfo=datetime.timezone.pst)) page.goto('http://localhost:3333') locator = page.get_by_test_id('current-time') expect(locator).to_have_text('2/2/2024, 10:00:00 AM') page.clock.set_time(datetime.datetime(2024, 2, 2, 10, 30, 0, tzinfo=datetime.timezone.pst)) expect(locator).to_have_text('2/2/2024, 10:30:00 AM') ``` ```java page.clock().setTime(Instant.parse("2024-02-02T10:00:00")); page.navigate("http://localhost:3333"); Locator locator = page.getByTestId("current-time"); assertThat(locator).hasText("2/2/2024, 10:00:00 AM"); page.clock().setTime(Instant.parse("2024-02-02T10:30:00")); assertThat(locator).hasText("2/2/2024, 10:30:00 AM"); ``` ```csharp // Initialize clock with a specific time, only fake Date.now. await page.Clock.SetTimeAsync(new DateTime(2024, 2, 2, 10, 0, 0, DateTimeKind.Pst)); await page.GotoAsync("http://localhost:3333"); var locator = page.GetByTestId("current-time"); await Expect(locator).ToHaveTextAsync("2/2/2024, 10:00:00 AM"); await page.Clock.SetTimeAsync(new DateTime(2024, 2, 2, 10, 30, 0, DateTimeKind.Pst)); await Expect(locator).ToHaveTextAsync("2/2/2024, 10:30:00 AM"); ``` ## Mock Date.now consistent with the timers Sometimes your timers depend on `Date.now` and are confused when the time stands still. In cases like this you need to ensure that `Date.now` and timers are consistent. You can achieve this by installing the fake timers. ```html ``` ```js // Initialize clock with a specific time, take full control over time. await page.clock.installFakeTimers(new Date('2024-02-02T10:00:00')); await page.goto('http://localhost:3333'); await expect(page.getByTestId('current-time')).toHaveText('2/2/2024, 10:00:00 AM'); // Fast forward time 30 minutes without firing intermediate timers, as if the user // closed and opened the lid of the laptop. await page.clock.skipTime('30:00'); await expect(page.getByTestId('current-time')).toHaveText('2/2/2024, 10:30:00 AM'); ``` ```python async # Initialize clock with a specific time, take full control over time. await page.clock.install_fake_timers( datetime.datetime(2024, 2, 2, 10, 0, 0, tzinfo=datetime.timezone.pst) ) await page.goto('http://localhost:3333') locator = page.get_by_test_id('current-time') await expect(locator).to_have_text('2/2/2024, 10:00:00 AM') # Fast forward time 30 minutes without firing intermediate timers, as if the user # closed and opened the lid of the laptop. await page.clock.skip_time('30:00') await expect(locator).to_have_text('2/2/2024, 10:30:00 AM') ``` ```python sync # Initialize clock with a specific time, take full control over time. page.clock.install_fake_timers( datetime.datetime(2024, 2, 2, 10, 0, 0, tzinfo=datetime.timezone.pst) ) page.goto('http://localhost:3333') locator = page.get_by_test_id('current-time') expect(locator).to_have_text('2/2/2024, 10:00:00 AM') # Fast forward time 30 minutes without firing intermediate timers, as if the user # closed and opened the lid of the laptop. page.clock.skip_time('30:00') expect(locator).to_have_text('2/2/2024, 10:30:00 AM') ``` ```java // Initialize clock with a specific time, take full control over time. page.clock().installFakeTimers(Instant.parse("2024-02-02T10:00:00")); page.navigate("http://localhost:3333"); Locator locator = page.getByTestId("current-time"); assertThat(locator).hasText("2/2/2024, 10:00:00 AM") // Fast forward time 30 minutes without firing intermediate timers, as if the user // closed and opened the lid of the laptop. page.clock().skipTime("30:00"); assertThat(locator).hasText("2/2/2024, 10:30:00 AM"); ``` ```csharp // Initialize clock with a specific time, take full control over time. await page.Clock.InstallFakeTimersAsync( new DateTime(2024, 2, 2, 10, 0, 0, DateTimeKind.Pst) ); await page.GotoAsync("http://localhost:3333"); var locator = page.GetByTestId("current-time"); await Expect(locator).ToHaveTextAsync("2/2/2024, 10:00:00 AM"); // Fast forward time 30 minutes without firing intermediate timers, as if the user // closed and opened the lid of the laptop. await page.Clock.SkipTimeAsync("30:00"); await Expect(locator).ToHaveTextAsync("2/2/2024, 10:30:00 AM"); ``` ## Tick through time manually In rare cases, you may want to tick through time manually, firing all timers and animation frames in the process to achieve a fine-grained control over the passage of time. ```html ``` ```js // Initialize clock with a specific time, take full control over time. await page.clock.installFakeTimers(new Date('2024-02-02T10:00:00')); await page.goto('http://localhost:3333'); // Tick through time manually, firing all timers in the process. // In this case, time will be updated in the screen 2 times. await page.clock.runFor(2000); await expect(locator).to_have_text('2/2/2024, 10:00:02 AM') ``` ```python async # Initialize clock with a specific time, take full control over time. await page.clock.install_fake_timers( datetime.datetime(2024, 2, 2, 10, 0, 0, tzinfo=datetime.timezone.pst), ) await page.goto('http://localhost:3333') locator = page.get_by_test_id('current-time') # Tick through time manually, firing all timers in the process. # In this case, time will be updated in the screen 2 times. await page.clock.run_for(2000) await expect(locator).to_have_text('2/2/2024, 10:00:02 AM') ``` ```python sync # Initialize clock with a specific time, take full control over time. page.clock.install_fake_timers( datetime.datetime(2024, 2, 2, 10, 0, 0, tzinfo=datetime.timezone.pst), ) page.goto('http://localhost:3333') locator = page.get_by_test_id('current-time') # Tick through time manually, firing all timers in the process. # In this case, time will be updated in the screen 2 times. page.clock.run_for(2000) expect(locator).to_have_text('2/2/2024, 10:00:02 AM') ``` ```java // Initialize clock with a specific time, take full control over time. page.clock().installFakeTimers(Instant.parse("2024-02-02T10:00:00")); page.navigate("http://localhost:3333"); Locator locator = page.getByTestId("current-time"); // Tick through time manually, firing all timers in the process. // In this case, time will be updated in the screen 2 times. page.clock().runFor(2000); assertThat(locator).hasText("2/2/2024, 10:00:02 AM"); ``` ```csharp // Initialize clock with a specific time, take full control over time. await page.Clock.InstallFakeTimersAsync( new DateTime(2024, 2, 2, 10, 0, 0, DateTimeKind.Pst) ); await page.GotoAsync("http://localhost:3333"); var locator = page.GetByTestId("current-time"); // Tick through time manually, firing all timers in the process. // In this case, time will be updated in the screen 2 times. await page.Clock.RunForAsync(2000); await Expect(locator).ToHaveTextAsync("2/2/2024, 10:00:02 AM"); ```