在 Playwright 的 Python API 中,video
、screenshot
和 trace
是用于调试和记录自动化测试或网页交互的重要工具。这些功能可以帮助捕获页面的视觉状态、录制操作视频以及生成详细的跟踪日志,特别适合调试失败的测试或记录复杂交互。结合你之前的提问(关于 Locator
、get_by_text
、get_by_role
、属性和子节点),我将详细介绍这些功能的开启和使用方法,并提供针对性的示例代码,解决你之前提到的问题(如 get_by_text
的换行问题)并与 Locator
结合使用。
1. Screenshot(截图)
概述
- 功能: Playwright 允许捕获页面、特定元素或整个滚动页面的截图,用于调试、验证 UI 或生成报告。
- 用途: 测试 UI 状态、验证视觉差异、记录错误时的页面状态。
- 接口: 主要通过
Page.screenshot()
或Locator.screenshot()
调用。
主要接口
page.screenshot(**kwargs)
: 捕获整个页面或视口的截图。- 参数:
path
: 保存截图的文件路径(例如"screenshot.png"
)。type
: 图片格式("png"
或"jpeg"
,默认"png"
)。quality
: JPEG 质量(0-100,仅对 JPEG 有效)。full_page
: 是否捕获整个滚动页面(默认False
,仅捕获视口)。clip
: 裁剪区域(字典,包含x
,y
,width
,height
)。omit_background
: 忽略透明背景(默认False
)。timeout
: 操作超时(毫秒)。
- 返回: 如果未指定
path
,返回二进制数据(字节流)。 locator.screenshot(**kwargs)
: 捕获特定元素的截图。- 参数同上,但只针对
Locator
匹配的元素。 - 自动截图(Pytest 插件): 使用
--screenshot
命令行参数(on
,off
,only-on-failure
)在测试失败时自动保存截图。
开启和使用
- 手动截图: 调用
page.screenshot()
或locator.screenshot()
。 - 自动截图: 在 Pytest 中,通过命令行参数启用:
pytest --screenshot=only-on-failure --full-page-screenshot
这会在测试失败时保存截图,并可选择捕获整个页面。
注意事项
- 截图保存在文件系统或作为二进制数据返回,适合传递给 API 或进行图像处理。
- 完整页面截图(
full_page=True
)会捕获整个滚动区域,可能生成较大的文件。 - 元素截图需要确保
Locator
匹配的元素可见。
2. Video(视频录制)
概述
- 功能: Playwright 可以录制页面的操作视频,生成 WebM 格式的视频文件,适合调试用户交互流程。
- 用途: 记录测试执行过程、调试复杂交互、生成视觉报告。
- 接口: 通过
BrowserContext
的record_video_dir
和record_video_size
配置。
主要接口
browser.new_context(**kwargs)
:- 参数:
record_video_dir
: 保存视频的目录(例如"videos/"
)。record_video_size
: 视频分辨率(字典,包含width
,height
)。
- 视频会为每个页面自动生成,保存在指定目录。
page.video().path()
: 获取页面录制视频的文件路径(异步 API 使用await page.video.path()
)。- 自动视频录制(Pytest 插件): 使用
--video
命令行参数(on
,off
,retain-on-failure
):
pytest --video=on
开启和使用
- 在创建
BrowserContext
时启用视频录制:
context = await browser.new_context(record_video_dir="videos/")
- 视频会在页面关闭或上下文关闭时自动保存到指定目录。
- 文件名通常为页面相关的唯一标识,格式为
.webm
。
注意事项
- 视频录制需要指定
record_video_dir
,否则不生成视频。 - 视频文件可能较大,建议仅在调试时启用。
- 仅在
BrowserContext
级别配置,不支持单个页面或元素级别的视频录制。
3. Trace(跟踪)
概述
- 功能: Playwright 的 Trace Viewer 记录测试的详细操作日志,包括 DOM 快照、网络请求、动作时间线和截图,生成
.zip
文件,可在trace.playwright.dev
查看。 - 用途: 调试测试失败、分析性能、查看操作序列和网络活动。
- 接口: 通过
BrowserContext.tracing
API 控制。
主要接口
context.tracing.start(**kwargs)
: 开始跟踪。- 参数:
screenshots
: 是否包含截图(默认False
)。snapshots
: 是否包含 DOM 快照(默认False
)。sources
: 是否包含源代码(默认False
)。name
: 跟踪名称(显示在 Trace Viewer 中)。
context.tracing.start_chunk(**kwargs)
: 开始新的跟踪片段(用于分段记录)。context.tracing.stop(**kwargs)
: 停止跟踪并保存到文件。- 参数:
path
(保存路径,例如"trace.zip"
)。 context.tracing.stop_chunk(**kwargs)
: 停止当前跟踪片段并保存。- 自动跟踪(Pytest 插件): 使用
--tracing
命令行参数(on
,off
,retain-on-failure
):
pytest --tracing=on
- 查看跟踪: 使用 Playwright CLI 或网页查看:
playwright show-trace trace.zip
或访问 trace.playwright.dev
并上传 trace.zip
。
开启和使用
- 在
BrowserContext
上启动跟踪,执行操作后停止并保存:
await context.tracing.start(screenshots=True, snapshots=True)
# 执行操作
await context.tracing.stop(path="trace.zip")
- 分段跟踪(多个跟踪文件):
await context.tracing.start(screenshots=True, snapshots=True)
await context.tracing.start_chunk()
# 操作 1
await context.tracing.stop_chunk(path="trace1.zip")
await context.tracing.start_chunk()
# 操作 2
await context.tracing.stop_chunk(path="trace2.zip")
注意事项
- 跟踪文件(
.zip
)包含大量数据(如截图、网络请求、DOM 快照),可能占用较多磁盘空间。 - 建议启用
screenshots
和snapshots
以获得完整的调试信息。 - Trace Viewer 提供交互式界面,显示动作时间线、DOM 快照和网络请求,适合 CI 环境中调试。
4. 示例代码
以下示例整合了 screenshot
、video
和 trace
的使用,基于你之前的 HTML 和问题(get_by_text
换行、get_by_role
、属性和子节点),并使用异步 API(因为你之前使用了 await
)。
示例 1: 捕获截图、录制视频和生成跟踪
from playwright.async_api import async_playwright
import asyncio
async def main():
async with async_playwright() as p:
# Browser: 启动 Chromium
browser = await p.chromium.launch(headless=False, slow_mo=500)
# BrowserContext: 启用视频录制
context = await browser.new_context(
record_video_dir="videos/",
record_video_size={"width": 1280, "height": 720},
viewport={"width": 1280, "height": 720}
)
# 开始跟踪
await context.tracing.start(screenshots=True, snapshots=True, sources=True)
# Page: 创建页面并设置内容
page = await context.new_page()
html = """
<div class="first" role="region">Hello <span>world</span></div>
<button role="button" aria-label="Submit">Click me <span>world</span></button>
<input type="text" placeholder="Enter text">
"""
await page.set_content(html)
# Locator: 使用 get_by_text 精确定位 span(解决换行问题)
span_locator = page.locator("span:text-is('world')")
span_text = await span_locator.text_content()
print("Span text:", span_text) # 输出: world
# 捕获 span 的截图
await span_locator.screenshot(path="span_screenshot.png")
print("Span screenshot saved to span_screenshot.png")
# Locator: 使用 get_by_role 定位按钮
button_locator = page.get_by_role("button", name="Submit")
await button_locator.click()
# 捕获整个页面截图
await page.screenshot(path="full_page_screenshot.png", full_page=True)
print("Full page screenshot saved to full_page_screenshot.png")
# 打印按钮属性
attributes = await button_locator.evaluate(
"""element => {
const attrs = {};
for (const attr of element.attributes) {
attrs[attr.name] = attr.value;
}
return attrs;
}"""
)
print("Button attributes:", attributes)
# 打印按钮子节点
children = await button_locator.evaluate(
"""element => {
const childrenArray = [];
for (const child of element.children) {
childrenArray.push({
tagName: child.tagName,
textContent: child.textContent.trim(),
className: child.className || 'none'
});
}
return childrenArray;
}"""
)
print("Button children:")
for i, child in enumerate(children):
print(f"Child {i + 1}: Tag = {child['tagName']}, Text = {child['textContent']}, Class = {child['className']}")
# 获取视频路径
video_path = await page.video.path()
print("Video saved to:", video_path)
# 停止跟踪并保存
await context.tracing.stop(path="trace.zip")
print("Trace saved to trace.zip")
await context.close()
await browser.close()
asyncio.run(main())
输出示例:
Span text: world
Span screenshot saved to span_screenshot.png
Full page screenshot saved to full_page_screenshot.png
Button attributes: {'role': 'button', 'aria-label': 'Submit'}
Button children:
Child 1: Tag = SPAN, Text = world, Class = none
Video saved to: videos/<unique_id>.webm
Trace saved to trace.zip
示例 2: Pytest 自动截图和跟踪
使用 Pytest 插件自动捕获截图和跟踪,模拟测试失败场景。
import pytest
from playwright.async_api import async_playwright
@pytest.mark.asyncio
async def test_example(page):
html = """
<div class="first" role="region">Hello <span>world</span></div>
<button role="button" aria-label="Submit">Click me</button>
"""
await page.set_content(html)
# Locator: 使用 get_by_role
button_locator = page.get_by_role("button", name="Submit")
await button_locator.click()
# 故意引发失败以触发自动截图和跟踪
assert await button_locator.text_content() == "Wrong text", "Button text mismatch"
# 运行命令:
# pytest --screenshot=only-on-failure --tracing=retain-on-failure --video=on
说明:
- 运行上述测试时,失败会触发:
- 截图保存到
test-results/
目录(默认)。 - 跟踪文件保存为
trace.zip
。 - 视频保存到
test-results/
目录(WebM 格式)。 - 查看跟踪:
playwright show-trace test-results/trace.zip
。
5. 结合你之前的问题
- get_by_text 换行问题:
- 示例中使用
span:text-is('world')
确保精确匹配<span>
,避免父<div>
的干扰(如world\n Hello\n
)。
- get_by_role:
- 使用
page.get_by_role("button", name="Submit")
定位按钮,结合Locator
操作(如点击、截图)。
- 属性和子节点:
- 使用
evaluate
提取按钮的属性和子节点,与screenshot
和trace
结合,记录调试信息。
- Locator 集成:
- 示例展示了
Locator
的链式定位(span_locator
)、截图(span_locator.screenshot()
)和内容提取(text_content()
)。
6. Mac上用Quicktime Player录屏并转为mp4
- Quicktime Player录屏
- ffmpeg转为mp4
ffmpeg -i ubereats_flow.mov -vcodec h264 -acodec mp3 ubereats_flow.mp4
7. 注意事项
- 文件管理:
- 截图和视频文件可能占用大量磁盘空间,建议仅在需要时启用。
- 跟踪文件(
trace.zip
)包含截图和快照,需合理管理存储。 - 异步 vs 同步:
- 示例使用异步 API(
async_playwright
),同步 API 类似,只需替换为sync_playwright
并移除await
和async
。 - 同步示例:
python from playwright.sync_api import sync_playwright with sync_playwright() as p: browser = p.chromium.launch(headless=False) context = browser.new_context(record_video_dir="videos/") context.tracing.start(screenshots=True, snapshots=True) page = context.new_page() page.set_content('<div>Hello <span>world</span></div>') page.screenshot(path="screenshot.png") context.tracing.stop(path="trace.zip") print("Video saved to:", page.video.path()) context.close() browser.close()
- 调试:
- 使用 Trace Viewer(
trace.playwright.dev
)查看跟踪,检查动作时间线、截图和网络请求。 - 启用
slow_mo
(如launch(slow_mo=500)
)减慢操作,便于观察视频。 - Pytest 集成:
- 使用
--screenshot=only-on-failure
和--tracing=retain-on-failure
优化 CI 环境,减少不必要的文件生成。 - 权限和环境:
- 确保有权限写入截图、视频和跟踪文件(检查目录权限)。
- 视频和跟踪需要支持的浏览器(如 Chromium)。
7. 引用
8. 总结
- Screenshot: 通过
page.screenshot()
或locator.screenshot()
捕获页面或元素截图,支持视口、完整页面或裁剪区域,适合 UI 验证和调试。 - Video: 通过
record_video_dir
启用页面操作录制,生成 WebM 视频,适合记录交互流程。 - Trace: 使用
context.tracing
记录详细操作日志(包括截图和快照),通过 Trace Viewer 分析,适合 CI 调试。 - 结合 Locator: 示例展示了如何与
get_by_text
、get_by_role
和evaluate
结合,解决你之前的换行问题并提取属性和子节点。
如果你有更具体的场景(例如处理动态页面、特定元素的截图或多片段跟踪),请提供细节,我可以进一步定制代码!