Playwright实战-定位元素详解

简介:网页元素定位是编写端到端自动化测试的一个关键步骤。本文由浅入深循序渐进介绍了在Playwright中的定位元素方法。

在编写端到端测试时,我们需要首先找到网页上的元素,然后对其执行用户操作。例如,找到一个链接并点击它。使用 Playwright 的测试生成器是最方便的方法,不仅可以生成测试代码,还可以生成特定元素的定位器。在深入了解如何使用测试生成器之前,先让我们理解什么是链接元素以及定位器是什么。

基础知识

什么是链接?

HTML` <a> `元素,也称为锚点元素,是一个交互元素,它创建一个指向另一个页面的超链接,可以是站内链接,也可以是外部链接。它还可以用于链接到同一页面的特定区域,以及用于电子邮件、文件下载或任何URL可以指向的内容。<a> 元素使用 href 属性传递超链接指向的URL。

什么是定位器?

在 Playwright 中,我们使用“定位器”来表示查找页面元素的方法,具有自动等待和重试功能。自动等待意味着 Playwright 会在执行点击操作之前,对元素进行一系列可操作性检查,如确保元素可见且已启用。

你可以通过以下方式定位元素

• 角色(role)

• 标签(label)

• 占位符(placeholder)

• 文本(text)

• 替代文本(alt text)

• 标题(title)

• 测试ID(test id)

如何定位链接

<a href="/about">About</a>

这意味着我们可以使用 getByRole() 定位器,通过链接角色来定位 <a> 元素,并在其后添加点击方法。

await page.getByRole('link').click();

添加名称

这将起作用,但如果页面上有多个链接呢?这时需要使用 name 选项。name 是辅助技术用于识别元素的可访问名称,通常取自元素内容、属性或相关元素。

await page.getByRole('link', { name: 'About' }).click();

使用正则表达式

我们还可以使用正则表达式并忽略大小写,这样无论文本是否包含大写字母,测试都将通过。

await page.getByRole('link', { name: /about/i }).click();

设置精确匹配

你可以将 exact 设置为 true 以进行精确匹配。如果你有一个包含文本 "About" 的链接和另一个包含文本 "About the Company" 的链接,设置 exact 为 true 将只匹配包含 "About" 的链接。

await page.getByRole('link', { name: 'About', exact: true }).click();

添加 aria-label

如果链接包含 aria-label,则将使用 aria-label 的值而不是文本内容。

<a href="/locators" aria-label="read more about locators">Read more</a>

然后我们可以使用 getByRole() 定位器通过 aria-label 的值来定位链接。

await page.getByRole('link', { name: /read more about locators/i }).click();

使用 Playwright 的测试生成器

你可以使用 VS Code 扩展从测试侧边栏点击“record new”链接来生成代码。

当你点击网站上的元素时,生成器将查看页面并为你找出最佳定位器,优先考虑角色、文本和测试ID定位器。如果生成器找到多个匹配的元素,它将改进定位器以使其独特和稳健,因此你不必担心由于定位器问题导致的测试失败。

如果你没有使用 VS Code 扩展,Playwright 提供了一个独立的测试生成器 Codegen

npx playwright codegen

选择定位器

你可以通过点击测试侧边栏中的“pick locator”按钮来选择定位器。

当你将鼠标悬停在浏览器窗口中的任何元素上时,该元素的定位器将突出显示在光标下。

图片[1]-Playwright实战-定位元素详解-365博客

如果你点击该元素,定位器将出现在“pick locator”框中。你可以将其复制到剪贴板并粘贴到测试中。

图片[2]-Playwright实战-定位元素详解-365博客

你还可以通过点击独立测试生成器中的“explore”按钮来选择定位器。

链式定位器

如果你的网站包含重复链接,例如在页眉和页脚中有两个关于链接,那么测试生成器将为每个链接创建一个唯一的定位器。它通过查找链接的易识别祖先并链式定位器来实现这一点。

getByRole('navigation').getByRole('link', { name: 'About' })

对于页脚中的关于链接,测试生成器再次查找祖先并链式两个 getByRole() 定位器,确保只有一个元素匹配该定位器。

getByRole('contentinfo').getByRole('link', { name: 'About' })

过滤定位器

如果测试生成器不能通过链式定位器给你一个唯一的定位器,它将使用 filter() 方法确保定位器是唯一的。例如,我们可能有两个包含博客文章主题的列表。第一个列表用于过滤博客文章,第二个列表用于显示每篇文章的主题。测试生成器将使用 filter() 方法确保定位器是唯一的。

getByRole('list')
  .filter({ hasText: 'architecturedev reljamstackjavascriptlifestylementoringmotivationnuxtperformance' })
  .getByRole('link', { name: 'architecture' })

改进你的定位器

你可能会注意到,通过文本过滤有时会给你一个非常丑陋的定位器,如上例所示,并可能在以后引起问题,特别是如果你添加了另一个主题到过滤器中。

你可以通过使用正则表达式来匹配文本中的某些单词来改进这个过滤器,选择那些通常不会在一篇文章中一起出现的词,如“architecture”“mentoring”“testing”

getByRole('list')
  .filter({ hasText: /architecture.*mentoring.*testing/ })
  .getByRole('link', { name: 'architecture' })

另一种选择是向第一个 <ul> 元素添加一个 aria-label 值为“topics”。这不仅有助于提高页面的可访问性,还允许 Playwright 通过角色定位。

<ul aria-label="topics">
  //...
</ul>

测试生成器现在将使用这个 aria-label 并通过角色为“topics”的列表进行定位,从而生成一个唯一的定位器。

结论

本文未涉及的角色和定位器还有很多。幸运的是,你不必知道哪些是可用的,因为感谢测试生成器,你不必担心在编写测试时选择哪个角色或定位器。这提供了更好的开发体验,并确保你拥有稳健的定位器,无论你是否是测试新手。

如果测试生成器生成了你不满意的定位器,那么可能值得调查DOM,看看是否可以改进代码以提高可访问性,从而使测试生成器生成更好的定位器。这不仅为你提供了更好的测试,还改进了代码。

最后,从作者自己使用体会来说,比较推荐尝试使用测试生成器,无论是使用VS Code扩展还是从终端打开它

npx playwright codegen

一旦你熟练掌握之后,就可以自己手写代码而不依赖于生成器了。

© 版权声明
THE END
喜欢就支持一下吧
点赞8 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容