mirror of
https://github.com/microsoft/playwright.git
synced 2025-06-26 21:40:17 +00:00
docs: iterate over the clock dock
This commit is contained in:
parent
935aa0493c
commit
8d2f4c1433
@ -1,9 +1,10 @@
|
|||||||
# class: Clock
|
# class: Clock
|
||||||
* since: v1.45
|
* 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
|
Accurately simulating time-dependent behavior is essential for verifying the correctness of applications. Learn more about [clock emulation](../clock.md).
|
||||||
in all the pages and iframes is controlled by the same clock.
|
|
||||||
|
|
||||||
|
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
|
## async method: Clock.install
|
||||||
* since: v1.45
|
* since: v1.45
|
||||||
|
@ -5,24 +5,30 @@ title: "Clock"
|
|||||||
|
|
||||||
## Introduction
|
## 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`
|
- `setTimeout`
|
||||||
- `clearTimeout`
|
- `clearTimeout`
|
||||||
- `setInterval`
|
- `setInterval`
|
||||||
- `clearInterval`
|
- `clearInterval`
|
||||||
- `Date`
|
|
||||||
- `requestAnimationFrame`
|
- `requestAnimationFrame`
|
||||||
- `cancelAnimationFrame`
|
- `cancelAnimationFrame`
|
||||||
- `requestIdleCallback`
|
- `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
|
```js
|
||||||
await page.clock.install();
|
await page.clock.install();
|
||||||
await page.clock.install({ now: new Date('2020-02-02') });
|
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
|
```html
|
||||||
<input type="datetime-local" id="my-time" data-testid="my-time">
|
<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
|
```js
|
||||||
// Initialize clock with a specific time.
|
// Initialize clock with a specific time, only fake Date.now.
|
||||||
await page.clock.install({
|
await page.clock.install({
|
||||||
now: new Date('2024-01-01T10:00:00Z'),
|
now: new Date('2024-01-01T10:00:00Z'),
|
||||||
toFake: ['Date'],
|
toFake: ['Date'],
|
||||||
@ -47,7 +53,7 @@ await expect(page.getByTestId('my-time')).toHaveValue('2024-01-01T10:00');
|
|||||||
```
|
```
|
||||||
|
|
||||||
```python async
|
```python async
|
||||||
# Initialize clock with a specific time.
|
# Initialize clock with a specific time, only fake Date.now.
|
||||||
await page.clock.install(
|
await page.clock.install(
|
||||||
now=datetime.datetime(2024, 1, 1, 10, 0, 0, tzinfo=datetime.timezone.utc),
|
now=datetime.datetime(2024, 1, 1, 10, 0, 0, tzinfo=datetime.timezone.utc),
|
||||||
toFake=['Date'],
|
toFake=['Date'],
|
||||||
@ -58,7 +64,7 @@ await expect(locator).to_have_value('2024-01-01T10:00')
|
|||||||
```
|
```
|
||||||
|
|
||||||
```python sync
|
```python sync
|
||||||
# Initialize clock with a specific time.
|
# Initialize clock with a specific time, only fake Date.now.
|
||||||
page.clock.install(
|
page.clock.install(
|
||||||
now=datetime.datetime(2024, 1, 1, 10, 0, 0, tzinfo=datetime.timezone.utc),
|
now=datetime.datetime(2024, 1, 1, 10, 0, 0, tzinfo=datetime.timezone.utc),
|
||||||
to_fake=['Date'],
|
to_fake=['Date'],
|
||||||
@ -69,7 +75,7 @@ expect(locator).to_have_value('2024-01-01T10:00')
|
|||||||
```
|
```
|
||||||
|
|
||||||
```java
|
```java
|
||||||
// Initialize clock with a specific time.
|
// Initialize clock with a specific time, only fake Date.now.
|
||||||
page.clock().install(
|
page.clock().install(
|
||||||
new Clock.InstallOptions()
|
new Clock.InstallOptions()
|
||||||
.setNow(Instant.parse("2024-01-01T10:00:00Z"))
|
.setNow(Instant.parse("2024-01-01T10:00:00Z"))
|
||||||
@ -81,7 +87,7 @@ assertThat(locator).hasValue("2024-01-01T10:00");
|
|||||||
```
|
```
|
||||||
|
|
||||||
```csharp
|
```csharp
|
||||||
// Initialize clock with a specific time.
|
// Initialize clock with a specific time, only fake Date.now.
|
||||||
await page.Clock.InstallAsync(
|
await page.Clock.InstallAsync(
|
||||||
new ClockInstallOptions
|
new ClockInstallOptions
|
||||||
{
|
{
|
||||||
@ -95,6 +101,9 @@ await Expect(locator).ToHaveValueAsync("2024-01-01T10:00");
|
|||||||
|
|
||||||
## Assert page at different points in time
|
## 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
|
```html
|
||||||
<input type="datetime-local" id="my-time" data-testid="my-time">
|
<input type="datetime-local" id="my-time" data-testid="my-time">
|
||||||
<script>
|
<script>
|
||||||
@ -108,7 +117,7 @@ await Expect(locator).ToHaveValueAsync("2024-01-01T10:00");
|
|||||||
```
|
```
|
||||||
|
|
||||||
```js
|
```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.clock.install({ now: new Date('2024-01-01T10:00:00Z') });
|
||||||
await page.goto('http://localhost:3333');
|
await page.goto('http://localhost:3333');
|
||||||
await expect(page.getByTestId('my-time')).toHaveValue('2024-01-01T10:00');
|
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
|
```python async
|
||||||
# Initialize clock with a specific time.
|
# Initialize clock with a specific time, take full control over time.
|
||||||
await page.clock.install(
|
await page.clock.install(
|
||||||
now=datetime.datetime(2024, 1, 1, 10, 0, 0, tzinfo=datetime.timezone.utc),
|
now=datetime.datetime(2024, 1, 1, 10, 0, 0, tzinfo=datetime.timezone.utc),
|
||||||
toFake=['Date'],
|
|
||||||
)
|
)
|
||||||
await page.goto('http://localhost:3333')
|
await page.goto('http://localhost:3333')
|
||||||
locator = page.get_by_test_id('my-time')
|
locator = page.get_by_test_id('my-time')
|
||||||
@ -136,10 +144,9 @@ await expect(locator).to_have_value('2024-01-01T10:30')
|
|||||||
```
|
```
|
||||||
|
|
||||||
```python sync
|
```python sync
|
||||||
# Initialize clock with a specific time.
|
# Initialize clock with a specific time, take full control over time.
|
||||||
page.clock.install(
|
page.clock.install(
|
||||||
now=datetime.datetime(2024, 1, 1, 10, 0, 0, tzinfo=datetime.timezone.utc),
|
now=datetime.datetime(2024, 1, 1, 10, 0, 0, tzinfo=datetime.timezone.utc),
|
||||||
to_fake=['Date'],
|
|
||||||
)
|
)
|
||||||
page.goto('http://localhost:3333')
|
page.goto('http://localhost:3333')
|
||||||
locator = page.get_by_test_id('my-time')
|
locator = page.get_by_test_id('my-time')
|
||||||
@ -152,11 +159,10 @@ expect(locator).to_have_value('2024-01-01T10:30')
|
|||||||
```
|
```
|
||||||
|
|
||||||
```java
|
```java
|
||||||
// Initialize clock with a specific time.
|
// Initialize clock with a specific time, take full control over time.
|
||||||
page.clock().install(
|
page.clock().install(
|
||||||
new Clock.InstallOptions()
|
new Clock.InstallOptions()
|
||||||
.setNow(Instant.parse("2024-01-01T10:00:00Z"))
|
.setNow(Instant.parse("2024-01-01T10:00:00Z"))
|
||||||
.setToFake(new String[]{"Date"})
|
|
||||||
);
|
);
|
||||||
page.navigate("http://localhost:3333");
|
page.navigate("http://localhost:3333");
|
||||||
Locator locator = page.getByTestId("my-time");
|
Locator locator = page.getByTestId("my-time");
|
||||||
@ -169,12 +175,11 @@ assertThat(locator).hasValue("2024-01-01T10:30");
|
|||||||
```
|
```
|
||||||
|
|
||||||
```csharp
|
```csharp
|
||||||
// Initialize clock with a specific time.
|
// Initialize clock with a specific time, take full control over time.
|
||||||
await page.Clock.InstallAsync(
|
await page.Clock.InstallAsync(
|
||||||
new ClockInstallOptions
|
new ClockInstallOptions
|
||||||
{
|
{
|
||||||
Now = new DateTime(2024, 1, 1, 10, 0, 0, DateTimeKind.Utc),
|
Now = new DateTime(2024, 1, 1, 10, 0, 0, DateTimeKind.Utc),
|
||||||
ToFake = new[] { "Date" }
|
|
||||||
});
|
});
|
||||||
await page.GotoAsync("http://localhost:3333");
|
await page.GotoAsync("http://localhost:3333");
|
||||||
var locator = page.GetByTestId("my-time");
|
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 page.Clock.JumpAsync("30:00");
|
||||||
await Expect(locator).ToHaveValueAsync("2024-01-01T10:30");
|
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);
|
||||||
|
```
|
||||||
|
8
packages/playwright-core/types/types.d.ts
vendored
8
packages/playwright-core/types/types.d.ts
vendored
@ -17239,9 +17239,11 @@ export interface BrowserServer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Playwright uses [@sinonjs/fake-timers](https://github.com/sinonjs/fake-timers) for clock emulation. Clock is
|
* Accurately simulating time-dependent behavior is essential for verifying the correctness of applications. Learn
|
||||||
* installed for the entire {@link BrowserContext}, so the time in all the pages and iframes is controlled by the same
|
* more about [clock emulation](https://playwright.dev/docs/clock).
|
||||||
* 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 {
|
export interface Clock {
|
||||||
/**
|
/**
|
||||||
|
Loading…
x
Reference in New Issue
Block a user