《最新出炉》系列初窥篇-Python+Playwright自动化测试-6-元素定位大法-下篇

news2024/11/25 3:23:44

1.简介

上一篇主要是讲解我们日常工作中在使用Playwright进行元素定位的一些比较常用的定位方法的理论基础知识以及在什么情况下推荐使用。今天这一篇讲解和分享一下,在日常中很少用到或者很少见的定位,但是遇到了我们也要会,俗话说:手里有粮心里不慌。

2.阴影定位-Shadow DOM

在做web自动化的时候,一些元素在shadow-root的节点下,使得playwright中无法通过xpath来定位

上面所看到的shadow-root标签其实就是一个shadowDOM,那么什么是shadowDOM呢?

他是前端的一种页面封装技术,可以将shadowDOM视为“DOM中的DOM”(可以看成一个隐藏的DOM)

他是一个独立的DOM树,具有自己的元素和样式,与原始文档DOM完全隔离。

shadowDOM必须附在一个HTML元素中,存放shadowDOM的元素,我们可以把它称为宿主元素。在HTML5中有很多的标签样式都是通过shadowDOM来实现的。

比如:日期选择框,音频播放标签,视频播放标签都自带了样式;(这种封装对于前端开发来说虽好,但是我们测试人员在做web自动给的时候就会遇到一些问题,shadowDOM中的标签无法定位。)

默认情况下,Playwright 中的所有定位器都使用 Shadow DOM 中的元素。例外情况是:

  • 通过 XPath 定位不会刺穿阴影根部。
  • 不支持闭合模式影子根。

例如:以下示例和自定义 Web 组件:

<x-details role=button aria-expanded=true aria-controls=inner-details>
  <div>Title</div>
  #shadow-root
    <div id=inner-details>Details</div>
</x-details>

您可以采用与影子根根本不存在相同的方式进行定位。

要单击 :<div>Details</div>

page.get_by_text("Details").click()

要单击 :<x-details>

page.locator("x-details", has_text="Details" ).click()

要确保包含文本“详细信息”,请执行以下操作:<x-details>

expect(page.locator("x-details")).to_contain_text("Details")

3.过滤器定位-Filtering

例如以下 DOM 结构,我们要在其中单击第二个产品卡的购买按钮。我们有几个选项来过滤定位器以获得正确的定位器。

3.1文本过滤

定位器可以使用 locator.filter()方法按文本进行过滤。它将搜索元素内某处的特定字符串,可能在后代元素中,不区分大小写。您还可以传递正则表达式。

1.使用文本

page.get_by_role("listitem").filter(has_text="Product 2").get_by_role(
    "button", name="Add to cart"
).click()

2.使用正则表达式

page.get_by_role("listitem").filter(has_text=re.compile("Product 2")).get_by_role(
    "button", name="Add to cart"
).click()

3.通过没有文本进行筛选

# 5 in-stock items
expect(page.get_by_role("listitem").filter(has_not_text="Out of stock")).to_have_count(5)
3.2子项/后代过滤

定位器支持仅选择具有或没有与其他定位器匹配的后代的元素的选项。因此,您可以按任何其他定位器进行过滤,例如 locator.get_by_role()、locator.get_by_test_id()、locator.get_by_text() 等。

1.使用子项

page.get_by_role("listitem").filter(
    has=page.get_by_role("heading", name="Product 2")
).get_by_role("button", name="Add to cart").click()

2.使用产品卡断言,确保只有一个

expect(
    page.get_by_role("listitem").filter(
        has=page.get_by_role("heading", name="Product 2")
    )
).to_have_count(1)

3.通过内部没有匹配的元素进行过滤

expect(
    page.get_by_role("listitem").filter(
        has_not=page.get_by_role("heading", name="Product 2")
    )
).to_have_count(1)

敲黑板!!!!注意:内部定位器从外部定位器开始匹配,而不是从文档根目录匹配。

3.3匹配其他定位进行过滤

方法 locator.and_() 通过匹配其他定位器来缩小现有定位器的范围。例如,您可以组合 page.get_by_role() 和 page.get_by_title() 以按角色和头衔进行匹配。

button = page.get_by_role("button").and_(page.getByTitle("Subscribe"))

4.链接定位器

您可以链接创建定位器的方法(如 page.get_by_text() 或 locator.get_by_role()),以将搜索范围缩小到页面的特定部分。

在此示例中,我们首先通过定位其角色:listitem 来创建一个名为 product 的定位器。然后我们按文本过滤。我们可以再次使用产品定位器按按钮的角色获取并单击它,然后使用断言来确保只有一个带有文本“产品 2”的产品。

product = page.get_by_role("listitem").filter(has_text="Product 2")

product.get_by_role("button", name="Add to cart").click()

您还可以将两个定位器链接在一起,例如在特定对话框中查找“保存”按钮:

save_button = page.get_by_role("button", name="Save")
# ...
dialog = page.get_by_test_id("settings-dialog")
dialog.locator(save_button).click()

5.列表

5.1对列表中的项目进行计数

可以断言定位器以对列表中的项目进行计数。例如:一下DOM结构

 使用计数断言确保列表包含 3 个项目。

expect(page.get_by_role("listitem")).to_have_count(3)
5.2断言列表中所有文本

可以断言定位器以查找列表中的所有文本。使用 expect(定位器).to_have_text() 确保列表包含文本“苹果”、“香蕉”和“橙色”。

expect(page.get_by_role("listitem")).to_have_text(["apple", "banana", "orange"])
5.3定位特定项目

有许多方法可以在列表中定位特定项目。

5.3.1通过文本定位

使用 page.get_by_text() 方法通过文本内容在列表中查找元素,然后单击它。

 通过文本内容找到项目并单击它。

page.get_by_text("orange").click()
5.3.2通过文本过滤定位

使用 locator.filter() 在列表中查找特定项目。按“列表项”的角色找到一个项目,然后按“橙色”的文本进行筛选,然后单击它。

page.get_by_role("listitem").filter(has_text="orange").click()
5.3.3通过测试id定位

使用 page.get_by_test_id() 方法在列表中查找元素。如果您还没有测试 ID,则可能需要修改 html 并添加测试 ID。

通过测试ID“橙色”找到项目,然后单击它。

page.get_by_test_id("orange").click()
5.3.4通过第n项定位

如果你有一个相同元素的列表,并且区分它们的唯一方法是顺序,你可以从带有 locator.first、locator.last 或 locator.nth() 的列表中选择一个特定的元素。

banana = page.get_by_role("listitem").nth(1)

但是,请谨慎使用此方法。通常,页面可能会更改,并且定位器将指向与预期完全不同的元素。相反,尝试提出一个通过严格标准的独特定位器。

5.4链接过滤器

当您有各种相似性的元素时,可以使用 locator.filter()方法选择正确的元素。您还可以链接多个筛选器以缩小选择范围。

 要截取带有“Mary”和“Say goodbye”的行的屏幕截图:

row_locator = page.get_by_role("listitem")

row_locator
    .filter(has_text="Mary")
    .filter(has=page.get_by_role("button", name="Say goodbye"))
    .screenshot(path="screenshot.png")
5.5罕见例子
5.5.1对列表中每个元素执行操作

迭代元素

for row in page.get_by_role("listitem").all():
    print(row.text_content())

使用常规 for 循环进行迭代:

rows = page.get_by_role("listitem")
count = rows.count()
for i in range(count):
    print(rows.nth(i).text_content())
5.5.2在页面中评估

locator.evaluate_all()中的代码在页面中运行,您可以在那里调用任何 DOM API。

rows = page.get_by_role("listitem")
texts = rows.evaluate_all("list => list.map(element => element.textContent)")

6.小结

定位器是非常严格。这意味着,如果多个元素匹配,则对定位器执行暗示某些目标 DOM 元素的所有操作都将引发异常。例如,如果 DOM 中有多个按钮,则会引发以下调用:

如果有多个button,则引发错误
page.get_by_role("button").click()

另一方面,Playwright 了解何时执行多元素操作,因此当定位器解析为多个元素时,以下调用工作正常。

适用于多个元素
page.get_by_role("button").count()

您可以通过 locator.first、locator.last 和 locator.nth() 告诉 Playwright 在多个元素匹配时使用哪个元素来明确选择退出严格性检查。不建议使用这些方法,因为当您的页面更改时,Playwright 可能会单击您不想要的元素。相反,请按照上述最佳实践创建唯一标识目标元素的定位器。

6.1其他定位器

对于不太常用的定位器,请查看官网的其他定位器指南。由于时间关系,宏哥就不在这里对其进行展开介绍和讲解了。好了时间不早了,关于元素定位大法今天就分享到这里!!!仅供大家学习参考,感谢您耐心的阅读。

 -每天学习一点,今后必成大神-

往期推荐(由于跳转参数丢失了,所有建议选中要访问的右键,在新标签页中打开链接即可访问):

Appium自动化系列,耗时80天打造的从搭建环境到实际应用精品教程测试

Python接口自动化测试教程,熬夜87天整理出这一份上万字的超全学习指南

Python+Selenium自动化系列,通宵700天从无到有搭建一个自动化测试框架

Java+Selenium自动化系列,仿照Python趁热打铁呕心沥血317天搭建价值好几K的自动化测试框架

Jmeter工具从基础->进阶->高级,费时2年多整理出这一份全网超详细的入门到精通教程

Fiddler工具从基础->进阶->高级,费时100多天吐血整理出这一份全网超详细的入门到精通教程

Pycharm工具基础使用教程

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

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

相关文章

Origin 2022软件安装包下载及安装教程

Origin 2022https://docs.qq.com/doc/DUklGWUhMVEZTbUVU 1、选中下载好的安装包&#xff0c;右键选择解压到“Origin 2022”文件夹 2、选中“Setup.exe”右键以管理员身份运行 3、点击“下一步” 4、选择“我接受……”&#xff0c;点击"下一步" 5、选择“安装origi…

Vue中全局事件总线的配置和原理

实现任意组件之间的通信 任意组件通信的原理&#xff1a; 1、实现任意组件之间的通信,需要一个傀儡。这个傀儡既能被vm访问到,也能被VueComponent访问。 2、VueComponent.prototype.proto Vue.prototype为图上1.0黄色的线路。是Vue让组件实例对象VueComponent可以访问到Vue原…

SSM学生成绩信息管理系统----计算机毕业设计

项目介绍 本项目分为管理员、教师、学生三种角色&#xff0c; 管理员角色包含以下功能&#xff1a; 公告管理,写公告,学生增删改查,教师增删改查,查看成绩报表,管理员首页,课程表增删改查等功能。 教师角色包含以下功能&#xff1a; 修改密码,按照条件查询,查看学生信息,管理…

【k8s】deamonset文件和说明

目录 deamonset的相关命令 deamonset的定义 deamonset的使用场景 deamonset的例子 deamonset字段说明 serviceAccountName DaemonSet的结构及其各个部分的作用 deamonset的相关命令 #查看<name-space>空间内有哪些deamonset kubectl get DaemonSet -n <na…

关于Python里xlwings库对Excel表格的操作(二十七)

这篇小笔记主要记录如何【如何使用xlwings库的“Charts类” 在一个工作表中创建多个图表】。前面的小笔记已整理成目录&#xff0c;可点链接去目录寻找所需更方便。 【目录部分内容如下】【点击此处可进入目录】 &#xff08;1&#xff09;如何安装导入xlwings库&#xff1b; &…

分布式定时任务Xxl_Job详细使用手册

看了很多网上的版本&#xff0c;思路描述的都不是很清晰&#xff0c;都只是几步操作就完成了&#xff0c;看效果&#xff0c;导致容易走入弯路&#xff08;不排除是自己理解能力把&#xff09;&#xff0c;最开始以为是把admin模块集成到项目&#xff0c;后来测试了会&#xff…

ubuntu terminator 非常好用的护眼配置

安装 sudo apt install terminator 配置文件&#xff1a;sudo gedit ~/.config/terminator/config &#xff08;如果没有就创建&#xff09; 配置如下&#xff1a; [global_config] handle_size -3 title_transmit_fg_color "#000000" title_trans…

YOLOv8训练损失、mAP画图功能 | 支持多结果对比,多结果绘在一个图片(科研必备)

一、本文介绍 本文给大家带来的是YOLOv8系列的绘图功能&#xff0c;我将向大家介绍YOLO系列的绘图功能。我们在进行实验时&#xff0c;经常需要比较多个结果&#xff0c;针对这一问题&#xff0c;我写了点代码来解决这个问题&#xff0c;它可以根据训练结果绘制损失(loss)和mA…

稳部落 – 新浪微博备份导出工具

稳部落 稳部落是新浪微博备份导出工具&#xff0c;可以帮助用户非常方便的导出备份新浪微博的数据&#xff0c;让我们可以永久保存这些微博数据。它支持新浪微博、微博私信、微博评论的导出&#xff0c;并可以备份包含图片、视频的完整微博内容。用户只需登录微博账号&#xf…

浅学一下哈

1.新建用户test不建家目录不允许登录&#xff0c;uid为10086_____________________ useradd -u 10086 -M -s /sbin/nologin 2.将 /opt 文件夹中所有文件的属主&#xff0c;属组改成&#xff0c;test_______________________ chown -R test.test /opt chown -R …

小红书、抖音、视频号下载工具:随心管理个人作品集 | 开源日报 No.134

karanpratapsingh/system-design Stars: 20.6k License: NOASSERTION 这个项目是关于系统设计的。它提供了有关系统设计的课程内容&#xff0c;包括 IP、OSI 模型、TCP 和 UDP 等主题。该项目的核心优势和特点如下&#xff1a; 提供全面而高效的系统架构定义。从基础设施到数…

【XR806开发板试用】FreeRTOS创建任务测试

这篇来学习下&#xff0c;XR806开发板在FreeRTOS系统下创建两个任务测试&#xff0c;由于没有找到学习的文档&#xff0c;试着参考例程来测试。 一、复制工程 上篇测试了hello_demo的测试例程&#xff0c;直接复制这个工程文件&#xff0c;在此基础上修改 rootubuntu:/home/…

C语言实验6:文件

目录 一、实验要求 二、实验原理 1. 文件的基本概念 2. 文件指针 3. 文件的打开与关闭 3.1 fopen 3.2 fclose 4. 文件的读写操作 4.1 fread 4.2 fwrite 5. 文件的定位 三、实验内容 3.1 文件复制 代码 截图 分析 3.2 单词统计 代码 截图 分析 一、实验要求…

流量预测_MLP模型_keras

目录 0、我在干什么&#xff1f;1、import libararies2、加载数据load data3、独家观察数据函数 :heartbeat:4、数据预处理pre-processing&#xff08;1&#xff09;将时间戳转换为一个日期时间索引&#xff08;2&#xff09;填充所有缺失的值&#xff08;3&#xff09;将时间序…

GPT如何完成技术路线图?

GPT如何完成技术路线图&#xff1f; 一OpenAI 1.最新大模型GPT-4 Turbo 2.最新发布的高级数据分析&#xff0c;AI画图&#xff0c;图像识别&#xff0c;文档API 3.GPT Store 4.从0到1创建自己的GPT应用 5. 模型Gemini以及大模型Claude2二定制自己的GPTs 1.自定义GPTs使用…

POC-700系列 支持多功能扩展的强固型无风扇嵌入式计算平台

POC-700系列是一款拥有小巧紧凑尺寸的无风扇嵌入式计算平台&#xff0c;搭载了英特尔 Alder Lake i3-N305或凌动 x7425E处理器&#xff0c;提供高达32个执行单元(EU) UHD图形功能&#xff0c;8核8线程&#xff0c;而其功耗非常低&#xff0c;仅为12W。POC-700系列可支持英特尔 …

2 - 表结构 | MySQL键值

表结构 | MySQL键值 表管理1. 库的操作2. 表的操作表的创建与删除表的修改复制表 3. 管理表记录 数据类型数值类型字符类型&#xff08;汉字或者英文字母&#xff09;日期时间类型 表头存储与日期时间格式的数据枚举类型 数据批量处理 表管理 客户端把数据存储到数据库服务器上…

Java项目:104SpringBoot就业管理系统

博主主页&#xff1a;Java旅途 简介&#xff1a;分享计算机知识、学习路线、系统源码及教程 文末获取源码 一、项目介绍 就业管理系统基于SpringBootMybatis开发&#xff0c;系统分为两种角色&#xff0c;分别是管理员和普通用户。 管理员功能如下&#xff1a; 就业信息管理…

一、医学影像云平台(AI赋能基层的最佳实践)

医学影像云平台&#xff0c;是一个目前影像业务中&#xff0c;各省市级领导比较重视的业务板块。因为&#xff0c;影像平台不但可以直接给原来没有PACS系统的1,2级医院提供PACS服务&#xff0c;还可以提供院间之间的业务&#xff0c;例如发送远程诊断&#xff0c;远程会诊业务&…

银行业绩数据监控大屏:驾驭金融海洋的航标

在金融领域&#xff0c;数据就是生命线。如何有效地监控和管理这些数据&#xff0c;确保银行业绩的稳健发展&#xff0c;已成为银行业内亟待解决的问题。而银行业绩数据监控大屏&#xff0c;正是解决这一问题的有力工具。 一、实时监控&#xff0c;把握业绩动态 银行业绩数据监…