在Playwright的自动化测试框架中,定位器(Locators)扮演着至关重要的角色。它们不仅支持自动等待和重试机制,还能以用户感知的方式定位页面元素,确保测试的稳定性和可靠性。
定位器是Playwright自动等待和重试能力的核心。它们提供了一种在页面上任何时刻查找元素的方式。推荐使用内置定位器,如page.get_by_role()
、page.get_by_text()
、page.get_by_label()
等,以提高测试的健壮性。
以下是Playwright推荐的内置定位器及其用途:
page.get_by_role()
:通过显式和隐式可访问性属性定位元素。page.get_by_text()
:通过文本内容定位元素。page.get_by_label()
:通过关联标签文本定位表单控件。page.get_by_placeholder()
:通过占位符定位输入框。page.get_by_alt_text()
:通过替代文本定位图像等元素。page.get_by_title()
:通过title属性定位元素。page.get_by_test_id()
:基于data-testid属性定位元素。Playwright提供了多种内置定位器,建议优先使用面向用户的属性和明确的合约,如page.get_by_role()
。例如,对于以下DOM结构:
<button>Sign inbutton>
可以通过其角色和名称进行定位:
page.get_by_role("button", name="Sign in").click()
每次使用定位器执行操作时,都会在页面中查找最新的DOM元素。这意味着即使DOM在操作之间重新渲染,也会使用与定位器对应的新元素。
page.get_by_role()
定位器反映了用户和辅助技术对页面的感知方式。定位时通常需要传递可访问名称,以便精确定位元素。例如:
<h3>Sign uph3>
<label>
<input type="checkbox" /> Subscribe
label>
<button>Submitbutton>
可以按以下方式定位元素:
expect(page.get_by_role("heading", name="Sign up")).to_be_visible()
page.get_by_role("checkbox", name="Subscribe").check()
page.get_by_role("button", name=re.compile("submit", re.IGNORECASE)).click()
对于表单控件,可以使用page.get_by_label()
通过关联标签文本定位。例如:
<label>Password <input type="password" />label>
可以通过标签文本定位输入框:
page.get_by_label("Password").fill("secret")
对于带有占位符属性的输入框,可以使用page.get_by_placeholder()
定位。例如:
<input type="email" placeholder="[email protected]" />
可以通过占位符文本定位输入框:
page.get_by_placeholder("[email protected]").fill("[email protected]")
通过元素包含的文本定位,可以使用Substring、Exact String或Regular Expression。例如:
<span>Welcome, Johnspan>
可以通过文本内容定位元素:
expect(page.get_by_text("Welcome, John")).to_be_visible()
对于图像等支持alt属性的元素,可以使用page.get_by_alt_text()
定位。例如:
<img alt="playwright logo" src="/img/playwright-logo.svg" width="100" />
可以通过alt文本定位图像:
page.get_by_alt_text("playwright logo").click()
通过元素的title属性定位,可以使用page.get_by_title()
。例如:
<span title='Issues count'>25 issuesspan>
可以通过title文本定位元素:
expect(page.get_by_title("Issues count")).to_have_text("25 issues")
使用测试ID进行测试是最稳定的方式之一。QA和开发人员应定义明确的测试ID,并通过page.get_by_test_id()
查询。例如:
<button data-testid="directions">Itinérairebutton>
可以通过测试ID定位元素:
page.get_by_test_id("directions").click()
默认情况下,page.get_by_test_id()
基于data-testid属性定位元素,但可以通过selectors.set_test_id_attribute()
配置自定义属性。例如:
playwright.selectors.set_test_id_attribute("data-pw")
然后在HTML中使用自定义属性:
<button data-pw="directions">Itinérairebutton>
如果必须使用CSS或XPath定位器,可以使用page.locator()
创建定位器。Playwright支持CSS和XPath选择器,并能自动检测它们。例如:
page.locator("css=button").click()
page.locator("xpath=//button").click()
Playwright的定位器默认支持Shadow DOM中的元素。例如,对于以下自定义Web组件:
<x-details role=button aria-expanded=true aria-controls=inner-details>
<div>Titlediv>
#shadow-root
<div id=inner-details>Detailsdiv>
x-details>
可以像没有Shadow根一样定位元素:
page.get_by_text("Details").click()
通过locator.filter()
方法可以根据文本过滤定位器。例如,在以下DOM结构中点击第二个产品卡片的购买按钮:
<ul>
<li>
<h3>Product 1h3>
<button>Add to cartbutton>
li>
<li>
<h3>Product 2h3>
<button>Add to cartbutton>
li>
ul>
可以通过文本过滤定位器:
page.get_by_role("listitem").filter(has_text="Product 2").get_by_role("button", name="Add to cart").click()
可以链式调用创建定位器的方法,如page.get_by_text()
或locator.get_by_role()
,以缩小搜索范围。例如:
product = page.get_by_role("listitem").filter(has_text="Product 2")
product.get_by_role("button", name="Add to cart").click()
可以对定位器进行断言,以计算列表中的项目数量或获取特定项目。例如:
expect(page.get_by_role("listitem")).to_have_count(3)
expect(page.get_by_role("listitem")).to_have_text(["apple", "banana", "orange"])
定位器是严格的,如果匹配到多个元素,将抛出异常。可以通过locator.first
、locator.last
和locator.nth()
明确选择元素,但建议创建唯一标识目标元素的定位器。
Playwright定位器提供了强大的元素查找功能,支持多种定位策略,确保测试的稳定性和可靠性。通过合理选择和组合定位器,可以高效地进行Web应用测试。