简介
Playwright 提供强大的 API,可以模拟和修改 HTTP/HTTPS 网络流量。无论是 XHR 还是 fetch 请求,都可以被轻松跟踪、修改和模拟。此外,Playwright 还支持使用 HTTP Archive (HAR) 文件来模拟页面发出的多个网络请求。
模拟 API 请求
以下代码示例展示了如何使用 Playwright 拦截对特定 API 的调用,并返回自定义响应。
def test_mock_the_fruit_api(page: Page):
def handle(route: Route):
json = [{"name": "Strawberry", "id": 21}]
# 使用模拟数据完成路由
route.fulfill(json=json)
# 拦截到fruits API 的路由
page.route("*/**/api/v1/fruits", handle)
# 转到页面
page.goto("https://demo.playwright.dev/api-mocking")
# 断言Strawberry可见
expect(page.get_by_text("Strawberry")).to_be_visible()
在此示例中,我们拦截了对 /api/v1/fruits
的所有调用,并返回一个包含草莓数据的 JSON 响应。测试过程中,页面将使用模拟数据,而不会实际调用 API
修改 API 响应
有时,我们需要发出 API 请求,但希望修改其响应以实现可重现的测试。以下示例展示了如何在拦截请求后,向原始响应中添加新数据。
def test_gets_the_json_from_api_and_adds_a_new_fruit(page: Page):
def handle(route: Route):
response = route.fetch()
json = response.json()
json.append({"name": "Loquat", "id": 100})
# 使用原始响应(同时用给定的 JSON 对象修补响应体)来完成
route.fulfill(response=response, json=json)
page.route("https://demo.playwright.dev/api-mocking/api/v1/fruits", handle)
# 转到页面
page.goto("https://demo.playwright.dev/api-mocking")
# 断言Loquat可见
expect(page.get_by_text("Loquat", exact=True)).to_be_visible()
在此示例中,拦截了对水果 API 的调用,并向返回的数据中添加了一个名为 ‘Loquat’ 的新水果。然后,验证该数据是否在页面上正确显示
通过检查响应,可以看到Loquat已添加到列表中。
使用 HAR 文件进行模拟
HAR 文件记录了加载页面时发出的所有网络请求。使用 Playwright,我们可以录制、修改和重放这些请求。
记录 HAR 文件
要记录 HAR 文件,可以使用 page.route_from_har()
或 browser_context.route_from_har()
方法。以下示例展示了如何录制 HAR 文件并使用实际数据更新它。
def test_records_or_updates_the_har_file(page: Page):
# 从 HAR 文件获取响应
page.route_from_har("./hars/fruit.har", url="*/**/api/v1/fruits", update=True)
# 转到页面
page.goto("https://demo.playwright.dev/api-mocking")
# 断言Strawberry可见
expect(page.get_by_text("Strawberry")).to_be_visible()
修改 HAR 文件
录制完 HAR 文件后,可以手动编辑其中的 JSON 数据。例如,可以添加新的水果数据。
[
{
"name": "Playwright",
"id": 100
},
// ... other fruits
]
从 HAR 重放
修改完 HAR 文件后,可以在测试中使用它来提供匹配的响应。以下示例展示了如何从 HAR 文件重放 API 请求。
def test_gets_the_json_from_har_and_checks_the_new_fruit_has_been_added(page: Page):
# 从 HAR 重放 API 请求。
# 要么使用 HAR 中的匹配响应,
# 要么如果没有匹配项则中止请求。
page.route_from_har("./hars/fruit.har", url="*/**/api/v1/fruits", update=False)
# 转到页面
page.goto("https://demo.playwright.dev/api-mocking")
# 断言 Playwright 可见
expect(page.get_by_text("Playwright", exact=True)).to_be_visible()
在此示例中,测试从 HAR 文件获取响应,而不会实际调用 API。我们验证了新添加的水果数据是否在页面上正确显示。
使用 CLI 录制 HAR
除了使用代码录制 HAR 文件外,还可以使用 Playwright CLI。以下命令展示了如何录制特定 API 请求的 HAR 文件。
# 将example.com的API请求保存为“example.har”存档。
playwright open --save-har=example.har --save-har-glob="**/api/**" https://example.com
模拟 WebSocket
Playwright 还支持模拟 WebSocket 通信。以下示例展示了如何拦截 WebSocket 连接并模拟整个通信过程。
def message_handler(ws: WebSocketRoute, message: Union[str, bytes]):
if message == "request":
ws.send("response")
page.route_web_socket("wss://example.com/ws", lambda ws: ws.on_message(
lambda message: message_handler(ws, message)
))
或者,我们可以连接到实际服务器,但拦截并修改中间的消息。以下示例展示了如何实现这一点。
def message_handler(server: WebSocketRoute, message: Union[str, bytes]):
if message == "request":
server.send("request2")
else:
server.send(message)
def handler(ws: WebSocketRoute):
server = ws.connect_to_server()
ws.on_message(lambda message: message_handler(server, message))
page.route_web_socket("wss://example.com/ws", handler)