docs: iterate over the clock dock

This commit is contained in:
Pavel 2024-06-01 08:18:29 -07:00
parent 935aa0493c
commit 8d2f4c1433
3 changed files with 113 additions and 23 deletions

View File

@ -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

View File

@ -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
<input type="datetime-local" id="my-time" data-testid="my-time">
@ -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
<input type="datetime-local" id="my-time" data-testid="my-time">
<script>
@ -108,7 +117,7 @@ await Expect(locator).ToHaveValueAsync("2024-01-01T10:00");
```
```js
// Initialize clock with a specific time.
// 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');
await expect(page.getByTestId('my-time')).toHaveValue('2024-01-01T10:00');
@ -120,10 +129,9 @@ await expect(page.getByTestId('my-time')).toHaveValue('2024-01-01T10:30');
```
```python async
# Initialize clock with a specific time.
# 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),
toFake=['Date'],
)
await page.goto('http://localhost:3333')
locator = page.get_by_test_id('my-time')
@ -136,10 +144,9 @@ await expect(locator).to_have_value('2024-01-01T10:30')
```
```python sync
# Initialize clock with a specific time.
# 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),
to_fake=['Date'],
)
page.goto('http://localhost:3333')
locator = page.get_by_test_id('my-time')
@ -152,11 +159,10 @@ expect(locator).to_have_value('2024-01-01T10:30')
```
```java
// Initialize clock with a specific time.
// 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"))
.setToFake(new String[]{"Date"})
);
page.navigate("http://localhost:3333");
Locator locator = page.getByTestId("my-time");
@ -169,12 +175,11 @@ assertThat(locator).hasValue("2024-01-01T10:30");
```
```csharp
// Initialize clock with a specific time.
// 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),
ToFake = new[] { "Date" }
});
await page.GotoAsync("http://localhost:3333");
var locator = page.GetByTestId("my-time");
@ -185,3 +190,85 @@ await Expect(locator).ToHaveValueAsync("2024-01-01T10:00");
await page.Clock.JumpAsync("30:00");
await Expect(locator).ToHaveValueAsync("2024-01-01T10:30");
```
## Tick through time manually
In some cases, you may want to tick through time manually, firing all timers in the process.
This can be useful when you want to simulate the passage of time in a controlled manner.
```html
<input type="datetime-local" id="my-time" data-testid="my-time">
<script>
const renderTime = () => {
const time = new Date();
document.getElementById('my-time').value = time.toISOString().slice(0, 16);
setTimeout(renderTime, 1000);
};
renderTime();
</script>
```
```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);
```

View File

@ -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 {
/**