Playwright Python — справочник На главный сайт

Обзор Clock API

Clock API в Playwright позволяет полностью контролировать время в браузере: перехватывать Date, setTimeout, setInterval, requestAnimationFrame и другие временные функции. Это необходимо для детерминированного тестирования анимаций, таймеров, календарей и поведения, зависящего от времени.

Установка и управление

page.clock.install() — перехват времени

Устанавливает перехват всех временных функций в браузере. После вызова все таймеры и Date управляются через Clock API.

from playwright.sync_api import sync_playwright

with sync_playwright() as p:
    browser = p.chromium.launch()
    page = browser.new_page()
    page.clock.install()
    page.goto("https://example.com")
    browser.close()

page.clock.install(time="2024-01-01T00:00:00")

Установка перехвата времени с начальной точкой отсчёта.

page.clock.install(time="2024-01-01T00:00:00")

page.clock.set_fixed_time() — фиксированное время

Устанавливает фиксированное время, которое не изменяется.

page.clock.set_fixed_time("2024-06-15T12:00:00")
# Date.now() всегда будет возвращать это значение

page.clock.set_system_time() — системное время

Устанавливает системное время (время течёт как обычно, но стартует с указанной точки).

page.clock.set_system_time("2024-06-15T12:00:00")
# Время течёт, но начальная точка задана

page.clock.pause_at() — остановка в конкретное время

Останавливает время в указанный момент.

page.clock.pause_at("2024-06-15T12:30:00")

page.clock.resume() — возобновление

Возобновляет течение времени после паузы.

page.clock.resume()

Управление таймерами и анимациями

page.clock.fast_forward() — ускорение времени

Прокручивает время вперёд на указанное количество миллисекунд, выполняя все ожидающие таймеры.

page.clock.fast_forward(5000)  # перемотать на 5 секунд вперёд

page.clock.fast_forward_async() — ускорение с async

То же, что fast_forward(), но в асинхронном режиме.

await page.clock.fast_forward_async(5000)

page.clock.advance() — продвинуть на N мс

Продвигает время на указанное количество миллисекунд (выполняет только таймеры, попавшие в этот интервал).

page.clock.advance(1000)  # продвинуть на 1 секунду

page.clock.run_for(1000) — пройти 1 сек

Запускает течение времени на указанный период, выполняя все таймеры и анимации.

page.clock.run_for(1000)  # выполнить все таймеры за 1 секунду

Примеры

Тестирование setTimeout

def test_settimeout(page):
    page.clock.install()
    result = []
    page.evaluate("setTimeout(() => window.__result = 'done', 1000)")
    page.clock.fast_forward(1000)
    assert page.evaluate("window.__result") == "done"

Тестирование анимаций (requestAnimationFrame)

def test_animation(page):
    page.clock.install()
    page.goto("https://example.com")
    # Прокрутить анимацию на 2 секунды
    page.clock.fast_forward(2000)

Тестирование календаря с фиксированной датой

def test_calendar(page):
    page.clock.set_fixed_time("2024-12-25T10:00:00")
    page.goto("https://example.com/calendar")
    # Календарь всегда показывает 25 декабря 2024
    expect(page.get_by_text("25 декабря 2024")).to_be_visible()

Тестирование таймеров с setInterval

def test_interval(page):
    page.clock.install()
    count = {"value": 0}
    page.expose_function("increment", lambda: count.update(value=count["value"] + 1))
    page.evaluate("setInterval(() => window.increment(), 500)")
    page.clock.fast_forward(2000)
    assert count["value"] == 4  # 2000 / 500 = 4 срабатывания

Совет: Используйте page.clock.install() перед навигацией, чтобы гарантировать, что все таймеры на странице будут под контролем с самого начала.

Важно: После вызова page.clock.install() все временные функции в браузере перестают работать естественным образом. Вы должны явно управлять временем через методы Clock API.

Примечание: Clock API поддерживается в Chromium и Firefox. В WebView2 также доступен, но с некоторыми ограничениями.