diff --git a/docs/src/api/class-clock.md b/docs/src/api/class-clock.md
index d703c07b84..271023e2cb 100644
--- a/docs/src/api/class-clock.md
+++ b/docs/src/api/class-clock.md
@@ -1,9 +1,10 @@
# class: Clock
* since: v1.45
-Playwright uses [@sinonjs/fake-timers](https://github.com/sinonjs/fake-timers) for clock emulation. Clock is installed for the entire [BrowserContext], so the time
-in all the pages and iframes is controlled by the same clock.
+Accurately simulating time-dependent behavior is essential for verifying the correctness of applications. Learn more about [clock emulation](../clock.md).
+Note that clock is installed for the entire [BrowserContext], so the time
+in all the pages and iframes is controlled by the same clock.
## async method: Clock.install
* since: v1.45
diff --git a/docs/src/clock.md b/docs/src/clock.md
index 1b063f11b7..95e8df0e56 100644
--- a/docs/src/clock.md
+++ b/docs/src/clock.md
@@ -5,24 +5,30 @@ title: "Clock"
## Introduction
-[`property: Page.clock`] overrides native global functions related to time allowing them to be manually controlled:
+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`
- - `Date`
- `requestAnimationFrame`
- `cancelAnimationFrame`
- `requestIdleCallback`
+ - `cancelIdleCallback`
-By default, the clock starts at the unix epoch (timestamp of 0), but you can override it using the `now` option.
+By default, the clock starts at the unix epoch (timestamp of 0). You can override it using the `now` option.
```js
await page.clock.install();
await page.clock.install({ now: new Date('2020-02-02') });
```
-## Only fake Date.now
+## Freeze Date.now
+
+Sometimes 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
@@ -37,7 +43,7 @@ await page.clock.install({ now: new Date('2020-02-02') });
```
```js
-// Initialize clock with a specific time.
+// Initialize clock with a specific time, only fake Date.now.
await page.clock.install({
now: new Date('2024-01-01T10:00:00Z'),
toFake: ['Date'],
@@ -47,7 +53,7 @@ await expect(page.getByTestId('my-time')).toHaveValue('2024-01-01T10:00');
```
```python async
-# Initialize clock with a specific time.
+# Initialize clock with a specific time, only fake Date.now.
await page.clock.install(
now=datetime.datetime(2024, 1, 1, 10, 0, 0, tzinfo=datetime.timezone.utc),
toFake=['Date'],
@@ -58,7 +64,7 @@ await expect(locator).to_have_value('2024-01-01T10:00')
```
```python sync
-# Initialize clock with a specific time.
+# Initialize clock with a specific time, only fake Date.now.
page.clock.install(
now=datetime.datetime(2024, 1, 1, 10, 0, 0, tzinfo=datetime.timezone.utc),
to_fake=['Date'],
@@ -69,7 +75,7 @@ expect(locator).to_have_value('2024-01-01T10:00')
```
```java
-// Initialize clock with a specific time.
+// Initialize clock with a specific time, only fake Date.now.
page.clock().install(
new Clock.InstallOptions()
.setNow(Instant.parse("2024-01-01T10:00:00Z"))
@@ -81,7 +87,7 @@ assertThat(locator).hasValue("2024-01-01T10:00");
```
```csharp
-// Initialize clock with a specific time.
+// Initialize clock with a specific time, only fake Date.now.
await page.Clock.InstallAsync(
new ClockInstallOptions
{
@@ -95,6 +101,9 @@ await Expect(locator).ToHaveValueAsync("2024-01-01T10:00");
## Assert page at different points in time
+More often you need to simulate the passage of time to test time-dependent behavior.
+You can jump the clock forward in time to simulate the passage of time without waiting for real-time to pass.
+
```html
+```
+
+```js
+// Initialize clock with a specific time, take full control over time.
+await page.clock.install({ now: new Date('2024-01-01T10:00:00Z') });
+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.tick(2000);
+```
+
+```python async
+# Initialize clock with a specific time, take full control over time.
+await page.clock.install(
+ now=datetime.datetime(2024, 1, 1, 10, 0, 0, tzinfo=datetime.timezone.utc),
+)
+await page.goto('http://localhost:3333')
+locator = page.get_by_test_id('my-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.tick(2000)
+```
+
+```python sync
+# Initialize clock with a specific time, take full control over time.
+page.clock.install(
+ now=datetime.datetime(2024, 1, 1, 10, 0, 0, tzinfo=datetime.timezone.utc),
+)
+page.goto('http://localhost:3333')
+locator = page.get_by_test_id('my-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.tick(2000)
+```
+
+```java
+// Initialize clock with a specific time, take full control over time.
+page.clock().install(
+ new Clock.InstallOptions()
+ .setNow(Instant.parse("2024-01-01T10:00:00Z"))
+);
+page.navigate("http://localhost:3333");
+Locator locator = page.getByTestId("my-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().tick(2000);
+```
+
+```csharp
+// Initialize clock with a specific time, take full control over time.
+await page.Clock.InstallAsync(
+ new ClockInstallOptions
+ {
+ Now = new DateTime(2024, 1, 1, 10, 0, 0, DateTimeKind.Utc),
+ });
+await page.GotoAsync("http://localhost:3333");
+var locator = page.GetByTestId("my-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.TickAsync(2000);
+```
diff --git a/packages/playwright-core/types/types.d.ts b/packages/playwright-core/types/types.d.ts
index a77afd9b5c..dd53b1e890 100644
--- a/packages/playwright-core/types/types.d.ts
+++ b/packages/playwright-core/types/types.d.ts
@@ -17239,9 +17239,11 @@ export interface BrowserServer {
}
/**
- * Playwright uses [@sinonjs/fake-timers](https://github.com/sinonjs/fake-timers) for clock emulation. Clock is
- * installed for the entire {@link BrowserContext}, so the time in all the pages and iframes is controlled by the same
- * clock.
+ * Accurately simulating time-dependent behavior is essential for verifying the correctness of applications. Learn
+ * more about [clock emulation](https://playwright.dev/docs/clock).
+ *
+ * Note that clock is installed for the entire {@link BrowserContext}, so the time in all the pages and iframes is
+ * controlled by the same clock.
*/
export interface Clock {
/**