diff --git a/playwright/src/main/java/com/microsoft/playwright/Clock.java b/playwright/src/main/java/com/microsoft/playwright/Clock.java index bab0a7f65..9641c055b 100644 --- a/playwright/src/main/java/com/microsoft/playwright/Clock.java +++ b/playwright/src/main/java/com/microsoft/playwright/Clock.java @@ -17,6 +17,7 @@ package com.microsoft.playwright; import java.util.Date; +import java.time.Instant; /** * Accurately simulating time-dependent behavior is essential for verifying the correctness of applications. Learn more @@ -53,6 +54,13 @@ public InstallOptions setTime(Date time) { this.time = time; return this; } + /** + * Time to initialize with, current system time by default. + */ + public InstallOptions setTime(Instant time) { + this.time = time; + return this; + } } /** * Advance the clock by jumping forward in time. Only fires due timers at most once. This is equivalent to user closing the @@ -257,6 +265,39 @@ default void install() { * @since v1.45 */ void pauseAt(Date time); + /** + * Advance the clock by jumping forward in time and pause the time. Once this method is called, no timers are fired unless + * {@link com.microsoft.playwright.Clock#runFor Clock.runFor()}, {@link com.microsoft.playwright.Clock#fastForward + * Clock.fastForward()}, {@link com.microsoft.playwright.Clock#pauseAt Clock.pauseAt()} or {@link + * com.microsoft.playwright.Clock#resume 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 + *
{@code
+ * SimpleDateFormat format = new SimpleDateFormat("yyy-MM-dd");
+ * page.clock().pauseAt(format.parse("2020-02-02"));
+ * page.clock().pauseAt("2020-02-02");
+ * }
+ *
+ * For best results, install the clock before navigating the page and set it to a time slightly before the intended test + * time. This ensures that all timers run normally during page loading, preventing the page from getting stuck. Once the + * page has fully loaded, you can safely use {@link com.microsoft.playwright.Clock#pauseAt Clock.pauseAt()} to pause the + * clock. + *
{@code
+ * // Initialize clock with some time before the test time and let the page load
+ * // naturally. `Date.now` will progress as the timers fire.
+ * SimpleDateFormat format = new SimpleDateFormat("yyy-MM-dd'T'HH:mm:ss");
+ * page.clock().install(new Clock.InstallOptions().setTime(format.parse("2024-12-10T08:00:00")));
+ * page.navigate("http://localhost:3333");
+ * page.clock().pauseAt(format.parse("2024-12-10T10:00:00"));
+ * }
+ *
+ * @param time Time to pause at.
+ * @since v1.45
+ */
+ void pauseAt(Instant time);
/**
* Resumes timers. Once this method is called, time resumes flowing, timers are fired as usual.
*
@@ -317,6 +358,24 @@ default void install() {
* @since v1.45
*/
void setFixedTime(Date time);
+ /**
+ * Makes {@code Date.now} and {@code new Date()} return fixed fake time at all times, keeps all the timers running.
+ *
+ * Use this method for simple scenarios where you only need to test with a predefined time. For more advanced scenarios, + * use {@link com.microsoft.playwright.Clock#install Clock.install()} instead. Read docs on clock emulation to learn more. + * + *
Usage + *
{@code
+ * page.clock().setFixedTime(new Date());
+ * page.clock().setFixedTime(new SimpleDateFormat("yyy-MM-dd").parse("2020-02-02"));
+ * page.clock().setFixedTime("2020-02-02");
+ * }
+ *
+ * @param time Time to be set in milliseconds.
+ * @since v1.45
+ */
+ void setFixedTime(Instant time);
/**
* Sets system time, but does not trigger any timers. Use this to test how the web page reacts to a time shift, for example
* switching from summer to winter time, or changing time zones.
@@ -362,5 +421,20 @@ default void install() {
* @since v1.45
*/
void setSystemTime(Date time);
+ /**
+ * Sets system time, but does not trigger any timers. Use this to test how the web page reacts to a time shift, for example
+ * switching from summer to winter time, or changing time zones.
+ *
+ * Usage + *
{@code
+ * page.clock().setSystemTime(new Date());
+ * page.clock().setSystemTime(new SimpleDateFormat("yyy-MM-dd").parse("2020-02-02"));
+ * page.clock().setSystemTime("2020-02-02");
+ * }
+ *
+ * @param time Time to be set in milliseconds.
+ * @since v1.45
+ */
+ void setSystemTime(Instant time);
}
diff --git a/playwright/src/main/java/com/microsoft/playwright/impl/ClockImpl.java b/playwright/src/main/java/com/microsoft/playwright/impl/ClockImpl.java
index 67d506cd3..4bc8687db 100644
--- a/playwright/src/main/java/com/microsoft/playwright/impl/ClockImpl.java
+++ b/playwright/src/main/java/com/microsoft/playwright/impl/ClockImpl.java
@@ -3,6 +3,7 @@
import com.google.gson.JsonObject;
import com.microsoft.playwright.Clock;
+import java.time.Instant;
import java.util.Date;
import static com.microsoft.playwright.impl.ChannelOwner.NO_TIMEOUT;
@@ -72,9 +73,12 @@ public void pauseAt(String time) {
@Override
public void pauseAt(Date time) {
- JsonObject params = new JsonObject();
- params.addProperty("timeNumber", time.getTime());
- sendMessageWithLogging("pauseAt", params);
+ pauseAt(time.getTime());
+ }
+
+ @Override
+ public void pauseAt(Instant time) {
+ pauseAt(time.toEpochMilli());
}
@Override
@@ -98,9 +102,12 @@ public void setFixedTime(String time) {
@Override
public void setFixedTime(Date time) {
- JsonObject params = new JsonObject();
- params.addProperty("timeNumber", time.getTime());
- sendMessageWithLogging("setFixedTime", params);
+ setFixedTime(time.getTime());
+ }
+
+ @Override
+ public void setFixedTime(Instant time) {
+ setFixedTime(time.toEpochMilli());
}
@Override
@@ -119,9 +126,12 @@ public void setSystemTime(String time) {
@Override
public void setSystemTime(Date time) {
- JsonObject params = new JsonObject();
- params.addProperty("timeNumber", time.getTime());
- sendMessageWithLogging("setSystemTime", params);
+ setSystemTime(time.getTime());
+ }
+
+ @Override
+ public void setSystemTime(Instant time) {
+ setSystemTime(time.toEpochMilli());
}
private static void parseTime(Object time, JsonObject params) {
@@ -129,6 +139,8 @@ private static void parseTime(Object time, JsonObject params) {
params.addProperty("timeNumber", (Long) time);
} else if (time instanceof Date) {
params.addProperty("timeNumber", ((Date) time).getTime());
+ } else if (time instanceof Instant) {
+ params.addProperty("timeNumber", ((Instant) time).toEpochMilli());
} else if (time instanceof String) {
params.addProperty("timeString", (String) time);
}
diff --git a/playwright/src/test/java/com/microsoft/playwright/TestPageClock.java b/playwright/src/test/java/com/microsoft/playwright/TestPageClock.java
index d00d365d6..719b35f28 100644
--- a/playwright/src/test/java/com/microsoft/playwright/TestPageClock.java
+++ b/playwright/src/test/java/com/microsoft/playwright/TestPageClock.java
@@ -9,6 +9,9 @@
import java.io.Writer;
import java.text.ParseException;
import java.text.SimpleDateFormat;
+import java.time.Instant;
+import java.time.LocalDateTime;
+import java.time.ZoneOffset;
import java.util.ArrayList;
import java.util.Date;
@@ -350,6 +353,25 @@ void setFixedTimeAllowsInstallingFakeTimersAfterSettingTime(Page page) {
assertEquals(200, ((Object[]) calls.get(0))[0]);
}
+ @Test
+ void acceptsInstant(Page page) {
+ // A LocalDateTime has no time zone, so convert it to an Instant at an explicit offset.
+ page.clock().install(new Clock.InstallOptions().setTime(
+ LocalDateTime.of(2024, 12, 10, 8, 0, 0).toInstant(ZoneOffset.UTC)));
+
+ Instant paused = LocalDateTime.of(2024, 12, 10, 10, 0, 0).toInstant(ZoneOffset.UTC);
+ page.clock().pauseAt(paused);
+ assertEquals(paused.toEpochMilli(), ((Number) page.evaluate("() => Date.now()")).longValue());
+
+ Instant system = LocalDateTime.of(2024, 12, 10, 12, 0, 0).toInstant(ZoneOffset.UTC);
+ page.clock().setSystemTime(system);
+ assertEquals(system.toEpochMilli(), ((Number) page.evaluate("() => Date.now()")).longValue());
+
+ Instant fixed = LocalDateTime.of(2024, 12, 10, 14, 0, 0).toInstant(ZoneOffset.UTC);
+ page.clock().setFixedTime(fixed);
+ assertEquals(fixed.toEpochMilli(), ((Number) page.evaluate("() => Date.now()")).longValue());
+ }
+
@Test
void whileRunningShouldProgressTime(Page page) {
page.clock().install(new Clock.InstallOptions().setTime(0));
diff --git a/tools/api-generator/src/main/java/com/microsoft/playwright/tools/ApiGenerator.java b/tools/api-generator/src/main/java/com/microsoft/playwright/tools/ApiGenerator.java
index a41df3f87..48f86f81e 100644
--- a/tools/api-generator/src/main/java/com/microsoft/playwright/tools/ApiGenerator.java
+++ b/tools/api-generator/src/main/java/com/microsoft/playwright/tools/ApiGenerator.java
@@ -402,13 +402,23 @@ private List