告别录屏与浏览器孤岛,Playwright以原生AI能力重塑测试工作流
📝 面试求职: 「面试试题小程序」 ,内容涵盖 测试基础、Linux操作系统、MySQL数据库、Web功能测试、接口测试、APPium移动端测试、Python知识、Selenium自动化测试相关、性能测试、性能测试、计算机网络知识、Jmeter、HR面试,命中率杠杠的。(大家刷起来…)
📝 职场经验干货:
Playwright 1.59 于近期正式发布。作为面向测试工程师的重大版本,这一版带来了多项关键更新:全新 Screencast API 让录屏不再难用、
browser.bind()打通了 AI Agent 与浏览器的连接通道、await using彻底终结了资源泄漏的噩梦……本文将逐一解析,带你用好这些新能力。
一、写在前面:为什么 1.59 值得关注?
很多测试 同学可能还停留在「Playwright 就是一个更快的 Selenium」这个认知上。
实际上,从 1.49 到 1.59,Playwright 正在悄然完成一次战略转型:从 Web 自动化测试工具,演变为 AI 驱动的测试平台。
体现在几个关键动作上:
|
版本 |
标志性事件 |
|
1.49 |
MCP(Model Context Protocol)协议支持 |
|
1.52 |
AI 可描述定位器(Describable Locators) |
|
1.57 |
编码代理(Coding Agent)正式登场 |
| 1.59 | Screencast API + browser.bind() |
如果你正在做 AI + 测试的探索,1.59 是必须关注的一个版本。如果你只是做常规 UI 自动化,这一版的 await using 改进和_locator 增强同样值得升级。
二、Screencast API:终于,录屏变得好用了
2.1 痛点回顾
在 1.59 之前,如果你想在 Playwright 测试中录制视频,方案相当原始:
-
用系统录屏工具手动录
-
用 FFmpeg 配合 Xvfb(Linux 无头环境)
-
自己写一个 Canvas + MediaRecorder 封装
每一种都不优雅,且无法与测试上下文关联。
2.2 核心 API
新版引入 page.screencast,提供完整的录屏能力:
import asyncio
from playwright.async_api import expect
'''
@Author : TesterRoad
@Time : 2026/4
@Desc : 公众号:测试工程师成长之路
@Software: PyCharm
'''
async def test_submit_order(page):
# 基础录制:保存为 WebM
video_path = "./test-results/demo.webm"
await page.screencast.start(path=video_path)
# 执行测试操作
await page.get_by_role("button", name="提交订单").click()
await expect(page.get_by_text("下单成功")).to_be_visible()
# 停止录制
await page.screencast.stop()
print(f"视频已保存: {video_path}")
2.3 动作标注:录屏里的操作轨迹
这是最实用的功能之一——录屏中自动高亮显示鼠标点击、键盘输入等操作:
await page.screencast.start(
path="annotated.webm",
# 显示操作标注
show_actions={
"position": "top-right", # 标注出现在右上角
"font_size": 14,
},
)
# 每次点击/输入会自动记录并显示在录屏上
await page.get_by_placeholder("搜索商品").fill("iPhone 16")
标注支持以下位置:top-left、top、top-right、left、right、bottom-left、bottom、bottom-right。
2.4 章节叠加:让视频自带叙事结构
你可以给录屏添加章节标记,适合生成报告或事后回放:
'''
@Author : TesterRoad
@Time : 2025/7
@Desc : 公众号:测试工程师成长之路
@Software: PyCharm
'''
await page.screencast.start(path="chaptered.webm")
# 章节 1:进入商品页
await page.screencast.show_chapter(
"进入商品详情页",
description="点击商品卡片",
duration=2000, # 持续 2 秒
)
await page.get_by_role("link", name="iPhone 16 Pro").click()
# 章节 2:加入购物车
await page.screencast.show_chapter(
"加入购物车",
description="点击加入按钮",
duration=1500,
)
await page.get_by_role("button", name="加入购物车").click()
await page.screencast.hide_chapter()
await page.screencast.stop()
2.5 实时帧流:为 AI 视觉模型而生
如果你在做 AI Agent 相关的测试,需要实时将画面传给视觉模型处理:
async def handle_frame(frame_data: bytes):
# frame_data 为 JPEG 编码的帧数据
await send_to_vision_model(frame_data)
await page.screencast.start(
on_frame=handle_frame,
size={"width": 800, "height": 600}, # 降低分辨率以节省带宽
)
这个 API 的典型应用场景:
-
AI Agent 视觉反馈循环测试
-
实时监控页面状态变化
-
截图驱动的自动化决策
2.6 代理视频回执
编码代理(Playwright Codegen Agent)现在可以生成带丰富标注的工作视频记录, 测试同学可以直接用录屏来审查 AI Agent 的执行过程。
三、browser.bind():浏览器成了可共享的资源
3.1 解决了什么问题?
在之前的架构里,每个Playwright脚本都需要自己启动和管理浏览器进程。如果你有多个工具(playwright-cli、MCP Server、测试脚本)想同时连接同一个浏览器实例,基本不可能。browser.bind() 彻底解决了这个问题。
3.2 基础用法
# 在主测试脚本中绑定浏览器
result = await browser.bind("my-session", workspace_dir="/my/project")
endpoint = result["endpoint"]
print(f"绑定端点: {endpoint}")
# 输出示例: ws://localhost:53321/session/my-session
# 这个 endpoint 可以分享给其他客户端连接
3.3 连接方式
绑定后,以下客户端都可以连接到同一个浏览器实例:
# 方式 1:playwright-cli
playwright-cli attach my-session
# 方式 2:@playwright/mcp(AI Agent)
# 在 MCP 配置中使用 endpoint
# 方式 3:Playwright 客户端 SDK
const client = await chromium.connect(endpoint);
3.4 实际应用场景
场景一:AI Agent 接管浏览器会话
# 测试脚本预先打开目标页面并绑定
await page.goto("https://your-app.com/dashboard")
await browser.bind("agent-session")
# AI Agent 通过 MCP 连接后,可以直接操作同一浏览器
# 无需重新登录,因为 Cookie 和会话状态已就绪
场景二:调试与测试共用一个浏览器
# 开发阶段:绑定浏览器,用 playwright-cli 手动调试
await browser.bind("dev-debug")
# 测试阶段:测试脚本 attach 到同一浏览器执行断言
# 两个工具共享同一个 Chrome DevTools Protocol 连接
四、上下文管理器:资源泄漏的终结者
4.1 旧世界的问题
在 Python 中使用 page.route()、add_init_script() 这类临时性 API 时,最让人头疼的就是清理:
# ❌ 旧写法:容易遗漏清理
import pytest
'''
@Author : TesterRoad
@Time : 2025/7
@Desc : 公众号:测试工程师成长之路
@Software: PyCharm
'''
route_handler = None
@pytest.fixture(autouse=True)
async def block_ads(page):
global route_handler
async def handler(route):
if "ads.doubleclick" in route.request.url:
await route.abort()
else:
await route.continue_()
route_handler = handler
await page.route("**/*", route_handler)
yield
# ⚠️ 容易忘写,导致测试间互相污染
await page.unroute("**/*", route_handler)
多了容易漏,少了会导致下一个测试继承了上一个的拦截逻辑——间歇性 bug 的经典来源。
4.2 新写法:自动 Cleanup
Playwright Python 1.59 中,page.route() 等 API 支持 async with 上下文管理器语法,离开作用域自动释放:
import pytest
@pytest.mark.asyncio
async def test_block_ads(page):
# ✅ 新写法:离开作用域自动清理
async with page.route("**/*", lambda route: route.abort() if "ads" in route.request.url else route.continue_()) as route:
# 作用域内的所有操作都生效
await page.goto("https://news.example.com")
# 测试结束,route 自动 unroute,无需手动清理
说明:Playwright Python 的上下文管理器模式是标准
async with语法,无需额外依赖。相比 TypeScript 的await using(TC39 显式资源管理提案),Python 的写法更加成熟稳定,是 Python 异步编程的最佳实践。
五、Locator 增强:更精准,更灵活
5.1 locator.normalize() — 定位器最佳实践转换
这个方法可以把你写的定位器转换成 Playwright 推荐的标准写法:
# 假设你写了这样的选择器
locator = page.locator('[data-testid="submit-btn"]')
# 调用 normalize 后,会返回 Playwright 推荐的最佳定位器
best_practice = await locator.normalize()
print(best_practice)
# 输出可能是: get_by_role('button', name='提交')
用途:
-
代码审查时检查定位器质量
-
自动发现脆弱的 CSS 选择器
-
团队统一定位器规范
5.2 page.pick_locator()— 交互式选择元素
如果你不想在代码里写死定位器,这个方法允许你在页面上直接点击选择元素:
# 启动交互式选择器(终端会显示提示)
locator = await page.pick_locator()
# 在浏览器中点击你想定位的元素
# 按 Escape 确认选择
await locator.click() # 使用刚才选择的定位器
这个功能在录制脚本或现场调试时非常有用。
5.3 locator.aria_snapshot() 增强
# 深度限制:只获取前两层结构
snapshot = await locator.aria_snapshot(depth=2)
# 模式选择:隐藏还是显示隐藏元素
snapshot_with_hidden = await locator.aria_snapshot(mode="all") # "all" | "accessible"
六、可观测性:Trace 分析进入命令行时代
6.1 playwright-cli show仪表板
新版命令行可以启动一个交互式仪表板:
npx playwright-cli show
仪表板功能:
-
查看所有
browser.bind()创建的浏览器会话 -
实时查看各浏览器状态
-
直接在仪表板中操作浏览器
6.2 命令行 Trace 分析
之前分析 trace 文件必须打开 Playwright 的 Web UI,现在可以在终端里完成:
# 查看所有 action 列表
npx playwright trace actions test-results/trace.zip
# 过滤特定 action
npx playwright trace actions --grep="expect" test-results/trace.zip
# 查看单个 action 详情
npx playwright trace action 9 test-results/trace.zip
这对于 CI/CD 环境中自动化分析 trace 报告非常有用。
6.3 tracing.start()新增 live 选项
await context.tracing.start(
live=True, # 实时上传 trace 数据到 Playwright 服务器
title="Checkout Flow Test",
)
配合 browser.bind() 使用,团队成员可以实时看到测试执行的 trace。
七、其他值得关注的更新
7.1 存储状态管理增强
# 清除并重置存储状态
await context.set_storage_state(paths=[]) # 相当于清空所有 cookie/storage
# 之前需要手动循环删除,现在一行搞定
7.2 控制台和错误清理
# 清除控制台消息(测试间隔离)
await page.clear_console_messages()
# 清除页面错误(避免错误状态泄漏)
await page.clear_page_errors()
# 获取消息时间戳(新增 API)
msgs = await page.wait_for_console_messages()
if msgs:
print(f"消息时间: {msgs[0].timestamp}") # ISO 8601 格式
7.3 request.existing_response()不等待直接返回
# 之前:必须等待响应返回
response = await request.fetch(url)
# 现在:如果响应已存在,直接返回,不等待
existing = await request.existing_response(url)
if existing:
print(f"响应状态: {existing.status}")
7.4 UI Mode 改进
-
新增仅显示受源代码变更影响的测试选项(
--only-changed)改进操作过滤逻辑 -
HTML Reporter 支持按测试步骤过滤
八、升级注意事项(破坏性变更)
macOS 14 WebKit 支持移除
如果你的 CI 环境还在用 macOS 14 + WebKit,请注意:1.59 已移除该平台支持。
# 检查你的 CI 配置
# macos-13(Ventura)及以下版本 + WebKit 仍然支持
# macos-14(Sonoma)+ WebKit 已不支持
建议: 迁移到 Linux Docker 或 macOS 15。
@playwright/experimental-ct-svelte移除
如果你在使用 Svelte 组件测试的实验性包,需要迁移到正式版本或改用其他框架。
九、总结:1.59 到底值不值得升?
|
场景 |
推荐程度 |
理由 |
| AI Agent + 自动化测试 |
⭐⭐⭐⭐⭐ 强烈推荐 |
Screencast API + browser.bind() 是为此场景量身打造 |
| 常规 UI 自动化 |
⭐⭐⭐⭐ 推荐 |
await using + locator 增强直接改善开发体验 |
| 录屏生成测试报告 |
⭐⭐⭐⭐⭐ 强烈推荐 |
Screencast 终于原生支持,效果比 FFmpeg 方案好太多 |
| CI/CD 稳定性优先 |
⭐⭐⭐ 观望一周 |
可先在 staging 环境验证,确认无 regression 再上生产 |
安装升级
# 升级 Playwright(Python)
pip install playwright --upgrade
# 安装/升级浏览器
playwright install
十、下一步建议
-
先跑一遍回归测试:升级后用
npx playwright test跑一遍现有用例,确认无破坏性影响 -
试试 Screencast:
page.screencast足够成熟,可以替换现有的录屏方案了 -
迁移到 await using:检查你的测试代码中
route和addInitScript的清理逻辑,有则改之 -
关注 AI 方向:如果你在探索 AI + 测试,
browser.bind()+ MCP 是目前最顺滑的接入路径
你在使用 Playwright 过程中遇到的最大痛点是什么?欢迎在评论区聊聊,说不定下一版的功能就是为你而写。
如果觉得这篇文章有帮助,转发给你身边做测试的同学,一起跟上 Playwright 的迭代节奏。
最后: 下方这份完整的软件测试视频教程已经整理上传完成,需要的朋友们可以自行领取【保证100%免费】
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐


所有评论(0)