《最新出炉》系列初窥篇-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其他定位器
对于不太常用的定位器,请查看官网的其他定位器指南。由于时间关系,宏哥就不在这里对其进行展开介绍和讲解了。好了时间不早了,关于元素定位大法今天就分享到这里!!!仅供大家学习参考,感谢您耐心的阅读。
《最新出炉》系列初窥篇-Python+Playwright自动化测试-6-元素定位大法-下篇的更多相关文章
- 《手把手教你》系列技巧篇(十五)-java+ selenium自动化测试-元素定位大法之By xpath中卷(详细教程)
1.简介 按宏哥计划,本文继续介绍WebDriver关于元素定位大法,这篇介绍定位倒数二个方法:By xpath.xpath 的定位方法, 非常强大. 使用这种方法几乎可以定位到页面上的任意元素. ...
- 《手把手教你》系列技巧篇(八)-java+ selenium自动化测试-元素定位大法之By id(详细教程)
1.简介 从这篇文章开始,要介绍web自动化核心的内容,也是最困难的部分了,就是:定位元素,并去对定位到的元素进行一系列相关的操作.想要对元素进行操作,第一步,也是最重要的一步,就是要找到这个元素,如 ...
- 《手把手教你》系列技巧篇(十)-java+ selenium自动化测试-元素定位大法之By class name(详细教程)
1.简介 按宏哥计划,本文继续介绍WebDriver关于元素定位大法,这篇介绍By ClassName.看到ID,NAME这些方法的讲解,小伙伴们和童鞋们应该知道,要做好Web自动化测试,最好是需要了 ...
- 《手把手教你》系列技巧篇(十四)-java+ selenium自动化测试-元素定位大法之By xpath上卷(详细教程)
1.简介 按宏哥计划,本文继续介绍WebDriver关于元素定位大法,这篇介绍定位倒数二个方法:By xpath.xpath 的定位方法, 非常强大. 使用这种方法几乎可以定位到页面上的任意元素. ...
- 《手把手教你》系列技巧篇(十六)-java+ selenium自动化测试-元素定位大法之By xpath下卷(详细教程)
1.简介 按宏哥计划,本文继续介绍WebDriver关于元素定位大法,这篇介绍定位倒数二个方法:By xpath.xpath 的定位方法, 非常强大. 使用这种方法几乎可以定位到页面上的任意元素. ...
- 《手把手教你》系列技巧篇(十七)-java+ selenium自动化测试-元素定位大法之By css上卷(详细教程)
1.简介 CSS定位方式和xpath定位方式基本相同,只是CSS定位表达式有其自己的格式.CSS定位方式拥有比xpath定位速度快,且比CSS稳定的特性.下面详细介绍CSS定位方式的使用方法.xpat ...
- 《手把手教你》系列技巧篇(十八)-java+ selenium自动化测试-元素定位大法之By css中卷(详细教程)
1.简介 按计划今天宏哥继续讲解倚天剑-css的定位元素的方法:ID属性值定位.其他属性值定位和使用属性值的一部分定位(这个类似xpath的模糊定位). 2.常用定位方法(8种) (1)id(2)na ...
- 《手把手教你》系列技巧篇(十九)-java+ selenium自动化测试-元素定位大法之By css下卷(详细教程)
1.简介 按计划今天宏哥继续讲解css的定位元素的方法.但是今天最后一种宏哥介绍给大家,了解就可以了,因为实际中很少用. 2.常用定位方法(8种) (1)id(2)name(3)class name( ...
- 《手把手教你》系列技巧篇(十一)-java+ selenium自动化测试-元素定位大法之By tag name(详细教程)
1.简介 按宏哥计划,本文继续介绍WebDriver关于元素定位大法,这篇介绍By ClassName.看到ID,NAME这些方法的讲解,小伙伴们和童鞋们应该知道,要做好Web自动化测试,最好是需要了 ...
- [python爬虫] Selenium常见元素定位方法和操作的学习介绍(转载)
转载地址:[python爬虫] Selenium常见元素定位方法和操作的学习介绍 一. 定位元素方法 官网地址:http://selenium-python.readthedocs.org/locat ...
随机推荐
- python中的类继承
""" """ class Animal(object): def __init__(self,name,food): self.name ...
- Vulnhub Development Walkthrough
Vulnhub Development Walkthrough Recon 首先使用netdiscover进行二层Arp扫描. ┌──(kali㉿kali)-[~] └─$ sudo netdisco ...
- token验证
token验证 什么是token?我相信很多开发者都或多或少听过基于 token 的用户鉴权和基于 session 的用户鉴权,而今天说的 token 验证就是第一种了.token 的意思是" ...
- 【LeetCode动态规划#12】详解买卖股票I~IV,经典dp题型
买卖股票的最佳时机 力扣题目链接(opens new window) 给定一个数组 prices ,它的第 i 个元素 prices[i] 表示一支给定股票第 i 天的价格. 你只能选择 某一天 买入 ...
- 一文教你如何使用Node进程管理工具-pm2
pm2 是什么 pm2 是一个守护进程管理工具,它能帮你守护和管理你的应用程序.通常一般会在服务上线的时候使用 pm2 进行管理.pm2 能做的其实有很多,比如监听文件改动自动重启,统一管理多个进程, ...
- FLV文件分析
很久没看,做下关于FLV文件格式知识点回顾! 一.简单介绍 FLV(Flash Video)是Adobe公司推出的一种媒体封装格式.一个FLV文件,每个Tag类型都属于一个流.也就是说一 ...
- 聊一聊redis十种数据类型及底层原理
概述 Redis 是一个开源的高性能键值数据库,它支持多种数据类型,可以满足不同的业务需求.本文将介绍 Redis 的10种数据类型,分别是 string(字符串) hash(哈希) list(列表) ...
- thinkphp常量定义
是已经封装好的系统常量 主要是用在控制器下面的动作当中 这样能很大的提高我们的开发效率主要有下面的一些 手册上面都有的 __ROOT__ 网站的根目录 __APP__ 代表项目 ...
- JavaWeb之day01html
目录: 1.html简介 - html的操作思想(*****) 2.文字标签和注释标签 3.标题标签.水平线标签和特殊字符 4.列表标签 5.图像标签(********) 6.路径介绍(相对路径*** ...
- 2022-05-23:给定一个数组arr,你可以随意挑选其中的数字, 但是你挑选的数中,任何两个数a和b,必须Math.abs(a - b) > 1。 返回你最多能挑选几个数。 来自美团。
2022-05-23:给定一个数组arr,你可以随意挑选其中的数字, 但是你挑选的数中,任何两个数a和b,必须Math.abs(a - b) > 1. 返回你最多能挑选几个数. 来自美团. 答案 ...