Clock
Введение
Точное моделирование поведения, зависящего от времени, необходимо для проверки корректности приложений. Использование функциональности Clock позволяет разработчикам управлять временем в тестах и изменять его, обеспечивая точную проверку таких функций, как отображение времени, тайм-ауты и запланированные задачи, без задержек и непредсказуемости выполнения в реальном времени.
API Clock предоставляет следующие методы для управления временем:
-
setFixedTime: задаёт фиксированное время дляDate.now()иnew Date(). -
install: инициализирует часы и позволяет:-
pauseAt: останавливает время в заданный момент. -
fastForward: быстро перематывает время вперёд. -
runFor: запускает ход времени на заданный период. -
resume: возобновляет ход времени.
-
-
setSystemTime: задаёт текущее системное время.
Рекомендуется использовать setFixedTime, чтобы задать определённое время. Если это не подходит для вашего сценария, можно использовать install, который позволяет позднее остановить время, перемотать его вперёд, продвинуть на шаг и т. д. setSystemTime рекомендуется только для сложных сценариев.
примечаниеpage.clock переопределяет встроенные глобальные классы и функции, связанные со временем, позволяя управлять ими вручную:
DatesetTimeoutclearTimeoutsetIntervalclearIntervalrequestAnimationFramecancelAnimationFramerequestIdleCallbackcancelIdleCallbackperformanceEvent.timeStamp
предупреждениеЕсли вы вызываете
installв ходе теста, этот вызов ДОЛЖЕН выполняться до любых других вызовов, связанных с часами (см. список выше в примечании). Вызов этих методов не по порядку приведёт к неопределённому поведению. Например, нельзя вызватьsetInterval, затемinstall, а после этогоclearInterval, посколькуinstallпереопределяет встроенное определение функций часов.
Тестирование с заданным временем
Часто достаточно подменить Date.now, не останавливая таймеры. Так время будет идти естественным образом, но Date.now всегда будет возвращать фиксированное значение.
<div id="current-time" data-testid="current-time"></div>
<script>
const renderTime = () => {
document.getElementById('current-time').textContent =
new Date().toLocaleString();
};
setInterval(renderTime, 1000);
</script> await page.clock.setFixedTime(new Date('2024-02-02T10:00:00'));
await page.goto('http://localhost:3333');
await expect(page.getByTestId('current-time')).toHaveText('2/2/2024, 10:00:00 AM');
await page.clock.setFixedTime(new Date('2024-02-02T10:30:00'));
// We know that the page has a timer that updates the time every second.
await expect(page.getByTestId('current-time')).toHaveText('2/2/2024, 10:30:00 AM'); Согласованная работа времени и таймеров
Иногда таймеры зависят от Date.now и работают некорректно, если значение Date.now не меняется со временем. В этом случае при тестировании можно установить часы и быстро перемотать время до нужного момента.
<div id="current-time" data-testid="current-time"></div>
<script>
const renderTime = () => {
document.getElementById('current-time').textContent =
new Date().toLocaleString();
};
setInterval(renderTime, 1000);
</script> // Initialize clock with some time before the test time and let the page load
// naturally. `Date.now` will progress as the timers fire.
await page.clock.install({ time: new Date('2024-02-02T08:00:00') });
await page.goto('http://localhost:3333');
// 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');
// Close the laptop lid again and open it at 10:30am.
await page.clock.fastForward('30:00');
await expect(page.getByTestId('current-time')).toHaveText('2/2/2024, 10:30:00 AM'); Тестирование отслеживания бездействия
Отслеживание бездействия — распространённая функция веб-приложений, которая завершает сеанс пользователя после периода бездействия. Тестировать её бывает непросто, поскольку для проверки результата приходится долго ждать. С помощью часов можно ускорить время и быстро протестировать эту функцию.
<div id="remaining-time" data-testid="remaining-time"></div>
<script>
const endTime = Date.now() + 5 * 60_000;
const renderTime = () => {
const diffInSeconds = Math.round((endTime - Date.now()) / 1000);
if (diffInSeconds <= 0) {
document.getElementById('remaining-time').textContent =
'You have been logged out due to inactivity.';
} else {
document.getElementById('remaining-time').textContent =
`You will be logged out in ${diffInSeconds} seconds.`;
}
setTimeout(renderTime, 1000);
};
renderTime();
</script>
<button type="button">Interaction</button> // Initial time does not matter for the test, so we can pick current time.
await page.clock.install();
await page.goto('http://localhost:3333');
// Interact with the page
await page.getByRole('button').click();
// Fast forward time 5 minutes as if the user did not do anything.
// Fast forward is like closing the laptop lid and opening it after 5 minutes.
// All the timers due will fire once immediately, as in the real browser.
await page.clock.fastForward('05:00');
// Check that the user was logged out automatically.
await expect(page.getByText('You have been logged out due to inactivity.')).toBeVisible(); Пошаговое продвижение времени вручную с последовательным запуском всех таймеров
В редких случаях может понадобиться вручную пошагово продвигать время, запуская при этом все таймеры и кадры анимации, чтобы точно контролировать ход времени.
<div id="current-time" data-testid="current-time"></div>
<script>
const renderTime = () => {
document.getElementById('current-time').textContent =
new Date().toLocaleString();
};
setInterval(renderTime, 1000);
</script> // Initialize clock with a specific time, let the page load naturally.
await page.clock.install({ time: new Date('2024-02-02T08:00:00') });
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.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.
// In this case, time will be updated in the screen 2 times.
await page.clock.runFor(2000);
await expect(page.getByTestId('current-time')).toHaveText('2/2/2024, 10:00:02 AM'); Связанные видео
© 2026 Microsoft
Licensed under the Apache License, Version 2.0.
https://playwright.dev/docs/clock