在 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.tracingAPI 控制。
主要接口
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结合,解决你之前的换行问题并提取属性和子节点。
如果你有更具体的场景(例如处理动态页面、特定元素的截图或多片段跟踪),请提供细节,我可以进一步定制代码!