Playwright codegen脚本录制

Playwright 的脚本录制功能 (codegen)------ 一个能让你 "点点鼠标就生成代码" 的神器,它能帮你快速构建自动化测试脚本,大幅提升工作效率。

1. Playwright codegen特点

Playwright 的 codegen 并非传统意义上的 "录制回放" 工具,它有几个核心优势

  1. 智能定位技术 :优先使用role/name/text/test-id等语义化属性生成选择器,而非脆弱的 CSS 选择器或 XPath,脚本更稳定
  2. 多语言支持:可生成 Python、JavaScript/TypeScript、C# 等多种语言代码
  3. 自动等待 :内置智能等待机制,无需手动添加time.sleep()
  4. 设备模拟:支持模拟手机、平板等不同设备环境
  5. 网络控制:可录制网络请求,支持 HAR 文件导出

2. 启动录制工具

最基础的录制命令:

复制代码
playwright codegen https://www.baidu.com

Target这里可以选择生成不同语言的录制脚本

这里我们选择生成pytest样式的脚本

会自动转换为pytest样式的脚本

可以看到我们操作的每一步都会自动生成对应的脚本

执行脚本,和录制时操作的效果是一致的;

3. 录制功能参数

1. 常用命令行参数

表格

参数 说明 示例
--browser 指定浏览器类型 --browser=firefox
--headed 以有头模式运行 --headed
--device 模拟移动设备 --device="iPhone 13"
--output 保存代码到文件 --output=test.py
--target 指定生成语言 --target=python
--color-scheme 模拟配色方案 --color-scheme=dark
--save-storage 保存上下文状态 --save-storage=state.json

2. 示例:

复制代码
playwright codegen --device="iPhone 13" --output=test_record.py https://www.baidu.com

可以看到浏览器对应以参数形式,打开浏览器并且对py文件写入代码,十分的方便,这里就不一一举例了,感兴趣的可以自己尝试;

4,Playwright Inspector

Playwright Inspector 是 Playwright 提供的一个图形用户界面(GUI)调试工具,它可以帮助开发者调试 Playwright 脚本。这个工具允许开发者逐步执行脚本,实时编辑定位器,选择定位器,并查看操作日志。

4.1 Record

点击Record 记录,即录制脚本的意思

4.2 Pick locator

Pick locator 是「单独抓取页面元素的定位代码」,只拿定位器、不录操作

1)定位器语法

定位器可以参考官方文档写的巨详细

复制代码
https://playwright.cn/docs/locators

4.3 Assert visibility

检查元素在不在

4.4 Assert text

检查元素在不在 + 字对不对

点击√会生成断言脚本

4.5 Assert value

断言输入框当前是否有值

4.6 Assert snapshot

断言页面结构

1)断言区别

断言选项 作用 校验目标 严格度 新手推荐
Assert visibility 断言可见 元素是否显示在页面 ✅ 必用
Assert text 断言文本 元素显示的文字是否正确 ✅ 必用
Assert value 断言输入值 输入框里填写的内容 ✅ 必用
🚫 Assert snapshot 断言视觉快照 校验结构 + 文字 + 链接 + 属性全部一致 极高 ❌ 不推荐

注意点: expect 是 Playwright 专用的断言函数,不是 Python 自带的,必须手动导入才能用。

复制代码
# 必加:导入 sync_playwright + expect
from playwright.sync_api import sync_playwright, expect

def test_case():
    with sync_playwright() as p:
        browser = p.chromium.launch(headless=False)
        # 加载登录状态
        context = browser.new_context(storage_state="login_state.json")
        page = context.new_page()
        
        # 打开知乎
        page.goto("https://www.zhihu.com/", wait_until="networkidle")
        page.wait_for_timeout(3000)

        # 你的断言代码(现在可以正常运行了)
        expect(page.get_by_label("创作中心卡片")).to_match_aria_snapshot(
            "- text: 创作中心\n- link \"Lv4\":\n  - /url: /creator/account/growth-level")
        
        # 关闭资源
        context.close()
        browser.close()

2)断言语法

断言可以参考官方文档写的巨详细

复制代码
https://playwright.net.cn/docs/test-assertions#:~:text=Playwright%20%E5%8C%85%E5%90%AB%E4%BB%A5%20expect%20%E5%87%BD%E6%95%B0%E5%BD%A2%E5%BC%8F%E5%91%88%E7%8E%B0%E7%9A%84%E6%B5%8B%E8%AF%95%E6%96%AD%E8%A8%80%E3%80%82%20%E8%A6%81%E8%BF%9B%E8%A1%8C%E6%96%AD%E8%A8%80%EF%BC%8C%E8%AF%B7%E8%B0%83%E7%94%A8%20expect%28value%29%20%E5%B9%B6%E9%80%89%E6%8B%A9%E4%B8%80%E4%B8%AA%E5%8F%8D%E6%98%A0%E9%A2%84%E6%9C%9F%E7%9A%84%E5%8C%B9%E9%85%8D%E5%99%A8%E3%80%82%20%E6%9C%89%E8%AE%B8%E5%A4%9A,%E3%80%81%20toBeTruthy%EF%BC%8C%E5%8F%AF%E7%94%A8%E4%BA%8E%E6%96%AD%E8%A8%80%E4%BB%BB%E4%BD%95%E6%9D%A1%E4%BB%B6%E3%80%82%20Playwright%20%E8%BF%98%E5%8C%85%E5%90%AB%20Web%20%E4%B8%93%E7%94%A8%E7%9A%84%20%E5%BC%82%E6%AD%A5%E5%8C%B9%E9%85%8D%E5%99%A8%EF%BC%8C%E5%AE%83%E4%BB%AC%E4%BC%9A%E4%B8%80%E7%9B%B4%E7%AD%89%E5%BE%85%E7%9B%B4%E5%88%B0%E6%BB%A1%E8%B6%B3%E9%A2%84%E6%9C%9F%E6%9D%A1%E4%BB%B6%E3%80%82%20%E8%AF%B7%E8%80%83%E8%99%91%E4%BB%A5%E4%B8%8B%E7%A4%BA%E4%BE%8B

4.7 copy

复制当前生成的脚本

4.8 Resume

最常见的含义是 "恢复""继续执行"

复制代码
可以理解为继续执行page.pause()这个语句后面的脚本;

4.9 Step Over

在 Playwright Inspector(以及几乎所有代码调试器)中,Step Over 的意思是:单步跳过

复制代码
可以理解为,如脚本中有两条page.pause()语句,点击Step Over即跳过25行的调试进入到27行的调试;

4.10 Target

获取不同语言的脚本

4.11 Clear

顾名思义是清除已生成的脚本,初始化

4.12 Settings

设置这里可以选择主题,建议选择黑色主题,因为前面的按钮点击后不明显;

Generate assertions的意思是自动生成断言代码,默认不勾选

5. 存储状态复用

--save-storage=state.json

复制代码
# 录制登录并保存状态
playwright codegen --save-storage=login_state.json https://www.zhihu.com

# 后续测试加载状态
playwright codegen --load-storage=login_state.json https://www.zhihu.com

这里直接手机扫码,登录成功后,直接结束录制,可以发现登录态已经保存下来了;

通过加载本地保存登录的json,browser.new_context(storage_state="login_state.json")

复制代码
from playwright.sync_api import sync_playwright

def test_case():
    with sync_playwright() as p:
        browser = p.chromium.launch(headless=False)

        # ✅ 关键:加载本地Cookie文件,自动携带登录信息
        context = browser.new_context(storage_state="login_state.json")

        page = context.new_page()
        # 直接打开知h,已经是登录状态!
        page.goto("https://www.zhihu.com/")

        page.pause()  # 暂停查看效果
        browser.close()

可以看到能够直接携带登录态去访问页面了

复制代码
from playwright.sync_api import sync_playwright
import re

def test_case():
    with sync_playwright() as p:
        browser = p.chromium.launch(headless=False)

        # ✅ 关键:加载本地Cookie文件,自动携带登录信息
        context = browser.new_context(storage_state="login_state.json")

        page = context.new_page()
        # 直接打开知乎,已经是登录状态!
        page.goto("https://www.zhihu.com/", wait_until="networkidle")
        page.wait_for_timeout(3000)

        page.get_by_text("分享此刻的想法").click()
        page.get_by_role("textbox", name="标题").fill("test3")
        page.get_by_role("textbox").nth(1).fill("test3")
        page.get_by_role("button", name="发布").click()
        page.get_by_role("button", name="关闭").click()

        page.pause()  # 暂停查看效果
        browser.close()

6. 录制网络请求

6.1 录制HAR的意义

6.1.1 HAR 文件的三大核心意义

1)核心意义一:锁定环境,让测试不再"飘忽不定" (最最重要!)

这是 HAR 最大的用处。在没有 HAR 的情况下,你的自动化测试会依赖一个随时可能变化的后端。

  • 没有 HAR:今天后端接口返回"哪吒汽车创始人已成老赖",明天可能改成"哪吒汽车创始人已和解"。你的测试今天能过,明天就挂了。你不得不花时间去排查是代码问题还是后端数据变了。

  • 有了 HAR :你录下了今天这个返回"已成老赖"的响应。以后每次跑测试,Playwright 都会把这段录好的"已成老赖" 返回给页面。你的测试从此与后端解耦,永远稳定,不会再因为后端数据变化而出现莫名其妙的失败。

简单说:HAR 给你的测试加了一把"时间锁",锁住了那一刻的后端数据。

2)核心意义二:离线运行,让测试"快如闪电"
  • 没 HAR:每次测试都要真实地去请求网络,等待图片、CSS、JS、API 一个个加载完,速度受网速、服务器响应时间影响。

  • 有 HAR :所有数据都从你电脑硬盘上的 HAR 文件读取,速度比真实网络快几倍甚至几十倍。而且你可以彻底断开网线,测试依然能跑得飞快。

简单说:HAR 把你的测试从"在线视频"变成了"本地缓存",随看随有,从不卡顿。

3)核心意义三:协作与复现,让 Bug "无处遁形"
  • 复现线上Bug:线上出了个 Bug,你可以在本地录制一个包含 Bug 的 HAR,然后把 HAR 文件发给同事。同事不需要配置任何后端环境,直接重放,就能在你电脑上看到一模一样的 Bug 现场,极大方便了调试。

  • 前后端分离开发 :前端开发时,后端接口还没写好。前端可以先用 Mock 工具录一份假数据生成 HAR,然后基于这个 HAR 写自己的 UI 测试。等后端接口好了,再把 update=False 改成 update=True 跑一次,就能轻松切换到真实数据。

简单说:HAR 是一个可以随身携带、随时重放、永不消失的"现场快照"。

6.2 录制HAR参数作用

6.2.1 --save-har

--save-har 是 Playwright 命令行中指定 HAR 文件保存路径和名称的参数。

它的作用告诉 Playwright 把录制的网络请求保存到哪个文件中。

基本用法

复制代码
# 保存到当前目录下的 example.har
playwright open --save-har=example.har https://example.com

# 保存到指定文件夹
playwright open --save-har=./recordings/my-test.har https://example.com

# 保存为 zip 压缩格式(体积更小)
playwright open --save-har=example.har.zip https://example.com

6.2.2 --save-har-glob

--save-har-glob 是 Playwright 命令行工具的一个参数,用来过滤哪些网络请求应该被保存到 HAR 文件中

作用只保存匹配规则的请求,其他请求不保存。

这样可以:

  • 减少 HAR 文件大小

  • 只关注你关心的 API 请求

  • 避免保存图片、CSS、JS 等静态资源

    只保存包含 /api/ 的请求

    playwright open --save-har=example.har --save-har-glob="/api/" https://example.com

    只保存特定域名的请求

    playwright open --save-har=example.har --save-har-glob="/zhihu.com/" https://www.zhihu.com

    只保存 JSON 请求(常见写法)

    playwright open --save-har=example.har --save-har-glob="**/*.json" https://example.com

通配符规则

模式 匹配什么
**/api/** URL 中任意位置包含 /api/ 的请求
**/*.json .json 结尾的请求
https://api.example.com/** 特定域名下的所有请求
**/user/** 包含 /user/ 的请求
** 匹配所有请求(默认行为)
6.2.2.1 实际例子
1)例子1:只保存知乎的 API 请求
复制代码
playwright open --save-har=zhihu.har --save-har-glob="**/api/**" https://www.zhihu.com

这样只会保存类似这些请求:

  • https://www.zhihu.com/api/v3/feed

  • https://www.zhihu.com/api/v4/questions

  • https://static.zhihu.com/css/main.css(不保存)

  • https://picx.zhimg.com/image.jpg(不保存)

2)例子2:保存多个模式(使用多次参数)
复制代码
playwright open --save-har=example.har \
  --save-har-glob="**/api/**" \
  --save-har-glob="**/graphql" \
  https://example.com
3)例子3:排除某些请求(用感叹号)
复制代码
# 保存所有请求,但不保存图片
playwright open --save-har=example.har \
  --save-har-glob="**" \
  --save-har-glob="!**/*.jpg" \
  --save-har-glob="!**/*.png" \
  https://example.com
4)在 Python 代码中的对应方式

命令行参数对应 Python 中的 record_har_url_filter

复制代码
# 等价于 --save-har-glob="**/api/**"
context = browser.new_context(
    record_har_path="example.har",
    record_har_url_filter="**/api/**"  # 只保存 API 请求
)
5)常见使用场景
场景 推荐配置
测试后端 API --save-har-glob="**/api/**"
测试页面加载性能 不设置(保存所有)
减少 HAR 文件大小 排除图片、CSS、JS
6)验证是否生效

录制完成后,用文本编辑器打开 HAR 文件,搜索 "entries" 数组,里面应该只包含你指定模式的请求。

生成的HAR (HTTP Archive) 是一个 JSON 格式的文件,记录了:

  • 所有网络请求的 URL、方法、请求头

  • 所有网络响应的状态码、响应头、响应体

  • 请求和响应的时序信息

6.3 录制HAR示例

复制代码
# 打开浏览器并开始录制,将匹配 **/api/** 的请求保存到 example.har
# --save-har 参数即保存har文件
playwright open --load-storage=login_state.json --save-har=zhihu_example.har --save-har-glob="**/api/**" https://www.zhihu.com

当前录制har文件的数据内容展示

修改har文件数据验证下断言

复制代码
#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
# 文件名:zhihu_dy.py
# 作者:Administrator
# 日期:2026/4/23
# 描述:
from playwright.sync_api import sync_playwright, expect

def test_case1():
    with sync_playwright() as p:
        browser = p.chromium.launch(headless=False)

        # ✅ 关键:加载本地Cookie文件,自动携带登录信息
        context = browser.new_context(storage_state="login_state.json")
        page = context.new_page()

        # 关键点:告诉 Playwright 用 example.har 文件里的数据来响应匹配的请求
        # update=False 表示直接使用已存好的 HAR 数据,不再发真实网络请求
        page.route_from_har("zhihu_example.har", url="*/**/api/**", update=False)

        page.goto("https://www.zhihu.com")
        # 后续页面上触发的符合条件的请求,都会用 HAR 文件里的数据返回
        # 因此你可以正常做 UI 断言,比如:
        # page.screenshot(path="before_assert.png")
        expect(page.get_by_text("哪吒汽车创始人已成老赖2")).to_be_visible()


        page.pause()  # 暂停查看效果

        browser.close()

可以看到修改的响应内容,在页面上展示出来了

断言也是成功的

复制代码
# update=False 表示直接使用已存好的 HAR 数据,不再发真实网络请求
page.route_from_har("zhihu_example.har", url="*/**/api/**", update=False)
步骤 作用 操作 代码设置
1️⃣ 录制 录制模式 :发真实网络请求,并把请求/响应写入 HAR 文件 跑一次 update=True,生成/更新 HAR 文件 route_from_har(..., update=True)
2️⃣ 重放 重放模式 :不从真实网络请求,直接从 HAR 文件读取响应 update=False,跑测试 route_from_har(..., update=False)

7. 录制功能好处

7.1 快速生成登录脚本

登录是大多数系统的基础流程,录制功能可以帮你快速生成包含验证码处理、Cookie 管理的完整登录脚本。

7.2 复杂表单提交

对于包含多级表单、动态字段、文件上传的复杂页面,录制功能可以准确记录每一步操作,避免手动编写时遗漏步骤。

7.3 页面交互调试

当你不确定某个元素的定位方式或操作方法时,录制功能可以帮你快速获取正确的代码片段。

7.4 跨浏览器兼容性测试

通过--browser参数,分别录制不同浏览器的操作,快速生成跨浏览器测试用例。

8. 常见问题与解决方案

8.1 录制的脚本运行失败

原因:页面元素动态变化、选择器不稳定、网络延迟

解决方案

  • 优化选择器,使用更稳定的定位方式
  • 添加显式等待,确保元素加载完成
  • 启用--slowmo=1000参数,慢动作录制,便于观察执行过程

8.2 录制的代码冗余

解决方案

  • 删除不必要的操作步骤
  • 合并重复的元素定位
  • 提取公共方法,提高代码复用性

8.3 无法录制某些操作

原因:部分浏览器原生对话框、文件选择框等无法通过常规方式录制

解决方案

  • 使用 Playwright 的 API 手动处理:page.on("dialog", lambda dialog: dialog.accept())
  • 对于文件上传,使用page.set_input_files("input[type=file]", "path/to/file")

9. 总结

录制功能是辅助工具 而非替代方案。最佳实践是:录制生成原型 → 手动优化 → 封装复用,让自动化测试既高效又可靠。

相关推荐
conti1232 小时前
水题记录2.4
c++·笔记·题解
做cv的小昊2 小时前
【TJU】研究生应用统计学课程笔记(4)——第二章 参数估计(2.1 矩估计和极大似然估计、2.2估计量的优良性原则)
人工智能·笔记·考研·数学建模·数据分析·excel·概率论
叹一曲当时只道是寻常2 小时前
memos-cli 安装与使用教程:将 Memos 笔记同步到本地并支持 AI 语义搜索
人工智能·笔记·golang
寒秋花开曾相惜3 小时前
(学习笔记)4.1 Y86-64指令集体系结构(4.1.6 一些Y86-64指令 )
linux·运维·服务器·开发语言·笔记·学习·安全
烛之武3 小时前
《深度学习基础与概念》笔记(1)
人工智能·笔记·深度学习
RainCity3 小时前
Java Swing 自定义组件库分享(二)
java·笔记
皮肤科大白4 小时前
X-AnyLabeling +9.5 G Medsam3全流程接入笔记
pytorch·笔记·深度学习
噜噜噜阿鲁~4 小时前
python学习笔记 | 7.2、高级特性-迭代
笔记·python·学习
yuezhilangniao4 小时前
tshark + tcpdump 入门实战笔记:从网站分析到 DDoS 模拟
笔记·ddos·tcpdump