Playwright 中 page.clock 的常用方法和示例
Playwright 中的 page.clock API 允许你在测试中控制和模拟时间流逝,这对于测试定时器、延迟和日期相关功能非常有用。
常用方法
1. 安装时钟
await page.clock.install()
安装 fake timers,替换原生的定时器函数。
2. 前进时间
await page.clock.tick(ms) # 前进指定的毫秒数
await page.clock.next() # 前进到下一个定时器触发
3. 取消时钟
await page.clock.uninstall()
恢复原生的定时器函数。
4. 设置系统时间
await page.clock.set_system_time(time) # time可以是时间戳或datetime对象
示例
基本使用示例
import pytest
from playwright.async_api import Page
@pytest.mark.asyncio
async def test_timer(page: Page):
await page.clock.install()
# 在页面中设置一个定时器
await page.evaluate("""
setTimeout(() => {
document.body.innerHTML = '<div id="done">Done!</div>';
}, 1000);
""")
# 前进时间
await page.clock.tick(1000)
# 验证定时器是否触发
await page.wait_for_selector("#done")
await page.clock.uninstall()
测试延迟加载
@pytest.mark.asyncio
async def test_lazy_loading(page: Page):
await page.clock.install()
await page.goto("http://example.com")
# 页面中有延迟加载的逻辑
await page.evaluate("""
setTimeout(() => {
fetch('/api/data').then(/* ... */);
}, 5000);
""")
# 立即前进5秒,而不是实际等待
await page.clock.tick(5000)
# 验证API调用是否发生
# ...
await page.clock.uninstall()
测试日期相关逻辑
from datetime import datetime
@pytest.mark.asyncio
async def test_date_functionality(page: Page):
await page.clock.install()
# 设置固定日期
fixed_date = datetime(2023, 1, 1)
await page.clock.set_system_time(fixed_date)
# 验证页面中的日期显示
await page.goto("http://example.com/date-display")
displayed_date = await page.text_content(".current-date")
assert "2023-01-01" in displayed_date
await page.clock.uninstall()
底层原理
Playwright Python 中的 page.clock 实现原理与 JavaScript 版本类似,但通过 Python 桥接层与浏览器通信:
-
Python 到 JavaScript 的桥接:
- Python API 通过 WebSocket 或管道与浏览器通信
- 所有 clock 相关调用被转换为浏览器端的 JavaScript 执行
-
Sinon.JS 集成:
- 底层仍然使用 Sinon.JS 的 fake timers 实现
- 通过 Playwright 的注入机制将 Sinon.JS 代码注入到页面上下文
-
时间控制流程:
Python代码 → Playwright Python客户端 → 浏览器通信协议 → 页面JavaScript环境 → Sinon.JS实现
-
定时器管理:
- 维护一个虚拟的时间轴
- 当调用
tick()时,会触发所有到期定时器 - 保持定时器的执行顺序与原生实现一致
-
Date 对象覆盖:
- 替换原生的 Date 构造函数和相关方法
- 确保所有时间相关调用都使用模拟时间
-
上下文隔离:
- 每个页面有独立的时钟实例
- iframe 也可以有自己的时钟控制
这种实现方式使得你可以在 Python 测试代码中精确控制浏览器内的时间流逝,而无需实际等待,大大加速了时间相关测试的执行速度。
注意事项
- 仅适用于测试:不要在生产代码中使用这些功能
- 异步操作:所有方法都是异步的,需要使用
await - 清理:测试完成后应该调用
uninstall()恢复原生日志 - 兼容性:某些复杂的时间相关库可能不完全兼容 fake timers
浙公网安备 33010602011771号