96SEO 2026-02-19 11:59 16
。

此篇博客将从源码层面上梳理playwright录制原理。
当打开playwright
vscode插件时#xff0c;点击录制按钮#xff0c;会开启一个新浏览器#xff0c;如下图所示#xff0c;在新开浏览器页…
在上一篇博客中介绍了如何从0构建一款具备录制UI测试的小工具。
此篇博客将从源码层面上梳理playwright录制原理。
当打开playwright
vscode插件时点击录制按钮会开启一个新浏览器如下图所示在新开浏览器页面上有录制查看等按钮。
查看vscode的源码会看到有个recorder的folder该folder下由react构建了一个应用的UI执行npm
dev在5173端口启动这样一个web应用web应用的UI如下图所示可以看到里面的录制按钮等和上图vscode插件大家的相同。
从这里可以推断recorder里面用react构建的componen被嵌入到了开启的浏览器中。
通过上一篇博客的介绍我们知道实现录制功能的核心原理是是在浏览器中注入了脚本通过监听用户行为并将用户行为转换为playwright的语法从而实现录制脚本的能力。
code在playwright-core/src/server/injected目录下就是注入脚本相关的内容。
查看injected/recorder/recorder.ts脚本在该脚本中在interface
RecordTool中定义了大量操作页面元素的方法例如onClickonInput等。
在recorder.ts中在document对象上添加了很多listener如下图所示
具体每个listener完成了哪些逻辑呢以onInput为例子下面的onInput方法的部分代码可以看到首先是获取Input的目标对象target再依次判断Input的具体属性例如时textarea或者select或者checkbox等。
根据判断的结果返回不同的内容。
下面是playwright中生产locator的一个function可以看到通过注入脚本injectedScript._evaluator.begin()开始这段代码的主要作用是为指定的HTML元素生成一个或多个唯一的CSS选择器并返回相关的选择器和匹配的元素列表以便用于自动化测试或其他需要唯一定位元素的场景。
首先是初始化开始评估选择器生成过程启用ARIA缓存。
如果选项中包含
forTextExpect则会尝试为目标元素生成一个带有文本的选择器。
否则首先尝试在目标元素的父元素或影子宿主中找到符合特定角色如按钮、链接等的元素。
然后根据是否允许多个选择器生成一个或多个选择器可能包含或不包含文本和CSS
ID。
生成locator结束后使用Set去重生成的选择器列表确保唯一性。
最后返回结果。
可以看到为了生成合理的locatorplaywright进行很多逻辑处理来保证生成locator的唯一性和合理性。
generateSelector(injectedScript:
{injectedScript._evaluator.begin();beginAriaCaches();try
targetElement.ownerDocument.documentElement,
parentElementOrShadowHost(element))
generateSelectorFor(injectedScript,
closestCrossShadow(targetElement,
button,select,input,[rolebutton],[rolecheckbox],[roleradio],a,[rolelink],
generateSelectorFor(injectedScript,
generateSelectorFor(injectedScript,
id.cacheAllowText.clear();cacheDisallowText.clear();if
hasCSSIdToken(withText))tokens.push(generateSelectorFor(injectedScript,
hasCSSIdToken(withoutText))tokens.push(generateSelectorFor(injectedScript,
(hasCSSIdToken(css))tokens.push(cssFallback(injectedScript,
generateSelectorFor(injectedScript,
[joinTokens(targetTokens)];}}const
injectedScript.parseSelector(selector);return
injectedScript.querySelectorAll(parsedSelector,
targetElement.ownerDocument)};}
{cacheAllowText.clear();cacheDisallowText.clear();endAriaCaches();injectedScript._evaluator.end();}
定义在injectedScript.js中的generateSelector方法实际在recorder.ts中被调用。
下图是recorder.ts中onMouseMove方法的完整代码。
可以看到通过注入脚本playwright获取到了目标对象event将event作为参数传入方法中在生成selector部分就是通过injectedScript.generateSelector生成的。
this._recorder.deepEventTarget(event);if
target)return;this._hoveredElement
this._recorder.injectedScript.generateSelector(this._hoveredElement,
this._recorder.state.testIdAttributeName,
generated.elements,tooltipText:
this._recorder.injectedScript.utils.asLocator(this._recorder.state.language,
generated.selector),tooltipFooter:
model?.selector)return;this._hoveredModel
selectors;this._recorder.updateHighlight(model,
上面大致解释了playwright如何通过注入脚本的方式来录制脚本接下来看看playwright是如何启动浏览器的。
在util/protocol-types-generator下有很多代码这里就是playwright自己实现的管理整个浏览器生命周期的代码。
以上就是playwright实现录制的大致过程。
当调用playwright的功能录制到页面内容后再调用vscode插件的textedit对象将生成的内容写入当前打开的测试文件中即可。
playwright是一个非常强大的工具源代码相对比较复杂如果要快速理解如何通过注入脚本实现录制功能可以参考上一篇博客他们在实现思路上是一致的。
上一遍博客直接调用puppeteer来启动浏览器playwright是完全自己实现了浏览器整个生命周期管理会更加复杂一些。
作为专业的SEO优化服务提供商,我们致力于通过科学、系统的搜索引擎优化策略,帮助企业在百度、Google等搜索引擎中获得更高的排名和流量。我们的服务涵盖网站结构优化、内容优化、技术SEO和链接建设等多个维度。
| 服务项目 | 基础套餐 | 标准套餐 | 高级定制 |
|---|---|---|---|
| 关键词优化数量 | 10-20个核心词 | 30-50个核心词+长尾词 | 80-150个全方位覆盖 |
| 内容优化 | 基础页面优化 | 全站内容优化+每月5篇原创 | 个性化内容策略+每月15篇原创 |
| 技术SEO | 基本技术检查 | 全面技术优化+移动适配 | 深度技术重构+性能优化 |
| 外链建设 | 每月5-10条 | 每月20-30条高质量外链 | 每月50+条多渠道外链 |
| 数据报告 | 月度基础报告 | 双周详细报告+分析 | 每周深度报告+策略调整 |
| 效果保障 | 3-6个月见效 | 2-4个月见效 | 1-3个月快速见效 |
我们的SEO优化服务遵循科学严谨的流程,确保每一步都基于数据分析和行业最佳实践:
全面检测网站技术问题、内容质量、竞争对手情况,制定个性化优化方案。
基于用户搜索意图和商业目标,制定全面的关键词矩阵和布局策略。
解决网站技术问题,优化网站结构,提升页面速度和移动端体验。
创作高质量原创内容,优化现有页面,建立内容更新机制。
获取高质量外部链接,建立品牌在线影响力,提升网站权威度。
持续监控排名、流量和转化数据,根据效果调整优化策略。
基于我们服务的客户数据统计,平均优化效果如下:
我们坚信,真正的SEO优化不仅仅是追求排名,而是通过提供优质内容、优化用户体验、建立网站权威,最终实现可持续的业务增长。我们的目标是与客户建立长期合作关系,共同成长。
Demand feedback