《刚刚问世》系列初窥篇-Java+Playwright自动化测试-7-元素基础定位方式-下篇 (详细教程)
软件测试微信群:https://bbs.csdn.net/topics/618423372 有兴趣的可以扫码加入
1.简介
上一篇主要是讲解我们日常工作中在使用Playwright进行元素定位的一些比较常用的基础定位方式的理论基础知识以及在什么情况下推荐使用。今天这一篇讲解和分享一下剩下部分的基础定位方式。
2.过滤器定位
例如以下 DOM 结构,我们要在其中单击第二个产品卡的购买按钮。我们有几个选项来过滤定位器以获得正确的定位器。
2.1按文本过滤
定位器可以使用 locator.filter()方法按文本进行过滤。它将搜索元素内某处的特定字符串,可能在后代元素中,不区分大小写。您还可以传递正则表达式。
1.使用文本
page.getByRole(AriaRole.LISTITEM).filter(new Locator.FilterOptions().setHasText("Product 2")).getByRole(AriaRole.BUTTON,new Page.GetByRoleOptions().setName("Add to cart")).click();
2.使用正则表达式
page.getByRole(AriaRole.LISTITEM).filter(new Locator.FilterOptions().setHasText(Pattern.compile("Product 2"))).getByRole(AriaRole.BUTTON,new Page.GetByRoleOptions().setName("Add to cart")).click();
2.2按没有文本进行筛选
通过没有文本进行筛选:
// 5 in-stock items assertThat(page.getByRole(AriaRole.LISTITEM).filter(new Locator.FilterOptions().setHasNotText("Out of stock"))).hasCount(5);
2.3子项/后代过滤
定位器支持一个选项,即仅选择具有或没有与另一个定位器匹配的后代的元素的元素。因此,您可以按任何其他定位器进行过滤,例如 Locator.getByRole()、Locator.getByTestId()、Locator.getByText() 等。
page.getByRole(AriaRole.LISTITEM).filter(new Locator.FilterOptions().setHas(page.GetByRole(AriaRole.HEADING, new Page.GetByRoleOptions().setName("Product 2")))).getByRole(AriaRole.BUTTON,new Page.GetByRoleOptions().setName("Add to cart")).click()
我们还可以断言产品卡,以确保只有一个:
assertThat(page.getByRole(AriaRole.LISTITEM).filter(new Locator.FilterOptions().setHas(page.GetByRole(AriaRole.HEADING,new Page.GetByRoleOptions().setName("Product 2")))).hasCount(1);
过滤定位器必须相对于原始定位器进行查询,并且从原始定位器匹配项开始进行查询,而不是从文档根开始进行查询。因此,以下操作将不起作用,因为过滤定位器从列表元素开始匹配,该列表元素位于原始定位器匹配的列表项之外:<ul>
<li>
// ✖ WRONG assertThat(page.getByRole(AriaRole.LISTITEM).filter(new Locator.FilterOptions().setHas(page.GetByRole(AriaRole.LIST).GetByRole(AriaRole.HEADING,new Page.GetByRoleOptions().setName("Product 2")))).hasCount(1);
2.4按没有子项/后代过滤
我们也可以通过内部没有匹配的元素来过滤。
assertThat(page.getByRole(AriaRole.LISTITEM).filter(new Locator.FilterOptions().setHasNot(page.getByText("Product 2"))).hasCount(1);
敲黑板!!!!请注意,内部定位器是从外部定位符开始匹配的,而不是从文档根目录开始匹配的。
3.定位器操作员
3.1定位器内部匹配
您可以链接创建定位器的方法,例如 Page.getByText() 或 Locator.getByRole(),以将搜索范围缩小到页面的特定部分。
在此示例中,我们首先通过定位其角色listitem来创建一个名为 product 的定位器。然后,我们按文本进行过滤。我们可以再次使用产品定位器来获取按钮的角色并单击它,然后使用断言来确保只有一个文本为“产品 2”的产品。
Locator product = page.getByRole(AriaRole.LISTITEM).filter(new Locator.FilterOptions().setHasText("Product 2"));product.getByRole(AriaRole.BUTTON,new Locator.GetByRoleOptions().setName("Add to cart")).click();
您还可以将两个定位器链接在一起,例如,在特定对话框中查找“保存”按钮:
Locator saveButton = page.getByRole(AriaRole.BUTTON,new Page.GetByRoleOptions().setName("Save")); // ... Locator dialog = page.getByTestId("settings-dialog"); dialog.locator(saveButton).click();
3.2同时匹配两个定位器
方法 Locator.and()通过匹配其他定位器来缩小现有定位器的范围。例如,您可以将 Page.getByRole() 和 Page.getByTitle() 组合在一起,以按角色和标题进行匹配。
Locator button = page.getByRole(AriaRole.BUTTON).and(page.getByTitle("Subscribe"));
3.3匹配两个备选定位器之一
如果您想定位两个或多个元素中的一个,但不知道会是哪一个,请使用 Locator.or() 创建一个与所有备选项匹配的定位器。
例如,考虑这样一种情况:您想单击“新电子邮件”按钮,但有时会出现安全设置对话框。在这种情况下,您可以等待“新电子邮件”按钮或对话框,然后采取相应措施。
敲黑板!!!注意:
如果屏幕上同时出现“新建电子邮件”按钮和安全对话框,则“或”定位器将匹配它们,从而可能引发“严格模式违规”错误。在这种情况下,您可以使用 Locator.first() 仅匹配其中一个。
Locator newEmail = page.getByRole(AriaRole.BUTTON, new Page.GetByRoleOptions().setName("New")); Locator dialog = page.getByText("Confirm security settings"); assertThat(newEmail.or(dialog).first()).isVisible(); if (dialog.isVisible())page.getByRole(AriaRole.BUTTON, new Page.GetByRoleOptions().setName("Dismiss")).click(); newEmail.click();
3.4仅匹配可见元素
敲黑板!!!注意:
通常,找到一种更可靠的方法来唯一标识元素,而不是检查可见性。
考虑一个有两个按钮的页面,第一个不可见,第二个可见。
<button style='display: none'>Invisible</button> <button>Visible</button>
这将找到两个按钮并抛出严格性违规错误:
page.locator("button").click();
这只会找到第二个按钮,因为它是可见的,然后单击它。
page.locator("button").locator("visible=true").click();
4.列表
4.1对列表中的项目进行计数
可以断言定位器以对列表中的项目进行计数。例如:以下DOM结构
使用count断言确保列表包含 3 个项目。
assertThat(page.getByRole(AriaRole.LISTITEM).hasCount(3);
4.2断言列表中所有文本
可以断言定位器以查找列表中的所有文本。例如:以下DOM结构
使用 assertThat(locator).hasText() 确保列表包含文本“apple”、“banana”和“orange”。
assertThat(page.getByRole(AriaRole.LISTITEM)).hasText(new String[] { "apple", "banana", "orange" });
4.3定位特定项目
有许多方法可以在列表中定位特定项目。
4.3.1通过文本定位
使用 Page.getByText()方法通过文本内容在列表中查找元素,然后单击它。例如:以下DOM结构
通过文本内容找到项目并单击它。
page.getByText("orange").click();
4.3.2通过文本过滤定位
使用 locator.filter() 在列表中查找特定项目。例如:以下DOM结构
按“listitem”的角色找到一个项目,然后按“orange”的文本进行筛选,然后单击它。
page.getByRole(AriaRole.LISTITEM).filter(new Locator.FilterOptions().setHasText("orange")).click();
4.3.3通过测试id定位
使用 Page.getByTestId()方法在列表中查找元素。如果您还没有测试 ID,则可能需要修改 html 并添加测试 ID。
通过测试 ID “orange”找到一个项目,然后单击它。
page.getByTestId("orange").click();
4.3.4通过第n项定位
如果您有一个相同元素的列表,并且区分它们的唯一方法是顺序,则可以使用 Locator.first()、Locator.last() 或 Locator.nth() 从列表中选择特定元素。
Locator banana = page.getByRole(AriaRole.LISTITEM).nth(1);
但是,请谨慎使用此方法。通常,页面可能会发生变化,定位器将指向与您预期的完全不同的元素。取而代之的是,尝试提出一个独特的定位器,该定位器将通过严格的标准。
4.4链接过滤器
当您有各种相似性的元素时,可以使用 locator.filter()方法选择正确的元素。您还可以链接多个筛选器以缩小选择范围。
要截取带有“Mary”和“Say goodbye”的行的屏幕截图,请执行以下操作:
Locator rowLocator = page.getByRole(AriaRole.LISTITEM);rowLocator.filter(new Locator.FilterOptions().setHasText("Mary")).filter(new Locator.FilterOptions().setHas(page.getByRole(AriaRole.BUTTON,new Page.GetByRoleOptions().setName("Say goodbye")))).screenshot(new Page.ScreenshotOptions().setPath("screenshot.png"));
现在,您应该在项目的根目录中有一个“screenshot.png”文件。
4.5罕见例子
4.5.1对列表中每个元素执行某些操作
迭代元素
for (Locator row : page.getByRole(AriaRole.LISTITEM).all())System.out.println(row.textContent());
使用常规 for 循环进行迭代:
Locator rows = page.getByRole(AriaRole.LISTITEM); int count = rows.count(); for (int i = 0; i < count; ++i)System.out.println(rows.nth(i).textContent());
4.5.2在页面中评估
locator.evaluate_all()中的代码在页面中运行,您可以在那里调用任何 DOM API。
Locator rows = page.getByRole(AriaRole.LISTITEM); Object texts = rows.evaluateAll("list => list.map(element => element.textContent)");
5.小结
定位器是非常严格。这意味着,如果多个元素匹配,则对定位器执行暗示某些目标 DOM 元素的所有操作都将引发异常。例如,如果 DOM 中有多个按钮,则会引发以下调用:
如果有多个button,则引发错误
page.getByRole(AriaRole.BUTTON).click();
另一方面,Playwright 了解何时执行多元素操作,因此当定位器解析为多个元素时,以下调用工作正常。
适用于多个元素
page.getByRole(AriaRole.BUTTON).count();
您可以通过 locator.first、locator.last 和 locator.nth() 告诉 Playwright 在多个元素匹配时使用哪个元素来明确选择退出严格性检查。不建议使用这些方法,因为当您的页面更改时,Playwright 可能会单击您不想要的元素。相反,请按照上述最佳实践创建唯一标识目标元素的定位器。
5.1其他定位器
对于不太常用的定位器,请查看官网的其他定位器指南。由于时间关系,宏哥就不在这里对其进行展开介绍和讲解了。好了时间不早了,关于元素基础定位方式今天就分享到这里!!!仅供大家学习参考,感谢您耐心的阅读。
每天学习一点,今后必成大神-
往期推荐(由于跳转参数丢失了,所有建议选中要访问的右键,在新标签页中打开链接即可访问)或者微信搜索: 北京宏哥 公众号提前解锁更多干货。
Appium自动化系列,耗时80天打造的从搭建环境到实际应用精品教程测试
Python接口自动化测试教程,熬夜87天整理出这一份上万字的超全学习指南
Python+Selenium自动化系列,通宵700天从无到有搭建一个自动化测试框架
Java+Selenium自动化系列,仿照Python趁热打铁呕心沥血317天搭建价值好几K的自动化测试框架
Jmeter工具从基础->进阶->高级,费时2年多整理出这一份全网超详细的入门到精通教程
其他定位器
Pycharm工具基础使用教程
相关文章:

《刚刚问世》系列初窥篇-Java+Playwright自动化测试-7-元素基础定位方式-下篇 (详细教程)
软件测试微信群:https://bbs.csdn.net/topics/618423372 有兴趣的可以扫码加入 1.简介 上一篇主要是讲解我们日常工作中在使用Playwright进行元素定位的一些比较常用的基础定位方式的理论基础知识以及在什么情况下推荐使用。今天这一篇讲解和分享一下剩下部分的基…...
[Day 44] 區塊鏈與人工智能的聯動應用:理論、技術與實踐
生成对抗网络(Generative Adversarial Networks,GANs)是一种由Ian Goodfellow等人在2014年提出的深度学习模型,广泛用于图像生成、图像超分辨率、图像修复等领域。GAN由一个生成器(Generator)和一个判别器&…...
【Redis】 Redis 列表指令指南
这是我父亲 日记里的文字 这是他的生命 留下留下来的散文诗 几十年后 我看着泪流不止 可我的父亲已经 老得像一个影子 🎵 许飞《父亲写的散文诗》 Redis 是一个开源的内存数据库,支持多种数据结构,其中列表(…...

设计测试用例的具体方法
一.等价类 等价类分为: 1.有效等价类 [6~15] 2.无效等价类 :小于6位,大于15位(不在数据范围内) 组合规则: 有效等价类组合的时候,尽可能一条测试用例尽可能多的覆盖有效等价类 无效等价类组合的时候,一条测试点,之恶能覆盖一个无效等价类 二.边界值 1.上点,离点,内点 上…...
GPT-4o mini(假设模型)概览
开篇背景: 近年来,随着计算能力的提升和大数据的积累,大型语言模型(LLMs)如GPT系列取得了显著进展。这些模型不仅能够理解复杂的自然语言文本,还能生成流畅、连贯的回复,甚至展现出一定程度的创…...
抽象代数精解【9】
文章目录 置换密码密码体制加解密过程置换置换运算定义置换运算的例子集合与置换置换规则两行表示法轮换表示法置换运算的结果置换的性质注意事项 分组加解密 理论基础1. 准备工作2. 置换过程3. 置换密码的具体实现方式4. 安全性分析5. 置换密码的应用代换密码代换密码的工作原…...
熟悉简单测试面经
SQL语句中增、删、查、改的关键字 MySQL中SQL语句删除语句有哪些?区别是啥。 “”和equals的区别 “String s "1"”与“String s new String("1")”中的s一样吗? StringBuilder与StringBuffer的区别 洗牌问题 HTTP、HTTPS、U…...

IoTDB 入门教程 实战篇④——C#示例(开源)
文章目录 一、前文二、新建C#项目三、NuGet安装四、示例源码五、查询数据六、参考 一、前文 IoTDB入门教程——导读 本文详细阐述了如何通过一个C#项目成功连接到IoTDB时序数据库,进而展示了如何向该数据库高效地写入数据以及执行精确的数据查询操作。 此示例旨在为…...
STL-vector容器
目录 一、常见接口 1.1 构造函数 1.2 访问与遍历 1.3 容量操作 1.4 增删查改 二、模拟实现 2.1 迭代器失效 2.2 源代码 一、常见接口 vector数据结构实际上是顺序表 详细解释与使用请参见官方网站:vector - C Reference (cplusplus.com) 1.1 构造函数 函…...
python字符串与变量名互相转换,字典,list操作
locals是python的内置函数,他可以以字典的方式去访问局部和全局变量 vars()本函数是实现返回对象object的属性和属性值的字典对象 eval()将字符串str当成有效的表达式来求值并返回计算结果 #!/usr/bin/python3 #-*- coding uft-8 -*- guo 666 str1 "guo&qu…...

企业及园区电力能源管理系统方案
概述 面对中小型的用能集团、园区能耗监测分析等场景需求,拓扑未来公司推出标准化的企业及园区电力能源管理系统方案,力求高效高质地为目标客户提供高效部署、轻松运维的本地化能源管理解决方案。 本方案以软硬件一体的方式,集成了标准电力监…...

5.3 需求分析
需求分析 软件需求定义分类练习题 需求工程需求获取练习题 需求分析状态转化图数据流图DFD顶层数据流图0层数据流图1层数据流图 练习题 需求规约需求定义方法 需求验证需求管理版本控制需求跟踪变更控制练习题 考试大概3分 软件需求 定义 软件需求:是指用户对目标…...
【C++】list介绍以及模拟实现(超级详细)
欢迎来到我的Blog,点击关注哦💕 list的介绍和模拟实现 前言list介绍标准库容器 std::list 与 std::vector 的优缺点缺点 list的基本操作构造函数list iteratorlist capcacitylist modify list模拟实现存贮结构(双向带头循环)itera…...

从艺术创作到作物生长,农业AI迎来“GPT“时刻
(于景鑫 国家农业信息化工程技术研究中心)"GPT"一词早已不再神秘,其在文本、图像生成领域掀起的风暴正以摧枯拉朽之势席卷全球。人们惊叹于ChatGPT对话之智能、思维之敏捷,更对Stable Diffusion、Midjourney创作的艺术画作赞叹不已。而大语言模…...

前端使用 Konva 实现可视化设计器(19)- 连接线 - 直线、折线
本章响应小伙伴的反馈,除了算法自动画连接线(仍需优化完善),实现了可以手动绘制直线、折线连接线功能。 请大家动动小手,给我一个免费的 Star 吧~ 大家如果发现了 Bug,欢迎来提 Issue 哟~ github源码 gitee…...
C#:通用方法总结—第15集
大家好,今天继续分享我们的通用方法系列。 下面是今天的通用方法: (1)这个通用方法为用文件流写数据 /// <summary> /// 用文件流写数据 /// </summary> /// <param name"data"></param> //…...

LoadRunner12 添加事务并添加检查点
1、先要添加事务开始函数lr_start_transaction("登陆事务");,在接口上方右击点击-插入-开始事务。输入事务名称; 2、在某个接口想法 右击点击-插入-结束事务,输入事务名称,与开始事务名称要保持一致,lr_end_…...
python中的文件
绝对路径和相对路径 一般情况下绝对路径就是从根目录开始描述的路径 相对路径就是相对于当前目录 . 没错,就是一个点,表示的是当前文件夹;.. 两个点表示的是上一层文件夹 os模块与os.path os 和 os.path 是两个非常重要的标准库模块,它们分别用于操作系统相关的功能操…...

Powerdesigner连接mysql数据库,逆向工程生成ER图 (保姆级教程:下载->连接->配置)看这一篇就够了
一、下载powerdesigner 下载的教程请看如下链接,我太懒了,直接借鉴! 把别大佬的博客搬过来了嘿嘿~我真聪明!ㄟ( ▔, ▔ )ㄏ 操作到完成汉化就好!!第5步不看了,别按那个走,因为新手…...

商家转账到零钱分销返佣申请方案及驳回处理办法
分销返佣场景是商家申请最多的场景,因而申请被驳回也是最多的,根据我们上万次成功开通商家转账到零钱的经验,当商家转账到零钱的分销返佣场景被驳回时,按照以下步骤,商家都可以快速过审: 一、分析驳回原因 …...
Python爬虫实战:研究MechanicalSoup库相关技术
一、MechanicalSoup 库概述 1.1 库简介 MechanicalSoup 是一个 Python 库,专为自动化交互网站而设计。它结合了 requests 的 HTTP 请求能力和 BeautifulSoup 的 HTML 解析能力,提供了直观的 API,让我们可以像人类用户一样浏览网页、填写表单和提交请求。 1.2 主要功能特点…...

shell脚本--常见案例
1、自动备份文件或目录 2、批量重命名文件 3、查找并删除指定名称的文件: 4、批量删除文件 5、查找并替换文件内容 6、批量创建文件 7、创建文件夹并移动文件 8、在文件夹中查找文件...
《Playwright:微软的自动化测试工具详解》
Playwright 简介:声明内容来自网络,将内容拼接整理出来的文档 Playwright 是微软开发的自动化测试工具,支持 Chrome、Firefox、Safari 等主流浏览器,提供多语言 API(Python、JavaScript、Java、.NET)。它的特点包括&a…...

解决Ubuntu22.04 VMware失败的问题 ubuntu入门之二十八
现象1 打开VMware失败 Ubuntu升级之后打开VMware上报需要安装vmmon和vmnet,点击确认后如下提示 最终上报fail 解决方法 内核升级导致,需要在新内核下重新下载编译安装 查看版本 $ vmware -v VMware Workstation 17.5.1 build-23298084$ lsb_release…...

YSYX学习记录(八)
C语言,练习0: 先创建一个文件夹,我用的是物理机: 安装build-essential 练习1: 我注释掉了 #include <stdio.h> 出现下面错误 在你的文本编辑器中打开ex1文件,随机修改或删除一部分,之后…...
Leetcode 3577. Count the Number of Computer Unlocking Permutations
Leetcode 3577. Count the Number of Computer Unlocking Permutations 1. 解题思路2. 代码实现 题目链接:3577. Count the Number of Computer Unlocking Permutations 1. 解题思路 这一题其实就是一个脑筋急转弯,要想要能够将所有的电脑解锁&#x…...
Java多线程实现之Callable接口深度解析
Java多线程实现之Callable接口深度解析 一、Callable接口概述1.1 接口定义1.2 与Runnable接口的对比1.3 Future接口与FutureTask类 二、Callable接口的基本使用方法2.1 传统方式实现Callable接口2.2 使用Lambda表达式简化Callable实现2.3 使用FutureTask类执行Callable任务 三、…...

Module Federation 和 Native Federation 的比较
前言 Module Federation 是 Webpack 5 引入的微前端架构方案,允许不同独立构建的应用在运行时动态共享模块。 Native Federation 是 Angular 官方基于 Module Federation 理念实现的专为 Angular 优化的微前端方案。 概念解析 Module Federation (模块联邦) Modul…...

ArcGIS Pro制作水平横向图例+多级标注
今天介绍下载ArcGIS Pro中如何设置水平横向图例。 之前我们介绍了ArcGIS的横向图例制作:ArcGIS横向、多列图例、顺序重排、符号居中、批量更改图例符号等等(ArcGIS出图图例8大技巧),那这次我们看看ArcGIS Pro如何更加快捷的操作。…...

中医有效性探讨
文章目录 西医是如何发展到以生物化学为药理基础的现代医学?传统医学奠基期(远古 - 17 世纪)近代医学转型期(17 世纪 - 19 世纪末)现代医学成熟期(20世纪至今) 中医的源远流长和一脉相承远古至…...