Skip to main content

其他定位器

介绍

Introduction

注意

查看主要 定位器指南,了解最常见和推荐的定位器。

Check out the main locators guide for most common and recommended locators.

除了推荐的定位器(如 page.getByRole()page.getByText())之外,Playwright 还支持本指南中描述的各种其他定位器。

In addition to recommended locators like page.getByRole() and page.getByText(), Playwright supports a variety of other locators described in this guide.

CSS 定位器

CSS locator

注意

我们建议优先考虑 用户可见的定位器(如文本或可访问角色),而不是使用与实现相关且可能在页面更改时中断的 CSS。

We recommend prioritizing user-visible locators like text or accessible role instead of using CSS that is tied to the implementation and could break when the page changes.

Playwright 可以通过 CSS 选择器来定位元素。

Playwright can locate an element by CSS selector.

await page.locator('css=button').click();

Playwright 通过两种方式增强标准 CSS 选择器:

Playwright augments standard CSS selectors in two ways:

  • CSS 选择器刺穿开放的影子 DOM。

    CSS selectors pierce open shadow DOM.

  • Playwright 添加了自定义伪类,如 :visible:has-text():has():is():nth-match() 等。

    Playwright adds custom pseudo-classes like :visible, :has-text(), :has(), :is(), :nth-match() and more.

CSS:按文本匹配

CSS: matching by text

Playwright 包含许多 CSS 伪类,用于根据文本内容来匹配元素。

Playwright include a number of CSS pseudo-classes to match elements by their text content.

  • article:has-text("Playwright") - :has-text() 匹配内部某处(可能在子元素或后代元素中)包含指定文本的任何元素。匹配不区分大小写,修剪空格并搜索子字符串。

    article:has-text("Playwright") - the :has-text() matches any element containing specified text somewhere inside, possibly in a child or a descendant element. Matching is case-insensitive, trims whitespace and searches for a substring.

    例如,article:has-text("Playwright") 匹配 <article><div>Playwright</div></article>

    For example, article:has-text("Playwright") matches <article><div>Playwright</div></article>.

    请注意,:has-text() 应与其他 CSS 说明符一起使用,否则它将匹配所有包含指定文本的元素,包括 <body>

    Note that :has-text() should be used together with other CSS specifiers, otherwise it will match all the elements containing specified text, including the <body>.

    // Wrong, will match many elements including <body>
    await page.locator(':has-text("Playwright")').click();
    // Correct, only matches the <article> element
    await page.locator('article:has-text("Playwright")').click();
  • #nav-bar :text("Home") - :text() 伪类匹配包含指定文本的最小元素。匹配不区分大小写,修剪空格并搜索子字符串。

    #nav-bar :text("Home") - the :text() pseudo-class matches the smallest element containing specified text. Matching is case-insensitive, trims whitespace and searches for a substring.

    例如,这将在 #nav-bar 元素内的某处找到带有文本 "Home" 的元素:

    For example, this will find an element with text "Home" somewhere inside the #nav-bar element:

    await page.locator('#nav-bar :text("Home")').click();
  • #nav-bar :text-is("Home") - :text-is() 伪类将最小元素与精确文本相匹配。精确匹配区分大小写、修剪空格并搜索完整字符串。

    #nav-bar :text-is("Home") - the :text-is() pseudo-class matches the smallest element with exact text. Exact matching is case-sensitive, trims whitespace and searches for the full string.

    例如,:text-is("Log")<button>Log in</button> 不匹配,因为 <button> 包含不等于 "Log" 的单个文本节点 "Log in"。但是,:text-is("Log")<button> Log <span>in</span></button> 匹配,因为 <button> 包含文本节点 " Log "

    For example, :text-is("Log") does not match <button>Log in</button> because <button> contains a single text node "Log in" that is not equal to "Log". However, :text-is("Log") matches <button> Log <span>in</span></button>, because <button> contains a text node " Log ".

    同样,:text-is("Download") 不会匹配 <button>download</button>,因为它区分大小写。

    Similarly, :text-is("Download") will not match <button>download</button> because it is case-sensitive.

  • #nav-bar :text-matches("reg?ex", "i") - :text-matches() 伪类匹配文本内容与 类似 JavaScript 的正则表达式 匹配的最小元素。

    #nav-bar :text-matches("reg?ex", "i") - the :text-matches() pseudo-class matches the smallest element with text content matching the JavaScript-like regex.

    例如,:text-matches("Log\s*in", "i") 匹配 <button>Login</button><button>log IN</button>

    For example, :text-matches("Log\s*in", "i") matches <button>Login</button> and <button>log IN</button>.

注意

文本匹配总是标准化空白。例如,它将多个空格变成一个,将换行符变成空格,并忽略前导和尾随空白。

Text matching always normalizes whitespace. For example, it turns multiple spaces into one, turns line breaks into spaces and ignores leading and trailing whitespace.

注意

buttonsubmit 类型的输入元素通过其 value 而不是文本内容进行匹配。例如,:text("Log in") 匹配 <input type=button value="Log in">

Input elements of the type button and submit are matched by their value instead of text content. For example, :text("Log in") matches <input type=button value="Log in">.

CSS:仅匹配可见元素

CSS: matching only visible elements

Playwright 支持 CSS 选择器中的 :visible 伪类。例如,css=button 匹配页面上的所有按钮,而 css=button:visible 仅匹配可见按钮。这对于区分非常相似但可见性不同的元素很有用。

Playwright supports the :visible pseudo class in CSS selectors. For example, css=button matches all the buttons on the page, while css=button:visible only matches visible buttons. This is useful to distinguish elements that are very similar but differ in visibility.

考虑一个带有两个按钮的页面,第一个按钮不可见,第二个按钮可见。

Consider a page with two buttons, first invisible and second visible.

<button style='display: none'>Invisible</button>
<button>Visible</button>
  • 这将找到两个按钮并抛出 strictness 违规错误:

    This will find both buttons and throw a strictness violation error:

    await page.locator('button').click();
  • 这只会找到第二个按钮,因为它是可见的,然后单击它。

    This will only find a second button, because it is visible, and then click it.

    await page.locator('button:visible').click();

CSS:包含其他元素的元素

CSS: elements that contain other elements

:has() 伪类是 实验性 CSS 伪类。如果作为参数传递的任何选择器相对于给定元素的 :scope 至少匹配一个元素,则它返回一个元素。

The :has() pseudo-class is an experimental CSS pseudo-class. It returns an element if any of the selectors passed as parameters relative to the :scope of the given element match at least one element.

以下代码片段返回内部包含 <div class=promo><article> 元素的文本内容。

Following snippet returns text content of an <article> element that has a <div class=promo> inside.

await page.locator('article:has(div.promo)').textContent();

CSS:符合条件之一的元素

CSS: elements matching one of the conditions

以逗号分隔的 CSS 选择器列表将匹配可由该列表中的选择器之一选择的所有元素。

Comma-separated list of CSS selectors will match all elements that can be selected by one of the selectors in that list.

// Clicks a <button> that has either a "Log in" or "Sign in" text.
await page.locator('button:has-text("Log in"), button:has-text("Sign in")').click();

:is() 伪类是 实验性 CSS 伪类,可用于指定元素上的额外条件列表。

The :is() pseudo-class is an experimental CSS pseudo-class that may be useful for specifying a list of extra conditions on an element.

CSS:根据布局匹配元素

CSS: matching elements based on layout

注意

基于布局的匹配可能会产生意想不到的结果。例如,当布局改变一个像素时,可以匹配不同的元素。

Matching based on layout may produce unexpected results. For example, a different element could be matched when layout changes by one pixel.

有时,当目标元素缺乏鲜明的特性时,很难找到一个好的选择器。在这种情况下,使用 Playwright 布局 CSS 伪类可能会有所帮助。这些可以与常规 CSS 结合起来以精确定位多个选择之一。

Sometimes, it is hard to come up with a good selector to the target element when it lacks distinctive features. In this case, using Playwright layout CSS pseudo-classes could help. These can be combined with regular CSS to pinpoint one of the multiple choices.

例如,input:right-of(:text("Password")) 匹配文本 "密码" 右侧的输入字段 - 当页面有多个难以区分的输入时很有用。

For example, input:right-of(:text("Password")) matches an input field that is to the right of text "Password" - useful when the page has multiple inputs that are hard to distinguish between each other.

请注意,布局伪类除了其他东西之外也很有用,例如 input。如果你单独使用布局伪类(例如 :right-of(:text("Password"))),很可能你不会得到你正在寻找的输入,而是在文本和目标输入之间得到一些空元素。

Note that layout pseudo-classes are useful in addition to something else, like input. If you use a layout pseudo-class alone, like :right-of(:text("Password")), most likely you'll get not the input you are looking for, but some empty element in between the text and the target input.

布局伪类使用 边界客户矩形 来计算元素的距离和相对位置。

Layout pseudo-classes use bounding client rect to compute distance and relative position of the elements.

  • :right-of(div > button) - 匹配与内部选择器匹配的任何元素右侧的元素,在任何垂直位置。

    :right-of(div > button) - Matches elements that are to the right of any element matching the inner selector, at any vertical position.

  • :left-of(div > button) - 匹配位于任何垂直位置的与内部选择器匹配的任何元素左侧的元素。

    :left-of(div > button) - Matches elements that are to the left of any element matching the inner selector, at any vertical position.

  • :above(div > button) - 匹配任何水平位置上与内部选择器匹配的任何元素之上的元素。

    :above(div > button) - Matches elements that are above any of the elements matching the inner selector, at any horizontal position.

  • :below(div > button) - 匹配任何水平位置上与内部选择器匹配的任何元素下方的元素。

    :below(div > button) - Matches elements that are below any of the elements matching the inner selector, at any horizontal position.

  • :near(div > button) - 匹配与内部选择器匹配的任何元素附近(50 CSS 像素内)的元素。

    :near(div > button) - Matches elements that are near (within 50 CSS pixels) any of the elements matching the inner selector.

请注意,生成的匹配项按其与锚元素的距离排序,因此你可以使用 locator.first() 来选择最接近的匹配项。仅当你有类似元素列表之类的内容时,这才有用,其中最接近的元素显然是正确的。但是,在其他情况下使用 locator.first() 很可能无法按预期工作 - 它不会定位你正在搜索的元素,而是定位最近的某些其他元素,例如随机的空 <div>,或者滚动出且当前不可见的元素。

Note that resulting matches are sorted by their distance to the anchor element, so you can use locator.first() to pick the closest one. This is only useful if you have something like a list of similar elements, where the closest is obviously the right one. However, using locator.first() in other cases most likely won't work as expected - it will not target the element you are searching for, but some other element that happens to be the closest like a random empty <div>, or an element that is scrolled out and is not currently visible.

// Fill an input to the right of "Username".
await page.locator('input:right-of(:text("Username"))').fill('value');

// Click a button near the promo card.
await page.locator('button:near(.promo-card)').click();

// Click the radio input in the list closest to the "Label 3".
await page.locator('[type=radio]:left-of(:text("Label 3"))').first().click();

所有布局伪类都支持可选的最大像素距离作为最后一个参数。例如,button:near(:text("Username"), 120) 匹配距离文本 "用户名" 元素最多 120 CSS 像素的按钮。

All layout pseudo-classes support optional maximum pixel distance as the last argument. For example button:near(:text("Username"), 120) matches a button that is at most 120 CSS pixels away from the element with the text "Username".

CSS:从查询结果中选择第 n 个匹配项

CSS: pick n-th match from the query result

注意

通常可以通过某些属性或文本内容来区分元素,这对页面更改更具弹性。

It is usually possible to distinguish elements by some attribute or text content, which is more resilient to page changes.

有时页面包含许多相似的元素,很难选择特定的元素。例如:

Sometimes page contains a number of similar elements, and it is hard to select a particular one. For example:

<section> <button>Buy</button> </section>
<article><div> <button>Buy</button> </div></article>
<div><div> <button>Buy</button> </div></div>

在本例中,:nth-match(:text("Buy"), 3) 将选择上面代码片段中的第三个按钮。请注意,索引是基于 1 的。

In this case, :nth-match(:text("Buy"), 3) will select the third button from the snippet above. Note that index is one-based.

// Click the third "Buy" button
await page.locator(':nth-match(:text("Buy"), 3)').click();

:nth-match() 对于等待指定数量的元素出现也很有用,使用 locator.waitFor()

:nth-match() is also useful to wait until a specified number of elements appear, using locator.waitFor().

// Wait until all three buttons are visible
await page.locator(':nth-match(:text("Buy"), 3)').waitFor();
注意

:nth-child() 不同,元素不必是同级元素,它们可以位于页面上的任何位置。在上面的代码片段中,所有三个按钮都匹配 :text("Buy") 选择器,:nth-match() 选择第三个按钮。

Unlike :nth-child(), elements do not have to be siblings, they could be anywhere on the page. In the snippet above, all three buttons match :text("Buy") selector, and :nth-match() selects the third button.

第 N 个元素定位器

N-th element locator

你可以使用传递从零开始的索引的 nth= 定位器将查询范围缩小到第 n 个匹配项。

You can narrow down query to the n-th match using the nth= locator passing a zero-based index.

// Click first button
await page.locator('button').locator('nth=0').click();

// Click last button
await page.locator('button').locator('nth=-1').click();

父元素定位器

Parent element locator

当你需要定位某个其他元素的父元素时,大多数时候你应该通过子定位器 locator.filter()。例如,考虑以下 DOM 结构:

When you need to target a parent element of some other element, most of the time you should locator.filter() by the child locator. For example, consider the following DOM structure:

<li><label>Hello</label></li>
<li><label>World</label></li>

如果你想将文本 "Hello" 定位到标签的父 <li>,则使用 locator.filter() 效果最佳:

If you'd like to target the parent <li> of a label with text "Hello", using locator.filter() works best:

const child = page.getByText('Hello');
const parent = page.getByRole('listitem').filter({ has: child });

或者,如果无法为父元素找到合适的定位器,请使用 xpath=..。请注意,此方法不太可靠,因为对 DOM 结构的任何更改都会破坏你的测试。如果可能,首选 locator.filter()

Alternatively, if you cannot find a suitable locator for the parent element, use xpath=... Note that this method is not as reliable, because any changes to the DOM structure will break your tests. Prefer locator.filter() when possible.

const parent = page.getByText('Hello').locator('xpath=..');

React 定位器

React locator

注意

React 定位器是实验性的,并带有 _ 前缀。该功能将来可能会发生变化。

React locator is experimental and prefixed with _. The functionality might change in future.

React 定位器允许通过组件名称和属性值查找元素。语法与 CSS 属性选择器 非常相似,支持所有 CSS 属性选择器运算符。

React locator allows finding elements by their component name and property values. The syntax is very similar to CSS attribute selectors and supports all CSS attribute selector operators.

在 React locator 中,组件名称采用 CamelCase 转录。

In React locator, component names are transcribed with CamelCase.

await page.locator('_react=BookItem').click();

更多示例:

More examples:

  • 按组件匹配:_react=BookItem

    match by component: _react=BookItem

  • 按组件和确切的属性值匹配,区分大小写:_react=BookItem[author = "Steven King"]

    match by component and exact property value, case-sensitive: _react=BookItem[author = "Steven King"]

  • 仅按属性值匹配,不区分大小写:_react=[author = "steven king" i]

    match by property value only, case-insensitive: _react=[author = "steven king" i]

  • 按组件和真实属性值进行匹配:_react=MyButton[enabled]

    match by component and truthy property value: _react=MyButton[enabled]

  • 按组件和布尔值匹配:_react=MyButton[enabled = false]

    match by component and boolean value: _react=MyButton[enabled = false]

  • 按属性值子字符串匹配:_react=[author *= "King"]

    match by property value substring: _react=[author *= "King"]

  • 按组件和多个属性匹配:_react=BookItem[author *= "king" i][year = 1990]

    match by component and multiple properties: _react=BookItem[author *= "king" i][year = 1990]

  • 按嵌套属性值匹配:_react=[some.nested.value = 12]

    match by nested property value: _react=[some.nested.value = 12]

  • 按组件和属性值前缀匹配:_react=BookItem[author ^= "Steven"]

    match by component and property value prefix: _react=BookItem[author ^= "Steven"]

  • 按组件和属性值后缀匹配:_react=BookItem[author $= "Steven"]

    match by component and property value suffix: _react=BookItem[author $= "Steven"]

  • 按组件和键匹配:_react=BookItem[key = '2']

    match by component and key: _react=BookItem[key = '2']

  • 按属性值正则表达式匹配:_react=[author = /Steven(\\s+King)?/i]

    match by property value regex: _react=[author = /Steven(\\s+King)?/i]

要在树中查找 React 元素名称,请使用 React 开发工具

To find React element names in a tree use React DevTools.

注意

React 定位器支持 React 15 及更高版本。

React locator supports React 15 and above.

注意

React 定位器以及 React 开发工具 仅适用于未缩小的应用构建。

React locator, as well as React DevTools, only work against unminified application builds.

Vue 定位器

Vue locator

注意

Vue 定位器是实验性的,前缀为 _。该功能将来可能会发生变化。

Vue locator is experimental and prefixed with _. The functionality might change in future.

Vue 定位器允许通过组件名称和属性值查找元素。语法与 CSS 属性选择器 非常相似,支持所有 CSS 属性选择器运算符。

Vue locator allows finding elements by their component name and property values. The syntax is very similar to CSS attribute selectors and supports all CSS attribute selector operators.

在 Vue 定位器中,组件名称是用短横线大小写转录的。

In Vue locator, component names are transcribed with kebab-case.

await page.locator('_vue=book-item').click();

更多示例:

More examples:

  • 按组件匹配:_vue=book-item

    match by component: _vue=book-item

  • 按组件和确切的属性值匹配,区分大小写:_vue=book-item[author = "Steven King"]

    match by component and exact property value, case-sensitive: _vue=book-item[author = "Steven King"]

  • 仅按属性值匹配,不区分大小写:_vue=[author = "steven king" i]

    match by property value only, case-insensitive: _vue=[author = "steven king" i]

  • 按组件和真实属性值进行匹配:_vue=my-button[enabled]

    match by component and truthy property value: _vue=my-button[enabled]

  • 按组件和布尔值匹配:_vue=my-button[enabled = false]

    match by component and boolean value: _vue=my-button[enabled = false]

  • 按属性值子字符串匹配:_vue=[author *= "King"]

    match by property value substring: _vue=[author *= "King"]

  • 按组件和多个属性匹配:_vue=book-item[author *= "king" i][year = 1990]

    match by component and multiple properties: _vue=book-item[author *= "king" i][year = 1990]

  • 按嵌套属性值匹配:_vue=[some.nested.value = 12]

    match by nested property value: _vue=[some.nested.value = 12]

  • 按组件和属性值前缀匹配:_vue=book-item[author ^= "Steven"]

    match by component and property value prefix: _vue=book-item[author ^= "Steven"]

  • 按组件和属性值后缀匹配:_vue=book-item[author $= "Steven"]

    match by component and property value suffix: _vue=book-item[author $= "Steven"]

  • 按属性值正则表达式匹配:_vue=[author = /Steven(\\s+King)?/i]

    match by property value regex: _vue=[author = /Steven(\\s+King)?/i]

要在树中查找 Vue 元素名称,请使用 Vue 开发工具

To find Vue element names in a tree use Vue DevTools.

注意

Vue 定位器支持 Vue2 及以上版本。

Vue locator supports Vue2 and above.

注意

Vue 定位器以及 Vue 开发工具 仅适用于未缩小的应用构建。

Vue locator, as well as Vue DevTools, only work against unminified application builds.

XPath 定位器

XPath locator

警告

我们建议优先考虑 用户可见的定位器(如文本或可访问角色),而不是使用与实现相关且在页面更改时容易中断的 XPath。

We recommend prioritizing user-visible locators like text or accessible role instead of using XPath that is tied to the implementation and easily break when the page changes.

XPath 定位器相当于调用 Document.evaluate

XPath locators are equivalent to calling Document.evaluate.

await page.locator('xpath=//button').click();
注意

任何以 //.. 开头的选择器字符串都被假定为 xpath 选择器。例如,Playwright 将 '//html/body' 转换为 'xpath=//html/body'

Any selector string starting with // or .. are assumed to be an xpath selector. For example, Playwright converts '//html/body' to 'xpath=//html/body'.

注意

XPath 不会穿透影子根。

XPath does not pierce shadow roots.

XPath 联合

XPath union

管道运算符 (|) 可用于在 XPath 中指定多个选择器。它将匹配该列表中的选择器之一可以选择的所有元素。

Pipe operator (|) can be used to specify multiple selectors in XPath. It will match all elements that can be selected by one of the selectors in that list.

// Waits for either confirmation dialog or load spinner.
await page.locator(
`//span[contains(@class, 'spinner__loading')]|//div[@id='confirmation']`
).waitFor();

标签到表单控件重定向

Label to form control retargeting

警告

我们推荐 通过标签文本定位,而不是依赖标签到控制的重定向。

We recommend locating by label text instead of relying to label-to-control retargeting.

Playwright 中的目标输入操作会自动区分标签和控件,因此你可以定位标签以对关联的控件执行操作。

Targeted input actions in Playwright automatically distinguish between labels and controls, so you can target the label to perform an action on the associated control.

例如,考虑以下 DOM 结构:<label for="password">Password:</label><input id="password" type="password">。你可以使用 page.getByText() 通过 "密码" 文本来定位标签。但是,将对输入而不是标签执行以下操作:

For example, consider the following DOM structure: <label for="password">Password:</label><input id="password" type="password">. You can target the label by it's "Password" text using page.getByText(). However, the following actions will be performed on the input instead of the label:

// Fill the input by targeting the label.
await page.getByText('Password').fill('secret');

但是,其他方法将针对标签本身,例如 expect(locator).toHaveText() 将断言标签的文本内容,而不是输入字段。

However, other methods will target the label itself, for example expect(locator).toHaveText() will assert the text content of the label, not the input field.

// Fill the input by targeting the label.
await expect(page.locator('label')).toHaveText('Password');

旧版文本定位器

Legacy text locator

警告

我们推荐现代 文本定位器

We recommend the modern text locator instead.

旧版文本定位器匹配包含传递文本的元素。

Legacy text locator matches elements that contain passed text.

await page.locator('text=Log in').click();

旧版文本定位器有一些变体:

Legacy text locator has a few variations:

  • text=Log in - 默认匹配不区分大小写,修剪空格并搜索子字符串。例如,text=Log 匹配 <button>Log in</button>

    text=Log in - default matching is case-insensitive, trims whitespace and searches for a substring. For example, text=Log matches <button>Log in</button>.

    await page.locator('text=Log in').click();
  • text="Log in" - 文本正文可以使用单引号或双引号进行转义,以在修剪空格后搜索具有精确内容的文本节点。

    text="Log in" - text body can be escaped with single or double quotes to search for a text node with exact content after trimming whitespace.

    例如,text="Log"<button>Log in</button> 不匹配,因为 <button> 包含不等于 "Log" 的单个文本节点 "Log in"。但是,text="Log"<button> Log <span>in</span></button> 匹配,因为 <button> 包含文本节点 " Log "。这种精确模式意味着区分大小写匹配,因此 text="Download" 不会匹配 <button>download</button>

    For example, text="Log" does not match <button>Log in</button> because <button> contains a single text node "Log in" that is not equal to "Log". However, text="Log" matches <button> Log <span>in</span></button>, because <button> contains a text node " Log ". This exact mode implies case-sensitive matching, so text="Download" will not match <button>download</button>.

    引用的正文遵循通常的转义规则,例如 使用 \" 转义双引号字符串中的双引号:text="foo\"bar"

    Quoted body follows the usual escaping rules, e.g. use \" to escape double quote in a double-quoted string: text="foo\"bar".

    await page.locator('text="Log in"').click();
  • /Log\s*in/i - 主体可以是封装在 / 符号中的 类似 JavaScript 的正则表达式。例如,text=/Log\s*in/i 匹配 <button>Login</button><button>log IN</button>

    /Log\s*in/i - body can be a JavaScript-like regex wrapped in / symbols. For example, text=/Log\s*in/i matches <button>Login</button> and <button>log IN</button>.

    await page.locator('text=/Log\\s*in/i').click();
注意

以引号("')开头和结尾的字符串选择器被假定为旧文本定位器。例如,"Log in" 在内部转换为 text="Log in"

String selectors starting and ending with a quote (either " or ') are assumed to be a legacy text locators. For example, "Log in" is converted to text="Log in" internally.

注意

匹配总是标准化空白。例如,它将多个空格变成一个,将换行符变成空格,并忽略前导和尾随空白。

Matching always normalizes whitespace. For example, it turns multiple spaces into one, turns line breaks into spaces and ignores leading and trailing whitespace.

注意

buttonsubmit 类型的输入元素通过其 value 而不是文本内容进行匹配。例如,text=Log in 匹配 <input type=button value="Log in">

Input elements of the type button and submit are matched by their value instead of text content. For example, text=Log in matches <input type=button value="Log in">.

id, data-testid, data-test-id, data-test 选择器

id, data-testid, data-test-id, data-test selectors

警告

我们推荐使用 通过测试 id 定位

We recommend locating by test id instead.

Playwright 支持使用某些属性选择元素的简写。目前仅支持以下属性:

Playwright supports shorthand for selecting elements using certain attributes. Currently, only the following attributes are supported:

  • id

  • data-testid

  • data-test-id

  • data-test

// Fill an input with the id "username"
await page.locator('id=username').fill('value');

// Click an element with data-test-id "submit"
await page.locator('data-test-id=submit').click();
注意

属性选择器不是 CSS 选择器,因此不支持任何特定于 CSS 的内容(例如 :enabled)。如需更多功能,请使用适当的 css 选择器,例如 css=[data-test="login"]:enabled

Attribute selectors are not CSS selectors, so anything CSS-specific like :enabled is not supported. For more features, use a proper css selector, e.g. css=[data-test="login"]:enabled.

注意

属性选择器穿透影子 DOM。要选择退出此行为,请在属性后使用 :light 后缀,例如 page.locator('data-test-id:light=submit').click()

Attribute selectors pierce shadow DOM. To opt-out from this behavior, use :light suffix after attribute, for example page.locator('data-test-id:light=submit').click()

链接选择器

Chaining selectors

警告

我们推荐使用 链接定位器

We recommend chaining locators instead.

定义为 engine=body 或短格式的选择器可以与 >> 令牌组合,例如 selector1 >> selector2 >> selectors3。当选择器被链接时,下一个选择器将相对于前一个选择器的结果进行查询。

Selectors defined as engine=body or in short-form can be combined with the >> token, e.g. selector1 >> selector2 >> selectors3. When selectors are chained, the next one is queried relative to the previous one's result.

例如,

For example,

css=article >> css=.bar > .baz >> css=span[attr=value]

相当于

is equivalent to

document
.querySelector('article')
.querySelector('.bar > .baz')
.querySelector('span[attr=value]');

如果选择器需要在正文中包含 >>,则应在字符串内对其进行转义,以免与链接分隔符混淆,例如 text="some >> text"

If a selector needs to include >> in the body, it should be escaped inside a string to not be confused with chaining separator, e.g. text="some >> text".

中间匹配

Intermediate matches

警告

我们建议使用 通过另一个定位器过滤 来定位包含其他元素的元素。

We recommend filtering by another locator to locate elements that contain other elements.

默认情况下,链式选择器解析为最后一个选择器查询的元素。选择器可以以 * 为前缀来捕获中间选择器查询的元素。

By default, chained selectors resolve to an element queried by the last selector. A selector can be prefixed with * to capture elements that are queried by an intermediate selector.

例如,css=article >> text=Hello 捕获带有文本 Hello 的元素,*css=article >> text=Hello(注意 *)捕获包含某些带有文本 Hello 的元素的 article 元素。

For example, css=article >> text=Hello captures the element with the text Hello, and *css=article >> text=Hello (note the *) captures the article element that contains some element with the text Hello.