diff --git a/docs/src/api/class-clock.md b/docs/src/api/class-clock.md index bf8b9ac59a487..9099d33a4ff23 100644 --- a/docs/src/api/class-clock.md +++ b/docs/src/api/class-clock.md @@ -45,43 +45,6 @@ await page.Clock.FastForwardAsync("30:00"); Time may be the number of milliseconds to advance the clock by or a human-readable string. Valid string formats are "08" for eight seconds, "01:00" for one minute and "02:34:10" for two hours, 34 minutes and ten seconds. -## async method: Clock.fastForwardTo -* since: v1.45 - -Advance the clock by jumping forward in time. Only fires due timers at most once. This is equivalent to user closing the laptop lid for a while and -reopening it at the specified time. - -**Usage** - -```js -await page.clock.fastForwardTo(new Date('2020-02-02')); -await page.clock.fastForwardTo('2020-02-02'); -``` - -```python async -await page.clock.fast_forward_to(datetime.datetime(2020, 2, 2)) -await page.clock.fast_forward_to("2020-02-02") -``` - -```python sync -page.clock.fast_forward_to(datetime.datetime(2020, 2, 2)) -page.clock.fast_forward_to("2020-02-02") -``` - -```java -page.clock().fastForwardTo(Instant.parse("2020-02-02")); -page.clock().fastForwardTo("2020-02-02"); -``` - -```csharp -await page.Clock.FastForwardToAsync(DateTime.Parse("2020-02-02")); -await page.Clock.FastForwardToAsync("2020-02-02"); -``` - -### param: Clock.fastForwardTo.time -* since: v1.45 -- `time` <[int]|[string]|[Date]> - ## async method: Clock.install * since: v1.45 @@ -145,10 +108,47 @@ await page.Clock.RunForAsync("30:00"); Time may be the number of milliseconds to advance the clock by or a human-readable string. Valid string formats are "08" for eight seconds, "01:00" for one minute and "02:34:10" for two hours, 34 minutes and ten seconds. -## async method: Clock.pause +## async method: Clock.pauseAt * since: v1.45 -Pause timers. Once this method is called, no timers are fired unless [`method: Clock.runFor`], [`method: Clock.fastForward`], [`method: Clock.fastForwardTo`] or [`method: Clock.resume`] is called. +Advance the clock by jumping forward in time and pause the time. Once this method is called, no timers +are fired unless [`method: Clock.runFor`], [`method: Clock.fastForward`], [`method: Clock.pauseAt`] or [`method: Clock.resume`] is called. + +Only fires due timers at most once. +This is equivalent to user closing the laptop lid for a while and reopening it at the specified time and +pausing. + +**Usage** + +```js +await page.clock.pauseAt(new Date('2020-02-02')); +await page.clock.pauseAt('2020-02-02'); +``` + +```python async +await page.clock.pause_at(datetime.datetime(2020, 2, 2)) +await page.clock.pause_at("2020-02-02") +``` + +```python sync +page.clock.pause_at(datetime.datetime(2020, 2, 2)) +page.clock.pause_at("2020-02-02") +``` + +```java +page.clock().pauseAt(Instant.parse("2020-02-02")); +page.clock().pauseAt("2020-02-02"); +``` + +```csharp +await page.Clock.PauseAtAsync(DateTime.Parse("2020-02-02")); +await page.Clock.PauseAtAsync("2020-02-02"); +``` + +### param: Clock.pauseAt.time +* since: v1.45 +- `time` <[int]|[string]|[Date]> + ## async method: Clock.resume * since: v1.45 @@ -202,7 +202,7 @@ Time to be set. ## async method: Clock.setSystemTime * since: v1.45 -Sets current system time but does not trigger any timers, unlike [`method: Clock.fastForwardTo`]. +Sets current system time but does not trigger any timers. **Usage** diff --git a/docs/src/clock.md b/docs/src/clock.md index 82fba434ec5b3..b89dfd93d6cf1 100644 --- a/docs/src/clock.md +++ b/docs/src/clock.md @@ -67,10 +67,9 @@ In this case, you can install the clock and fast forward to the time of interest await page.clock.install({ time: new Date('2024-02-02T08:00:00') }); await page.goto('http://localhost:3333'); -// Take control over time flow. -await page.clock.pause(); -// Pretend that the user closed the laptop lid and opened it again at 10am. -await page.clock.fastForwardTo(new Date('2024-02-02T10:00:00')); +// Pretend that the user closed the laptop lid and opened it again at 10am, +// Pause the time once reached that point. +await page.clock.pauseAt(new Date('2024-02-02T10:00:00')); // Assert the page state. await expect(page.getByTestId('current-time')).toHaveText('2/2/2024, 10:00:00 AM'); @@ -86,10 +85,9 @@ await expect(page.getByTestId('current-time')).toHaveText('2/2/2024, 10:30:00 AM await page.clock.install(time=datetime.datetime(2024, 2, 2, 8, 0, 0)) await page.goto("http://localhost:3333") -# Take control over time flow. -await page.clock.pause() # Pretend that the user closed the laptop lid and opened it again at 10am. -await page.clock.fast_forward_to(datetime.datetime(2024, 2, 2, 10, 0, 0)) +# Pause the time once reached that point. +await page.clock.pause_at(datetime.datetime(2024, 2, 2, 10, 0, 0)) # Assert the page state. await expect(page.get_by_test_id("current-time")).to_have_text("2/2/2024, 10:00:00 AM") @@ -105,10 +103,9 @@ await expect(page.get_by_test_id("current-time")).to_have_text("2/2/2024, 10:30: page.clock.install(time=datetime.datetime(2024, 2, 2, 8, 0, 0)) page.goto("http://localhost:3333") -# Take control over time flow. -page.clock.pause() # Pretend that the user closed the laptop lid and opened it again at 10am. -page.clock.fast_forward_to(datetime.datetime(2024, 2, 2, 10, 0, 0)) +# Pause the time once reached that point. +page.clock.pause_at(datetime.datetime(2024, 2, 2, 10, 0, 0)) # Assert the page state. expect(page.get_by_test_id("current-time")).to_have_text("2/2/2024, 10:00:00 AM") @@ -125,10 +122,9 @@ page.clock().install(new Clock.InstallOptions().setTime(Instant.parse("2024-02-0 page.navigate("http://localhost:3333"); Locator locator = page.getByTestId("current-time"); -// Take control over time flow. -page.clock().pause(); // Pretend that the user closed the laptop lid and opened it again at 10am. -page.clock().fastForwardTo(Instant.parse("2024-02-02T10:00:00")); +// Pause the time once reached that point. +page.clock().pauseAt(Instant.parse("2024-02-02T10:00:00")); // Assert the page state. assertThat(locator).hasText("2/2/2024, 10:00:00 AM"); @@ -147,10 +143,9 @@ await Page.Clock.InstallAsync(new }); await Page.GotoAsync("http://localhost:3333"); -// Take control over time flow. -await Page.Clock.PauseAsync(); // Pretend that the user closed the laptop lid and opened it again at 10am. -await Page.Clock.FastForwardToAsync(new DateTime(2024, 2, 2, 10, 0, 0)); +// Pause the time once reached that point. +await Page.Clock.PauseAtAsync(new DateTime(2024, 2, 2, 10, 0, 0)); // Assert the page state. await Expect(Page.GetByTestId("current-time")).ToHaveText("2/2/2024, 10:00:00 AM"); @@ -272,8 +267,7 @@ await page.goto('http://localhost:3333'); // Pause the time flow, stop the timers, you now have manual control // over the page time. -await page.clock.pause(); -await page.clock.fastForwardTo(new Date('2024-02-02T10:00:00')); +await page.clock.pauseAt(new Date('2024-02-02T10:00:00')); await expect(page.getByTestId('current-time')).toHaveText('2/2/2024, 10:00:00 AM'); // Tick through time manually, firing all timers in the process. @@ -292,8 +286,7 @@ locator = page.get_by_test_id("current-time") # Pause the time flow, stop the timers, you now have manual control # over the page time. -await page.clock.pause() -await page.clock.fast_forward_to(datetime.datetime(2024, 2, 2, 10, 0, 0)) +await page.clock.pause_at(datetime.datetime(2024, 2, 2, 10, 0, 0)) await expect(locator).to_have_text("2/2/2024, 10:00:00 AM") # Tick through time manually, firing all timers in the process. @@ -312,8 +305,7 @@ locator = page.get_by_test_id("current-time") # Pause the time flow, stop the timers, you now have manual control # over the page time. -page.clock.pause() -page.clock.fast_forward_to(datetime.datetime(2024, 2, 2, 10, 0, 0)) +page.clock.pause_at(datetime.datetime(2024, 2, 2, 10, 0, 0)) expect(locator).to_have_text("2/2/2024, 10:00:00 AM") # Tick through time manually, firing all timers in the process. @@ -331,8 +323,7 @@ Locator locator = page.getByTestId("current-time"); // Pause the time flow, stop the timers, you now have manual control // over the page time. -page.clock().pause(); -page.clock().fastForwardTo(Instant.parse("2024-02-02T10:00:00")); +page.clock().pauseAt(Instant.parse("2024-02-02T10:00:00")); assertThat(locator).hasText("2/2/2024, 10:00:00 AM"); // Tick through time manually, firing all timers in the process. @@ -352,8 +343,7 @@ var locator = page.GetByTestId("current-time"); // Pause the time flow, stop the timers, you now have manual control // over the page time. -await Page.Clock.PauseAsync(); -await Page.Clock.FastForwardToAsync(new DateTime(2024, 2, 2, 10, 0, 0)); +await Page.Clock.PauseAtAsync(new DateTime(2024, 2, 2, 10, 0, 0)); await Expect(locator).ToHaveTextAsync("2/2/2024, 10:00:00 AM"); // Tick through time manually, firing all timers in the process. diff --git a/packages/playwright-core/src/client/browser.ts b/packages/playwright-core/src/client/browser.ts index c1a9b0259dedf..b6f55e3b29fa9 100644 --- a/packages/playwright-core/src/client/browser.ts +++ b/packages/playwright-core/src/client/browser.ts @@ -88,7 +88,7 @@ export class Browser extends ChannelOwner implements ap if (!forReuse && !!process.env.PW_FREEZE_TIME) { await this._wrapApiCall(async () => { await context.clock.install({ time: 0 }); - await context.clock.pause(); + await context.clock.pauseAt(1000); }, true); } return context; diff --git a/packages/playwright-core/src/client/clock.ts b/packages/playwright-core/src/client/clock.ts index f4d2133b40353..32faa7a4d4f2e 100644 --- a/packages/playwright-core/src/client/clock.ts +++ b/packages/playwright-core/src/client/clock.ts @@ -32,12 +32,8 @@ export class Clock implements api.Clock { await this._browserContext._channel.clockFastForward(parseTicks(ticks)); } - async fastForwardTo(time: number | string | Date) { - await this._browserContext._channel.clockFastForwardTo(parseTime(time)); - } - - async pause() { - await this._browserContext._channel.clockPause({}); + async pauseAt(time: number | string | Date) { + await this._browserContext._channel.clockPauseAt(parseTime(time)); } async resume() { diff --git a/packages/playwright-core/src/protocol/validator.ts b/packages/playwright-core/src/protocol/validator.ts index 169b7574df22a..9f5af4ed72595 100644 --- a/packages/playwright-core/src/protocol/validator.ts +++ b/packages/playwright-core/src/protocol/validator.ts @@ -968,18 +968,16 @@ scheme.BrowserContextClockFastForwardParams = tObject({ ticksString: tOptional(tString), }); scheme.BrowserContextClockFastForwardResult = tOptional(tObject({})); -scheme.BrowserContextClockFastForwardToParams = tObject({ +scheme.BrowserContextClockInstallParams = tObject({ timeNumber: tOptional(tNumber), timeString: tOptional(tString), }); -scheme.BrowserContextClockFastForwardToResult = tOptional(tObject({})); -scheme.BrowserContextClockInstallParams = tObject({ +scheme.BrowserContextClockInstallResult = tOptional(tObject({})); +scheme.BrowserContextClockPauseAtParams = tObject({ timeNumber: tOptional(tNumber), timeString: tOptional(tString), }); -scheme.BrowserContextClockInstallResult = tOptional(tObject({})); -scheme.BrowserContextClockPauseParams = tOptional(tObject({})); -scheme.BrowserContextClockPauseResult = tOptional(tObject({})); +scheme.BrowserContextClockPauseAtResult = tOptional(tObject({})); scheme.BrowserContextClockResumeParams = tOptional(tObject({})); scheme.BrowserContextClockResumeResult = tOptional(tObject({})); scheme.BrowserContextClockRunForParams = tObject({ diff --git a/packages/playwright-core/src/server/clock.ts b/packages/playwright-core/src/server/clock.ts index 3cbb0b1b0a715..58a1f7272038e 100644 --- a/packages/playwright-core/src/server/clock.ts +++ b/packages/playwright-core/src/server/clock.ts @@ -33,13 +33,6 @@ export class Clock { await this._evaluateInFrames(`globalThis.__pwClock.controller.fastForward(${ticksMillis})`); } - async fastForwardTo(ticks: number | string) { - await this._installIfNeeded(); - const timeMillis = parseTime(ticks); - await this._browserContext.addInitScript(`globalThis.__pwClock.controller.log('fastForwardTo', ${Date.now()}, ${timeMillis})`); - await this._evaluateInFrames(`globalThis.__pwClock.controller.fastForwardTo(${timeMillis})`); - } - async install(time: number | string | undefined) { await this._installIfNeeded(); const timeMillis = time !== undefined ? parseTime(time) : Date.now(); @@ -47,10 +40,11 @@ export class Clock { await this._evaluateInFrames(`globalThis.__pwClock.controller.install(${timeMillis})`); } - async pause() { + async pauseAt(ticks: number | string) { await this._installIfNeeded(); - await this._browserContext.addInitScript(`globalThis.__pwClock.controller.log('pause', ${Date.now()})`); - await this._evaluateInFrames(`globalThis.__pwClock.controller.pause()`); + const timeMillis = parseTime(ticks); + await this._browserContext.addInitScript(`globalThis.__pwClock.controller.log('pauseAt', ${Date.now()}, ${timeMillis})`); + await this._evaluateInFrames(`globalThis.__pwClock.controller.pauseAt(${timeMillis})`); } async resume() { diff --git a/packages/playwright-core/src/server/dispatchers/browserContextDispatcher.ts b/packages/playwright-core/src/server/dispatchers/browserContextDispatcher.ts index 86b9a5576c2d0..585cf1d20be82 100644 --- a/packages/playwright-core/src/server/dispatchers/browserContextDispatcher.ts +++ b/packages/playwright-core/src/server/dispatchers/browserContextDispatcher.ts @@ -316,16 +316,12 @@ export class BrowserContextDispatcher extends Dispatcher { - await this._context.clock.fastForwardTo(params.timeString ?? params.timeNumber ?? 0); - } - async clockInstall(params: channels.BrowserContextClockInstallParams, metadata?: CallMetadata | undefined): Promise { await this._context.clock.install(params.timeString ?? params.timeNumber ?? undefined); } - async clockPause(params: channels.BrowserContextClockPauseParams, metadata?: CallMetadata | undefined): Promise { - await this._context.clock.pause(); + async clockPauseAt(params: channels.BrowserContextClockPauseAtParams, metadata?: CallMetadata | undefined): Promise { + await this._context.clock.pauseAt(params.timeString ?? params.timeNumber ?? 0); } async clockResume(params: channels.BrowserContextClockResumeParams, metadata?: CallMetadata | undefined): Promise { diff --git a/packages/playwright-core/src/server/injected/clock.ts b/packages/playwright-core/src/server/injected/clock.ts index 5f6d4cf613b63..5b8abd3271d35 100644 --- a/packages/playwright-core/src/server/injected/clock.ts +++ b/packages/playwright-core/src/server/injected/clock.ts @@ -69,7 +69,7 @@ type Time = { origin: number; }; -type LogEntryType = 'fastForward' | 'fastForwardTo' | 'install' | 'pause' | 'resume' | 'runFor' | 'setFixedTime' | 'setSystemTime'; +type LogEntryType = 'fastForward' |'install' | 'pauseAt' | 'resume' | 'runFor' | 'setFixedTime' | 'setSystemTime'; export class ClockController { readonly _now: Time; @@ -163,9 +163,10 @@ export class ClockController { throw firstException; } - pause() { + async pauseAt(time: number) { this._replayLogOnce(); this._innerPause(); + await this._innerFastForwardTo(time); } private _innerPause() { @@ -218,18 +219,18 @@ export class ClockController { async fastForward(ticks: number) { this._replayLogOnce(); - const ms = ticks | 0; - for (const timer of this._timers.values()) { - if (this._now.ticks + ms > timer.callAt) - timer.callAt = this._now.ticks + ms; - } - await this.runFor(ms); + await this._innerFastForwardTo(this._now.ticks + ticks | 0); } - async fastForwardTo(time: number) { - this._replayLogOnce(); - const ticks = time - this._now.time; - await this.fastForward(ticks); + + private async _innerFastForwardTo(toTicks: number) { + if (toTicks < this._now.ticks) + throw new Error('Cannot fast-forward to the past'); + for (const timer of this._timers.values()) { + if (toTicks > timer.callAt) + timer.callAt = toTicks; + } + await this._runTo(toTicks); } addTimer(options: { func: TimerHandler, type: TimerType, delay?: number | string, args?: any[] }): number { @@ -381,11 +382,10 @@ export class ClockController { this._innerSetTime(param!); } else if (type === 'fastForward' || type === 'runFor') { this._advanceNow(this._now.ticks + param!); - } else if (type === 'fastForwardTo') { - this._innerSetTime(param!); - } else if (type === 'pause') { - this._innerPause(); + } else if (type === 'pauseAt') { isPaused = true; + this._innerPause(); + this._innerSetTime(param!); } else if (type === 'resume') { this._innerResume(); isPaused = false; diff --git a/packages/playwright-core/types/types.d.ts b/packages/playwright-core/types/types.d.ts index 7fe30e2ef2bbf..76d12b2d9aa38 100644 --- a/packages/playwright-core/types/types.d.ts +++ b/packages/playwright-core/types/types.d.ts @@ -17263,21 +17263,6 @@ export interface Clock { */ fastForward(ticks: number|string): Promise; - /** - * Advance the clock by jumping forward in time. Only fires due timers at most once. This is equivalent to user - * closing the laptop lid for a while and reopening it at the specified time. - * - * **Usage** - * - * ```js - * await page.clock.fastForwardTo(new Date('2020-02-02')); - * await page.clock.fastForwardTo('2020-02-02'); - * ``` - * - * @param time - */ - fastForwardTo(time: number|string|Date): Promise; - /** * Install fake implementations for the following time-related functions: * - `Date` @@ -17305,13 +17290,25 @@ export interface Clock { }): Promise; /** - * Pause timers. Once this method is called, no timers are fired unless - * [clock.runFor(ticks)](https://playwright.dev/docs/api/class-clock#clock-run-for), + * Advance the clock by jumping forward in time and pause the time. Once this method is called, no timers are fired + * unless [clock.runFor(ticks)](https://playwright.dev/docs/api/class-clock#clock-run-for), * [clock.fastForward(ticks)](https://playwright.dev/docs/api/class-clock#clock-fast-forward), - * [clock.fastForwardTo(time)](https://playwright.dev/docs/api/class-clock#clock-fast-forward-to) or + * [clock.pauseAt(time)](https://playwright.dev/docs/api/class-clock#clock-pause-at) or * [clock.resume()](https://playwright.dev/docs/api/class-clock#clock-resume) is called. + * + * Only fires due timers at most once. This is equivalent to user closing the laptop lid for a while and reopening it + * at the specified time and pausing. + * + * **Usage** + * + * ```js + * await page.clock.pauseAt(new Date('2020-02-02')); + * await page.clock.pauseAt('2020-02-02'); + * ``` + * + * @param time */ - pause(): Promise; + pauseAt(time: number|string|Date): Promise; /** * Resumes timers. Once this method is called, time resumes flowing, timers are fired as usual. @@ -17349,8 +17346,7 @@ export interface Clock { setFixedTime(time: number|string|Date): Promise; /** - * Sets current system time but does not trigger any timers, unlike - * [clock.fastForwardTo(time)](https://playwright.dev/docs/api/class-clock#clock-fast-forward-to). + * Sets current system time but does not trigger any timers. * * **Usage** * diff --git a/packages/protocol/src/channels.ts b/packages/protocol/src/channels.ts index 85bd3a8ffab90..2ddeeee8377e8 100644 --- a/packages/protocol/src/channels.ts +++ b/packages/protocol/src/channels.ts @@ -1461,9 +1461,8 @@ export interface BrowserContextChannel extends BrowserContextEventTarget, EventT createTempFile(params: BrowserContextCreateTempFileParams, metadata?: CallMetadata): Promise; updateSubscription(params: BrowserContextUpdateSubscriptionParams, metadata?: CallMetadata): Promise; clockFastForward(params: BrowserContextClockFastForwardParams, metadata?: CallMetadata): Promise; - clockFastForwardTo(params: BrowserContextClockFastForwardToParams, metadata?: CallMetadata): Promise; clockInstall(params: BrowserContextClockInstallParams, metadata?: CallMetadata): Promise; - clockPause(params?: BrowserContextClockPauseParams, metadata?: CallMetadata): Promise; + clockPauseAt(params: BrowserContextClockPauseAtParams, metadata?: CallMetadata): Promise; clockResume(params?: BrowserContextClockResumeParams, metadata?: CallMetadata): Promise; clockRunFor(params: BrowserContextClockRunForParams, metadata?: CallMetadata): Promise; clockSetFixedTime(params: BrowserContextClockSetFixedTimeParams, metadata?: CallMetadata): Promise; @@ -1765,27 +1764,24 @@ export type BrowserContextClockFastForwardOptions = { ticksString?: string, }; export type BrowserContextClockFastForwardResult = void; -export type BrowserContextClockFastForwardToParams = { +export type BrowserContextClockInstallParams = { timeNumber?: number, timeString?: string, }; -export type BrowserContextClockFastForwardToOptions = { +export type BrowserContextClockInstallOptions = { timeNumber?: number, timeString?: string, }; -export type BrowserContextClockFastForwardToResult = void; -export type BrowserContextClockInstallParams = { +export type BrowserContextClockInstallResult = void; +export type BrowserContextClockPauseAtParams = { timeNumber?: number, timeString?: string, }; -export type BrowserContextClockInstallOptions = { +export type BrowserContextClockPauseAtOptions = { timeNumber?: number, timeString?: string, }; -export type BrowserContextClockInstallResult = void; -export type BrowserContextClockPauseParams = {}; -export type BrowserContextClockPauseOptions = {}; -export type BrowserContextClockPauseResult = void; +export type BrowserContextClockPauseAtResult = void; export type BrowserContextClockResumeParams = {}; export type BrowserContextClockResumeOptions = {}; export type BrowserContextClockResumeResult = void; diff --git a/packages/protocol/src/protocol.yml b/packages/protocol/src/protocol.yml index 65fc2db4de668..f02045d51ea4f 100644 --- a/packages/protocol/src/protocol.yml +++ b/packages/protocol/src/protocol.yml @@ -1209,18 +1209,16 @@ BrowserContext: ticksNumber: number? ticksString: string? - clockFastForwardTo: + clockInstall: parameters: timeNumber: number? timeString: string? - clockInstall: + clockPauseAt: parameters: timeNumber: number? timeString: string? - clockPause: - clockResume: clockRunFor: diff --git a/tests/library/clock.spec.ts b/tests/library/clock.spec.ts index a77356c17215b..da82f2d960682 100644 --- a/tests/library/clock.spec.ts +++ b/tests/library/clock.spec.ts @@ -1342,10 +1342,11 @@ it.describe('fastForward', () => { clock.setInterval(shortTimers[1], 100); clock.requestAnimationFrame(shortTimers[2]); await clock.fastForward(1500); - for (const stub of longTimers) - expect(stub.called).toBeFalsy(); - for (const stub of shortTimers) - expect(stub.callCount).toBe(1); + expect(longTimers[0].called).toBeFalsy(); + expect(longTimers[1].called).toBeFalsy(); + expect(shortTimers[0].callCount).toBe(1); + expect(shortTimers[1].callCount).toBe(1); + expect(shortTimers[2].callCount).toBe(1); }); }); diff --git a/tests/page/page-clock.spec.ts b/tests/page/page-clock.spec.ts index fdc01c55705f6..58a0d130e2586 100644 --- a/tests/page/page-clock.spec.ts +++ b/tests/page/page-clock.spec.ts @@ -36,8 +36,8 @@ const it = test.extend<{ calls: { params: any[] }[] }>({ it.describe('runFor', () => { it.beforeEach(async ({ page }) => { - await page.clock.install(); - await page.clock.pause(); + await page.clock.install({ time: 0 }); + await page.clock.pauseAt(1000); }); it('triggers immediately without specified delay', async ({ page, calls }) => { @@ -171,9 +171,8 @@ it.describe('runFor', () => { it.describe('fastForward', () => { it.beforeEach(async ({ page }) => { - await page.clock.install(); - await page.clock.pause(); - await page.clock.setSystemTime(0); + await page.clock.install({ time: 0 }); + await page.clock.pauseAt(1000); }); it(`ignores timers which wouldn't be run`, async ({ page, calls }) => { @@ -194,7 +193,7 @@ it.describe('fastForward', () => { }); await page.clock.fastForward(2000); - expect(calls).toEqual([{ params: [2000] }]); + expect(calls).toEqual([{ params: [1000 + 2000] }]); }); it('supports string time arguments', async ({ page, calls }) => { @@ -204,15 +203,14 @@ it.describe('fastForward', () => { }, 100000); // 100000 = 1:40 }); await page.clock.fastForward('01:50'); - expect(calls).toEqual([{ params: [110000] }]); + expect(calls).toEqual([{ params: [1000 + 110000] }]); }); }); it.describe('fastForwardTo', () => { it.beforeEach(async ({ page }) => { - await page.clock.install(); - await page.clock.pause(); - await page.clock.setSystemTime(0); + await page.clock.install({ time: 0 }); + await page.clock.pauseAt(1000); }); it(`ignores timers which wouldn't be run`, async ({ page, calls }) => { @@ -221,7 +219,7 @@ it.describe('fastForwardTo', () => { window.stub('should not be logged'); }, 1000); }); - await page.clock.fastForwardTo(500); + await page.clock.fastForward(500); expect(calls).toEqual([]); }); @@ -232,16 +230,15 @@ it.describe('fastForwardTo', () => { }, 1000); }); - await page.clock.fastForwardTo(2000); - expect(calls).toEqual([{ params: [2000] }]); + await page.clock.fastForward(2000); + expect(calls).toEqual([{ params: [1000 + 2000] }]); }); }); it.describe('stubTimers', () => { it.beforeEach(async ({ page }) => { - await page.clock.install(); - await page.clock.pause(); - await page.clock.setSystemTime(0); + await page.clock.install({ time: 0 }); + await page.clock.pauseAt(1000); }); it('sets initial timestamp', async ({ page, calls }) => { await page.clock.setSystemTime(1400); @@ -295,20 +292,19 @@ it.describe('stubTimers', () => { return { prev, next }; }); await page.clock.runFor(1000); - expect(await promise).toEqual({ prev: 0, next: 1000 }); + expect(await promise).toEqual({ prev: 1000, next: 2000 }); }); it('fakes Date constructor', async ({ page }) => { const now = await page.evaluate(() => new Date().getTime()); - expect(now).toBe(0); + expect(now).toBe(1000); }); }); it.describe('stubTimers', () => { it('replaces global performance.timeOrigin', async ({ page }) => { await page.clock.install({ time: 1000 }); - await page.clock.pause(); - await page.clock.setSystemTime(1000); + await page.clock.pauseAt(2000); const promise = page.evaluate(async () => { const prev = performance.now(); await new Promise(f => setTimeout(f, 1000)); @@ -317,16 +313,15 @@ it.describe('stubTimers', () => { }); await page.clock.runFor(1000); expect(await page.evaluate(() => performance.timeOrigin)).toBe(1000); - expect(await promise).toEqual({ prev: 0, next: 1000 }); + expect(await promise).toEqual({ prev: 2000, next: 3000 }); }); }); it.describe('popup', () => { it('should tick after popup', async ({ page }) => { await page.clock.install(); - await page.clock.pause(); const now = new Date('2015-09-25'); - await page.clock.setSystemTime(now); + await page.clock.pauseAt(now); const [popup] = await Promise.all([ page.waitForEvent('popup'), page.evaluate(() => window.open('about:blank')), @@ -340,9 +335,8 @@ it.describe('popup', () => { it('should tick before popup', async ({ page }) => { await page.clock.install(); - await page.clock.pause(); const now = new Date('2015-09-25'); - await page.clock.setSystemTime(now); + await page.clock.pauseAt(now); await page.clock.runFor(1000); const [popup] = await Promise.all([ @@ -358,7 +352,6 @@ it.describe('popup', () => { res.setHeader('Content-Type', 'text/html'); res.end(``); }); - await page.clock.setSystemTime(0); await page.goto(server.EMPTY_PAGE); // Wait for 2 second in real life to check that it is past in popup. await page.waitForTimeout(2000); @@ -376,8 +369,7 @@ it.describe('popup', () => { res.end(``); }); await page.clock.install(); - await page.clock.pause(); - await page.clock.setSystemTime(0); + await page.clock.pauseAt(1000); await page.goto(server.EMPTY_PAGE); // Wait for 2 second in real life to check that it is past in popup. await page.waitForTimeout(2000); @@ -386,7 +378,7 @@ it.describe('popup', () => { page.evaluate(url => window.open(url), server.PREFIX + '/popup.html'), ]); const popupTime = await popup.evaluate('time'); - expect(popupTime).toBe(0); + expect(popupTime).toBe(1000); }); }); @@ -457,7 +449,7 @@ it.describe('while running', () => { it('should fastForwardTo', async ({ page }) => { await page.clock.install({ time: 0 }); await page.goto('data:text/html,'); - await page.clock.fastForwardTo(10000); + await page.clock.fastForward(10000); const now = await page.evaluate(() => Date.now()); expect(now).toBeGreaterThanOrEqual(10000); expect(now).toBeLessThanOrEqual(11000); @@ -466,7 +458,7 @@ it.describe('while running', () => { it('should pause', async ({ page }) => { await page.clock.install({ time: 0 }); await page.goto('data:text/html,'); - await page.clock.pause(); + await page.clock.pauseAt(1000); await page.waitForTimeout(1000); await page.clock.resume(); const now = await page.evaluate(() => Date.now()); @@ -474,20 +466,19 @@ it.describe('while running', () => { expect(now).toBeLessThanOrEqual(1000); }); - it('should pause and fastForwardTo', async ({ page }) => { + it('should pause and fastForward', async ({ page }) => { await page.clock.install({ time: 0 }); await page.goto('data:text/html,'); - await page.clock.pause(); - await page.clock.fastForwardTo(1000); + await page.clock.pauseAt(1000); + await page.clock.fastForward(1000); const now = await page.evaluate(() => Date.now()); - expect(now).toBe(1000); + expect(now).toBe(2000); }); it('should set system time on pause', async ({ page }) => { - await page.clock.install(); + await page.clock.install({ time: 0 }); await page.goto('data:text/html,'); - await page.clock.pause(); - await page.clock.setSystemTime(1000); + await page.clock.pauseAt(1000); const now = await page.evaluate(() => Date.now()); expect(now).toBe(1000); }); @@ -495,9 +486,9 @@ it.describe('while running', () => { it.describe('while on pause', () => { it('fastForward should not run nested immediate', async ({ page, calls }) => { - await page.clock.install(); + await page.clock.install({ time: 0 }); await page.goto('data:text/html,'); - await page.clock.pause(); + await page.clock.pauseAt(1000); await page.evaluate(() => { setTimeout(() => { window.stub('outer'); @@ -511,9 +502,9 @@ it.describe('while on pause', () => { }); it('runFor should not run nested immediate', async ({ page, calls }) => { - await page.clock.install(); + await page.clock.install({ time: 0 }); await page.goto('data:text/html,'); - await page.clock.pause(); + await page.clock.pauseAt(1000); await page.evaluate(() => { setTimeout(() => { window.stub('outer'); @@ -527,9 +518,9 @@ it.describe('while on pause', () => { }); it('runFor should not run nested immediate from microtask', async ({ page, calls }) => { - await page.clock.install(); + await page.clock.install({ time: 0 }); await page.goto('data:text/html,'); - await page.clock.pause(); + await page.clock.pauseAt(1000); await page.evaluate(() => { setTimeout(() => { window.stub('outer');