深入解析:Playwright录制时的高亮实现机制分析

news/2025/9/24 9:53:02/文章来源:https://www.cnblogs.com/yfceshi/p/19108627

Playwright录制时的高亮实现机制分析

高亮功能的核心实现

Playwright在录制时通过一系列精心设计的DOM操作和CSS样式来实现元素高亮效果,让用户能够清晰地看到当前选中的元素。这一功能主要由以下几个核心组件组成:

1. Highlight类 - 高亮功能的核心引擎

Highlight类是高亮功能的核心实现,负责创建、管理和更新高亮元素:

class Highlight {
private _glassPaneElement: HTMLElement;
private _glassPaneShadow: ShadowRoot;
private _renderedEntries: RenderedHighlightEntry[] = [];
private _actionPointElement: HTMLElement;
// ...其他属性和方法
constructor(injectedScript: InjectedScript) {
this._injectedScript = injectedScript;
this._isUnderTest = injectedScript.isUnderTest;
// 创建玻璃面板作为覆盖层
this._glassPaneElement = injectedScript.document.createElement('x-pw-glass');
this._glassPaneElement.setAttribute('style', 'position:fixed;inset:0;z-index:2147483646;pointer-events:none;');
this._glassPaneShadow = this._glassPaneElement.attachShadow({ mode: 'open' });
// 创建动作点元素
this._actionPointElement = injectedScript.document.createElement('x-pw-action-point');
this._actionPointElement.hidden = true;
}
// 安装高亮样式和元素
install() {
// 添加CSS样式到shadow DOM
if (typeof this._glassPaneShadow.adoptedStyleSheets.push === 'function') {
const sheet = new this._injectedScript.window.CSSStyleSheet();
sheet.replaceSync(highlightCSS);
this._glassPaneShadow.adoptedStyleSheets.push(sheet);
} else {
const styleElement = this._injectedScript.document.createElement('style');
styleElement.textContent = highlightCSS;
this._glassPaneShadow.appendChild(styleElement);
}
this._glassPaneShadow.appendChild(this._actionPointElement);
this._injectedScript.document.documentElement.appendChild(this._glassPaneElement);
}
// 更新高亮显示
updateHighlight(entries: HighlightEntry[]) {
// 检查是否需要更新高亮
if (this._highlightIsUpToDate(entries))
return;
// 清除现有高亮
this.clearHighlight();
// 创建新的高亮元素
for (const entry of entries) {
const highlightElement = this._createHighlightElement();
this._glassPaneShadow.appendChild(highlightElement);
// 创建提示框(如果有文本)
let tooltipElement;
if (entry.tooltipText) {
tooltipElement = this._injectedScript.document.createElement('x-pw-tooltip');
this._glassPaneShadow.appendChild(tooltipElement);
// 设置提示框样式和内容
// ...
}
this._renderedEntries.push({
targetElement: entry.element,
color: entry.color,
tooltipElement,
highlightElement
});
}
// 计算位置并更新样式
// ...
}
}

2. 样式定义 - 高亮视觉效果

highlight.css文件定义了高亮元素的视觉样式,包括位置、尺寸、颜色和动画效果:

x-pw-glass {
position: fixed;
inset: 0;
z-index: 2147483646;
pointer-events: none;
}
x-pw-highlight {
position: absolute;
pointer-events: none;
}
x-pw-tooltip {
backdrop-filter: blur(5px);
background-color: white;
border-radius: 6px;
box-shadow: 0 0.5rem 1.2rem rgba(0,0,0,.3);
display: none;
/* ...其他样式 */
}
/* 其他相关样式 */

3. 录制器中的高亮集成

Recorder类中,高亮功能被集成到整个录制工作流程中,特别是在元素选择和断言创建过程中:

class Recorder {
// 创建高亮实例
constructor(injectedScript: InjectedScript, options?: { recorderMode?: 'default' | 'api' }) {
this.document = injectedScript.document;
this.injectedScript = injectedScript;
this.highlight = injectedScript.createHighlight();
// ...其他初始化
this.installListeners();
// ...
}
// 更新高亮
updateHighlight(model: HighlightModel | null, userGesture: boolean) {
this._lastHighlightedSelector = undefined;
this._lastHighlightedAriaTemplateJSON = 'undefined';
this._updateHighlight(model, userGesture);
}
// 内部高亮更新方法
private _updateHighlight(model: HighlightModel | null, userGesture: boolean) {
let tooltipText = model?.tooltipText;
if (tooltipText === undefined && model?.selector)
tooltipText = this.injectedScript.utils.asLocator(this.state.language, model.selector);
if (model)
this.highlight.updateHighlight(model.elements.map(element => ({ element, color: model.color, tooltipText })));
else
this.highlight.clearHighlight();
if (userGesture)
this._delegate.highlightUpdated?.();
}
// 清除高亮
clearHighlight() {
this.updateHighlight(null, false);
}
}

高亮工作流程详解

当用户使用Playwright录制器时,高亮功能的完整工作流程如下:

1. 初始化阶段

  1. InjectedScript类创建Highlight实例:

    createHighlight() {
    return new Highlight(this);
    }
  2. Recorder构造函数获取并安装高亮组件:

    this.highlight = injectedScript.createHighlight();
    // ...
    this.highlight.install();

2. 事件监听与处理

录制器监听鼠标移动、点击等事件,并根据当前模式更新高亮:

  1. 鼠标悬停高亮:当鼠标移动到元素上时,更新高亮显示

    onMouseMove(event: MouseEvent) {
    // ...
    const target = this._recorder.deepEventTarget(event);
    if (this._hoverHighlight?.elements[0] === target)
    return;
    // ...生成高亮模型
    this._recorder.updateHighlight(this._hoverHighlight, true);
    }
  2. 元素选择高亮:当用户选择元素时,保持高亮显示

    elementPicked(selector: string, model: HighlightModel) {
    const ariaSnapshot = this.injectedScript.ariaSnapshot(model.elements[0], { mode: 'expect'
    });
    void this._delegate.elementPicked?.({ selector, ariaSnapshot
    });
    }

3. 高亮更新与优化

Highlight类实现了多种优化机制来确保高亮显示的流畅性:

  1. 避免不必要的更新:检查当前高亮是否已经是最新状态

    private _highlightIsUpToDate(entries: HighlightEntry[]): boolean {
    if (entries.length !== this._renderedEntries.length)
    return false;
    for (let i = 0; i <
    this._renderedEntries.length;
    ++i) {
    if (entries[i].element !== this._renderedEntries[i].targetElement)
    return false;
    if (entries[i].color !== this._renderedEntries[i].color)
    return false;
    // 检查元素位置是否发生变化
    const oldBox = this._renderedEntries[i].box;
    if (!oldBox) return false;
    const box = entries[i].element.getBoundingClientRect();
    if (box.top !== oldBox.top || box.right !== oldBox.right ||
    box.bottom !== oldBox.bottom || box.left !== oldBox.left)
    return false;
    }
    return true;
    }
  2. 性能优化:批量更新DOM,减少重排重绘

    updateHighlight(entries: HighlightEntry[]) {
    // 代码注释中明确说明了优化策略
    // Code below should trigger one layout and leave with the
    // destroyed layout.
    // ...
    }

特殊高亮功能

除了基本的元素高亮外,Playwright还实现了一些特殊的高亮功能:

1. 不同状态的高亮颜色

根据不同的操作类型使用不同的高亮颜色:

2. 提示框显示

高亮元素时可以显示提示框,包含选择器信息:

// 生成提示文本
tooltipText = this.injectedScript.utils.asLocator(this.state.language, model.selector);
// 创建提示框
if (entry.tooltipText) {
tooltipElement = this._injectedScript.document.createElement('x-pw-tooltip');
// ...设置提示框样式和内容
}

3. 动作点标记

对于点击等操作,显示精确的点击位置:

showActionPoint(x: number, y: number) {
this._actionPointElement.style.left = x + 'px';
this._actionPointElement.style.top = y + 'px';
this._actionPointElement.hidden = false;
}
hideActionPoint() {
this._actionPointElement.hidden = true;
}

技术亮点与设计思路

  1. Shadow DOM隔离:使用Shadow DOM确保高亮样式不会影响页面原有样式,避免样式冲突

  2. 性能优化:通过减少不必要的DOM操作和布局计算,确保高亮流畅不卡顿

  3. 可访问性设计:合理的z-index和pointer-events设置,确保高亮层不影响页面交互

  4. 模块化设计:高亮功能与录制器核心逻辑分离,便于维护和扩展

  5. 跨浏览器兼容性:使用标准Web API,确保在不同浏览器中一致的表现

总结

Playwright录制时的高亮功能通过精心设计的DOM操作、CSS样式和JavaScript逻辑实现,为用户提供了直观的元素选择反馈。它采用了性能优化的方式处理高亮更新,并通过Shadow DOM确保样式隔离,是Playwright录制器用户体验的重要组成部分。

这种高亮机制不仅提升了用户体验,也提高了自动化测试脚本的编写效率和准确性,让用户能够精确地选择目标元素进行交互录制。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/915521.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

什么是文件外发审批?主要有哪几种关键流程?

文件外发审批是企业进行外部文档传输时不可或缺的一部分。它涵盖了从申请发起到文档送达后反馈的一系列环节。在申请阶段,员工需要利用Ftrans B2B企业间文件安全交换系统,准确填写申请信息以确保透明度和合规性。随后…

VPX处理板设计原理图:9-基于DSP TMS320C6678+FPGA XC7V690T的6U VPX信号处理卡 C6678板卡, XC7VX690T板卡, VPX处理板

基于DSP TMS320C6678+FPGA XC7V690T的6U VPX信号处理卡 一、概述本板卡基于标准6U VPX 架构,为通用高性能信号处理平台,系我公司自主研发。板卡采用一片TI DSP TMS320C6678和一片Xilinx公司Virtex 7系列的FPGA XC7V6…

Python入门—Mac如何搭建Python开发环境?

Python入门—Mac如何搭建Python开发环境?Python入门—Mac如何搭建Python开发环境?编程玉子 ​关注她14 人赞同了该文章随着Numpy、Scipy、Matplotlib和Pandas等众多程序库的开发,python在数据分析、数据挖掘、海量数…

织梦做网站简单吗高端网站建设公司排名

1.概述 封装&#xff08;Encapsulation&#xff09;是指一种将抽象性函式接口的实现细节部分包装、隐藏起来的方法。 封装可以被认为是一个保护屏障&#xff0c;防止该类的代码和数据被外部类定义的代码随机访问。 要访问该类的代码和数据&#xff0c;必须通过严格的接口控制…

VitePress 添加友链界面

效果预览友链数据存储 友链数据通常是经常需要添加和修改的,所以我们不能直接写死到页面上。这里我们单独提一个文件去存储友链数据,并且友链数据的格式基本也是类似的。 新建 docs/pages/links.md 文件,内容如下:…

跨网文件摆渡软件:企业数据安全高效传输的关键解决方案!

在数字化时代,企业为保障核心数据安全,普遍采用网络隔离策略,将内网与外网、研发网与办公网等不同网络环境分隔开来。然而,业务协同中跨网文件传输的需求始终存在,跨网文件摆渡软件应运而生。这类软件是专门用于在…

洛谷题单指南-进阶数论-P1495 【模板】中国剩余定理(CRT)/ 曹冲养猪

原题链接:https://www.luogu.com.cn/problem/P1495 题意解读:求方程组x ≡ bi (mod ai), i∈[1,n]的最小正整数解,所有的ai互质。 解题思路: 1、中国剩余定理 设方程组为(a1,a2,a3互质):x ≡ b1 (mod a1) x ≡…

第十四届蓝桥杯青少组C++选拔赛[2022.12.18]第二部分编程题(4、充电站) - 指南

第十四届蓝桥杯青少组C++选拔赛[2022.12.18]第二部分编程题(4、充电站) - 指南pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-…

界面控件DevExpress WinForms中文教程:Data Grid - 搜索/查找面板

界面控件DevExpress WinForms中文教程:Data Grid - 搜索/查找面板DevExpress WinForms拥有180+组件和UI库,能为Windows Forms平台创建具有影响力的业务解决方案。DevExpress WinForms能完美构建流畅、美观且易于使用…

c语言之自定义memcpy

void *Memcpy(void *dest, const void *src, size_t count) { cout<<"sizeof(dest)是:"<<sizeof(dest)<<endl;int bytelen=count/sizeof(dest); /*按CPU位宽拷贝*/int slice=count%si…

国产芯片处理板卡:7-基于国产化FT-M6678+JFM7K325T的6U CPCI信号处理卡

基于国产化FT-M6678+JFM7K325T的6U CPCI信号处理卡一、板卡概述本板卡系我公司自主研发,基于6U CPCI的通用高性能信号处理平台。板卡采用一片国产8核DSP FT-C6678和一片国产FPGA JFM7K325T-2FFG900作为主处理器。为您…

一文详解纷享销客CRM Agent平台3大核心能力(附应用场景与案例)

AI 技术加速渗透业务场景,智能体(Agent)已成为企业提效增长的关键工具 —— 它可助力销售快速掌握客户经营情况、辅助运营规避数据操作差错、帮助新人高效获取业务知识,在营销、销售、服务全链路实现 “数据洞察 -…

php网站开发实训总结东莞网络营销全网推广

简介&#xff1a;企业想要拥有领先的数据分析能力&#xff0c;自研往往需要投入巨大的人力和财力。 Quick BI作为唯一一个连续两年入选Gartner魔力象限的中国BI产品&#xff0c;具备强大的全链路开放集成能力&#xff0c;可以轻松的与企业原有系统匹配融合&#xff0c;帮助企业…

QOJ #5076. Prof. Pang and Ants 题解

Description 在庞教授的大房子边上,有一群包含 \(m\) 只蚂蚁的蚁群,居住在有 \(n\) 个洞口的洞穴里。 它们会外出寻找食物。食物在庞教授的大冰箱里,蚂蚁们试图从里面偷出食物来。 特别的, 一只蚂蚁需要 \(1\) 秒从…

微信小程序(uniapp)PDF预览完整实现方案

微信小程序(uniapp)PDF预览完整实现方案Posted on 2025-09-24 09:36 且行且思 阅读(0) 评论(0) 收藏 举报在微信小程序开发中,PDF文件预览是常见的业务需求。本文将提供一套基于uniapp的完整解决方案,涵盖从后…

发现5个宝藏文件摆渡系统 2025年企业首选的摆渡方案是这个!

文件摆渡系统作为解决网络隔离后业务交互的重要工具,其作用和价值不言而喻。不过对于企业的价值究竟是正面的,还是负面的,这就要看用的什么文件摆渡系统了。本文中我们就介绍5种文件摆渡系统,我们来看看首选的摆渡…

如何打开谷歌网站网站备案网站

文章目录 一、文档转换器 & 文本拆分器文本拆分器 二、开始使用文本拆分器三、按字符进行拆分四、代码分割 (Split code)1、PythonTextSplitter2、JS3、Markdown4、Latex5、HTML6、Solidity 五、MarkdownHeaderTextSplitter1、动机2、Use case 六、递归按字符分割七、按tok…

基金网站建设网站建设运营知识

移动应用程序开发的增长速度比以往任何时候都快。几乎每个企业都需要移动应用程序来保持市场竞争力。由于像 React Native 这样的跨平台移动应用程序开发框架允许公司使用单一源代码和单一编程语言构建 iOS 和 Android 应用程序&#xff0c; Flutter是 Google 支持的另一个热门…

BilldDesk:基于Vue3+WebRTC+Nodejs+Electron的开源远程桌面控制 - 详解

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

css-轮播图效果

<!DOCTYPE html> <html lang="zh-EN"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"&g…