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

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.hqwc.cn/news/315118.html

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

相关文章

Java:socket编程

目录 1、主程序 2、socket任务类 3、jdbc任务类 4、tomcat-jdbc连接池 5、jar包依赖 1、主程序 创建2个线程池&#xff0c;一个用于管理socket连接&#xff0c;一个用来管理jdbc连接。 package socket;import java.io.IOException; import java.net.ServerSocket; import…

深度学习核心技术与实践之自然语言处理篇

非书中全部内容&#xff0c;只是写了些自认为有收获的部分。 自然语言处理简介 NLP的难点 &#xff08;1&#xff09;语言有很多复杂的情况&#xff0c;比如歧义、省略、指代、重复、更正、倒序、反语等 &#xff08;2&#xff09;歧义至少有如下几种&#xff1a; …

一篇文章掌握系统架构的演变和常见微服务框架

目录 前言 一、系统架构的演变 1、单体应用架构 优点&#xff1a; 缺点&#xff1a; 2、垂直应用架构 优点&#xff1a; 缺点&#xff1a; 3、分布式SOA架构 3.1 什么是SOA 3.2 SOA架构 优点&#xff1a; 缺点&#xff1a; 4、微服务架构 优点&#xff1a; 缺点…

【活动回顾】ABeam 德硕 | 企业座谈及宣讲会--石河子大学专场

ABeam 石河子大学校招之旅 沙漠绿洲&#xff0c;戈壁明珠 近日&#xff0c;ABeam大中华区董事长兼总经理中野洋辅先生带领西安招聘团队来到新疆维吾尔自治区石河子市——石河子大学&#xff0c;与信息科学与技术学院领导就校企合作事宜进行了深入的座谈交流&#xff0c;并在随…

排序算法之快速排序

快速排序是一种高效的排序算法&#xff0c;它的基本思想是采用分治策略&#xff0c;将一个无序数组分割成两个子数组&#xff0c;分别对子数组进行排序&#xff0c;然后将两个排序好的子数组合并成一个有序数组。快速排序的性能优于归并排序&#xff0c;尤其在处理大规模数据时…

代表团坐车 - 华为OD统一考试

OD统一考试&#xff08;B卷&#xff09; 分值&#xff1a; 100分 题解&#xff1a; Java / Python / C 题目描述 某组织举行会议&#xff0c;来了多个代表团同时到达&#xff0c;接待处只有一辆汽车可以同时接待多个代表团&#xff0c;为了提高车辆利用率&#xff0c;请帮接待…

网络安全的红利还能吃几年?

一般人就别来凑热闹了&#xff0c;技术和嘴皮子都不硬混不出头的&#xff0c;干几年安服仔到时候跑都没处跑&#xff0c;行业和红利都会长久存在&#xff0c;但是能吃到的有多少就不好说了&#xff0c;92出身热爱或者技术过硬热爱尽管往里进&#xff0c;没出身没技术想wlb的建议…

Attention机制

前置知识&#xff1a;RNN&#xff0c;LSTM/GRU 提出背景 Attention模型是基于Encoder-Decoder框架提出的。Encoder-Decoder框架&#xff0c;也就是编码-解码框架&#xff0c;主要被用来处理序列-序列问题。 Encoder&#xff1a;编码器&#xff0c;将输入的序列<x1,x2,x3……

脆弱的SSL加密算法漏洞原理以及修复方法

漏洞名称&#xff1a;弱加密算法、脆弱的加密算法、脆弱的SSL加密算法、openssl的FREAK Attack漏洞 漏洞描述&#xff1a;脆弱的SSL加密算法&#xff0c;是一种常见的漏洞&#xff0c;且至今仍有大量软件支持低强度的加密协议&#xff0c;包括部分版本的openssl。其实&#xf…

信息安全评估

评估基础 安全评估是什么? 是针对潜在影响正常执行其职能的行为产色产生干扰或破坏的因素进行识别、评价的过程 广义上是综合的包括测试、检测、测评、审核、评估检查等进行综合评价和预测&#xff1b;狭义的就是某个信息安全风险风评 为什么要做安全评估&#xff1f; 是…

k8s 陈述式资源管理

k8s 陈述式资源管理 命令行&#xff1a;kubectl命令行工具 优点&#xff1a;90%以上的场景都可以满足 对资源的增&#xff0c;删&#xff0c;查比较方便&#xff0c;对改不是很友好 缺点&#xff1a; 命令比较冗长&#xff0c;复杂难记 声明式&#xff1a; k8s当中的yaml…

25计算机专业考研经验贴之准备篇

Hello各位小伙伴&#xff0c;大家新年好&#xff01; 马上就要进入寒假假期了&#xff0c;25考研也该提上日程了。今天先跟大家分享一下大家在假期可以先做起来的准备工作。 【选择学校】 择校是个非常重要的内容&#xff0c;因为不同学校的考试内容是不一样的&#xff0c;有些…