元素选择器
选择器是指向页中元素的字符串。它们用于通过 page.click(selector[, options])、page.fill(selector, value[, options])等方法对这些元素执行操作。所有这些方法都接受选择器 selector
作为它们的第一个参数。
快速指南
- 文本选择器
await page.click('text=Log in');
page.click('text=Log in')
了解有关 文本选择器 的更多信息。
- CSS 选择器
await page.click('button');
await page.click('#nav-bar .contact-us-item');
page.click('button')
page.click('#nav-bar .contact-us-item')
了解更多关于 CSS 选择器 的信息。
- 按属性选择,使用 CSS 选择器
await page.click('[data-test=login-button]');
await page.click('[aria-label="Sign in"]');
page.click('[data-test=login-button]')
page.click('[aria-label="Sign in"]')
了解更多关于 CSS 选择器 的信息。
- 组合 CSS 和文本选择器
await page.click('article:has-text("Playwright")');
await page.click('#nav-bar :text("Contact us")');
page.click('article:has-text("Playwright")')
page.click('#nav-bar :text("Contact us")')
了解有关 :has-text()
和 :text()
伪类 的更多信息。
- 元素,该元素包含另一个具有 CSS 选择器的
await page.click('.item-description:has(.item-promo-banner)');
page.click('.item-description:has(.item-promo-banner)')
了解有关 :has()
伪类的更多信息。
- 使用 CSS 选择器根据布局进行选择
await page.click('input:right-of(:text("Username"))');
page.click('input:right-of(:text("Username"))')
了解更多布局选择器。
- 仅可见元素,带有 CSS 选择器
await page.click('.login-button:visible');
page.click('.login-button:visible')
了解更多选择可见元素。
- 选择第N个匹配项
await page.click(':nth-match(:text("Buy"), 3)');
page.click(':nth-match(:text("Buy"), 3)')
了解有关 :nth-match()
伪类的更多信息。
- XPath 选择器
await page.click('xpath=//button');
page.click('xpath=//button')
了解有关 XPath 选择器 的更多信息。
- React 选择器(实验性)
await page.click('_react=ListItem[text *= "milk" i]');
page.click('_react=ListItem[text *= "milk" i]')
了解有关 React 选择器 的更多信息。
- VUE 选择器(实验性)
await page.click('_vue=list-item[text *= "milk" i]');
page.click('_vue=list-item[text *= "milk" i]')
了解更多关于 vue 选择器 的信息。
文本选择器
文本选择器定位包含传递文本的元素。
await page.click('text=Log in');
#
page.click('text=Log in')
文本选择器有一些变化:
text=Log in
:默认匹配不区分大小写,并搜索子字符串。例如,text=Log
和<button>Log in</button>
。text="Log in"
:文本主体可以使用单引号或双引号进行转义,以搜索具有确切内容的文本节点。例如,text="Log"
不匹配<button>Log in</button>
,因为<button>
包含不等于"Log"
的单个文本节点"Log in"
。但是,text="Log"
匹配<button>Log<span>in</span></button>
,因为<button>
包含文本节点"Log"
。
引用的主体遵循通常的转义规则,例如 \"
,用于转义双引号字符串中的双引号: text="foo\"bar"
。
await page.click('text="foo\"bar"');
page.click('text="foo\"bar"')
"Log in"
:以引号(或""
''
)开始和结束的选择器被认为是文本选择器。例如,"Log in"
转换为text="Log in"
内部。
await page.click('"Log in"');
page.click('"Log in"')
/Log\s*in/i
文本可以是JavaScript 正则表达式字符串——即用/
符号包装的正则表达式字符串。例如,text=/Log\s*in/i
匹配项<button>Login</button>
和<button>log IN</button>
。
await page.click('text=/Log\\s*in/i');
page.click('text=/Log\\s*in/i')
article:has-text("Playwright")
::has-text()
伪类可以在 CSS 选择器中使用。它匹配内部某处包含指定文本的任何元素,可能在子元素或后代元素中。例如,article:has-text("Playwright")
火柴<article><div>Playwright</div></article>
。
请注意,:has-text()
应与其他 css
选择器一起使用,比如p.notes:has-text("警告")
。否则它将匹配包含指定文本的所有元素,包括 <body>
。
// Wrong, will match many elements including <body>
await page.click(':has-text("Playwright")');
// Correct, only matches the <article> element
await page.click('article:has-text("Playwright")');
# Wrong, will match many elements including <body>
page.click(':has-text("Playwright")')
# Correct, only matches the <article> element
page.click('article:has-text("Playwright")')
#nav-bar :text("Home")
::text()
伪类可以在 CSS 选择器中使用。它匹配包含指定文本的最小元素。此示例等效于text=Home
,但位于#nav-bar
元素内部。
await page.click('#nav-bar :text("Home")');
page.click('#nav-bar :text("Home")')
#nav-bar :text-is("Home")
+:text-is()
伪类可以在 CSS 选择器中使用,用于严格的文本节点匹配。此示例等效于text="Home"
(注意引号),但位于#nav-bar
元素内部。#nav-bar :text-matches("reg?ex", "i")
::text-matches()
伪类可以在 CSS 选择器中使用,用于基于正则表达式的匹配。此示例等效于text=/reg?ex/i
,但位于#nav-bar
元素内部。
匹配始终规范化空格,例如,它将多个空格转换为一个,将换行符转换为空格,并忽略前导空格和尾随空格。
对于
type
为submit
和button
的<input>
元素,文本选择器会通过其value
属性而不是显示的文本内容进行匹配。例如,text=Log in
会匹配元素<input type=button value="Log in">
。
CSS 选择器
Playwright以两种方式增加标准 CSS 选择器:
- 默认情况下,
css
引擎穿透打开的Shadown DOM. - Playwright添加了自定义伪类
:visible
,如,:text
等等。
await page.click('button');
page.click('button')
筛选可见元素
使用Playwright选择可见元素有两种方法:
- CSS 选择器中
:visible
的伪类; visible=
选择器引擎;
如果你的选择器是 CSS,并且不想依赖于链式选择器,使用 :visible
伪类,如: input:visible
。如果你更喜欢组合选择器引擎,请使用 input >> visible=true
。后者允许你 text=
将、 xpath=
和其他选择器引擎与可见性过滤器相结合。
例如,input
匹配页面上的所有输入,而 input:visible
和 input >> visible=true
仅匹配可见输入。这对于区分非常相似但可见性不同的元素非常有用。
通常最好遵循最佳实践并找到一种更可靠的方法来唯一标识元素。
考虑一个有两个按钮的页面,第一个按钮不可见,第二个按钮可见。
<button style='display: none'>Invisible</button>
<button>Visible</button>
- 这将找到第一个按钮,因为它是 DOM 顺序中的第一个按钮。然后,它将在单击之前等待按钮变为可见,或者在等待时超时:
await page.click('button');
# 第一个按钮
page.click('button')
这也是常见的卡住情况,如果选择器正确但是实际执行时超时退出了,很可能是因为页面中有其它的隐藏元素被匹配到了,从而使执行引擎会一直等待该隐藏元素出现,从而超时。
- 这些将找到第二个按钮,因为它是可见的,然后单击它。
await page.click('button:visible');
await page.click('button >> visible=true');
page.click('button:visible')
page.click('button >> visible=true')
选择包含目标元素的元素
:has()
伪类是一个实验 CSS 伪类,反过来根据子元素定位父元素,传入:has()
的参数为另一个选择器。
假设完整的选择器写作form:has(#username)
,则会去匹配id
属性为"username"
的表单<form>
元素。
下面的代码片段返回内部包含 <div class=promo>
的元素的 <article>
文本内容。
await page.textContent('article:has(div.promo)');
page.text_content('article:has(div.promo)')
使用多个选择器同时匹配元素
:is()
伪类是一个实验 CSS 伪类,能够实现使用多个选择器同时匹配,返回满足任意一个选择器的元素。该函数将选择器列表(逗号,
分隔选择器)作为其参数,并选择可由该列表中的选择器之一选择的任何元素。这对于以更紧凑的形式编写大型选择器非常有用。
// Clicks a <button> that has either a "Log in" or "Sign in" text.
await page.click(':is(button:has-text("Log in"), button:has-text("Sign in"))');
# Clicks a <button> that has either a "Log in" or "Sign in" text.
page.click(':is(button:has-text("Log in"), button:has-text("Sign in"))')
在 Shadown DOM 中选择元素
默认情况下,我们的 css
和 text
引擎穿透Shadow DOM:
- 首先,它们按照迭代顺序搜索 Light DOM 中的元素,然后
- 然后,它们按照迭代顺序在开放的Shadow Root内进行递归搜索。
特别在 css
引擎中,任何后代组合或子组合穿透任意数量的开放Shadow Root节点,包括选择器起始处的隐式后代组合子。它不会在封闭的Shadow Root或 iframe 中进行搜索。
如果你想退出这种行为,你可以使用 :light
CSS 扩展或 text:light
选择器引擎。它们不会穿透Shadow Root。
await page.click(':light(.article > .header)');
page.click(':light(.article > .header)')
更高级的Shadow DOM 用例:
<article>
<div>In the light dom</div>
<div slot='myslot'>In the light dom, but goes into the shadow slot</div>
#shadow-root
<div class='in-the-shadow'>
<span class='content'>
In the shadow dom
#shadow-root
<li id='target'>Deep in the shadow</li>
</span>
</div>
<slot name='myslot'></slot>
</article>
"article div"
与":light(article div)"
两者都匹配第一个<div>In the light dom</div>
。"article > div"
和":light(article > div)"
匹配div
两个元素,这两个元素是的article
直接子元素。"article.in-the-shadow"
匹配<div class='in-the-shadow'>
,穿透Shadow Root,而":light(article.in-the-shadow)"
不匹配任何东西。":light(article div > span)"
不匹配任何内容,因为两个 light-domdiv
元素都不包含span
。"article div > span"
匹配<span class='content'>
,穿透Shadow Root部。"article >.in-the-shadow"
不匹配任何内容,因为<div class='in-the-shadow'>
不是的article
直接子级- 与任何东西都
":light(article >.in-the-shadow)"
不匹配。 "article li#target"
匹配<li id='target'>Deep in the shadow</li>
,穿透两个Shadow Root。
根据布局选择元素
Playwright可以根据页面布局选择元素,常用于表单的字段填写时,根据字段名定位输入框。这些可以与常规 CSS 选择器结合以获得更好的结果,例如 input:right-of(:text("Password"))
匹配"密码"文本右侧的<input>
元素。
布局选择器取决于页面布局,可能会产生意外的结果。例如,当布局改变一个像素时,可以匹配不同的元素。
布局选择器用于bounding client rect计算元素的距离和相对位置。
:right-of(inner > selector)
:匹配与内部选择器匹配的任何元素右侧的元素。:left-of(inner > selector)
:匹配与内部选择器匹配的任何元素左侧的元素。:above(inner > selector)
:匹配位于匹配内部选择器的任何元素之上的元素。:below(inner > selector)
:匹配位于与内部选择器匹配的任何元素之下的元素。:near(inner > selector)
:匹配与内部选择器匹配的任何元素附近(50 个 CSS 像素内)的元素。
// Fill an input to the right of "Username".
await page.fill('input:right-of(:text("Username"))', 'value');
// Click a button near the promo card.
await page.click('button:near(.promo-card)');
# Fill an input to the right of "Username".
page.fill('input:right-of(:text("Username"))', 'value')
# Click a button near the promo card.
page.click('button:near(.promo-card)')
所有布局选择器都支持将可选的最大像素距离作为最后一个参数。例如 button:near(:text("Username"), 120)
,将距离元素最多 120 像素的按钮与文本"username"匹配。
XPath 选择器
XPath是Web中用于描述元素所处的层次(相对于根节点<body>
的层次),因此就有了XPath选择器来定位元素,相当于调用 Document.evaluate
。例如: xpath=//html/body
。
以 ..
或 //
开头的选择器被假定为 XPath 选择器。例如,Playwright会自动将 '//html/body'
转换为 'xpath=//html/body'
。
xpath
不穿透Shadow Root
第N个元素选择器
你可以使用 nth=
选择器定位第N个匹配项,一般与其他的选择器一起调用,与 CSS :nth-child
不同, nth=
选择器的索引是从0开始的,即nth=0
表示选中第一个元素。比如可以用于定位列表<ul>
元素中的第2个列表项,选择器可以写作ul >> nth=1
。
// Click first button
await page.click('button >> nth=0');
// Click last button
await page.click('button >> nth=-1');
# Click first button
page.click('button >> nth=0')
# Click last button
page.click('button >> nth=-1')
React选择器
React 选择器是实验性的,其前缀为
_
。该功能将来可能会发生变化。
React 选择器允许按组件名称和属性值选择元素。该语法与所有属性选择器操作符非常相似属性选择器,并且支持所有属性选择器操作符。
在 React 选择器中,组件名称使用驼峰式命名(CamelCase)格式。
选择器示例:
- 按组件(Component)名称匹配:
_react=BookItem
- 按组件名称和准确的属性值匹配,区分大小写:
_react=BookItem[author = "Steven King"]
- 按不区分大小写的属性值匹配:
_react=[author = "steven king" i]
- 按组件和属性值匹配:
_react=MyButton[enabled]
- 按组件和指定的布尔值(Boolean)匹配:
_react=MyButton[enabled = false]
- 按属性值包含指定文本匹配:
_react=[author *= "King"]
- 按组件和多个属性匹配:
_react=BookItem[author *= "king" i][year = 1990]
- 按嵌套的属性值匹配:
_react=[some.nested.value = 12]
- 按组件和属性值前缀匹配:
_react=BookItem[author ^= "Steven"]
- 按组件和属性值后缀匹配:
_react=BookItem[author $= "Steven"]
要在树中查找 React 元素名称,请使用React 开发工具。
React 选择器支持 React 15 及以上版本。
React 选择器,以及React 开发工具,只适用于未编译为最小包的应用程序。
Vue 选择器
Vue 选择器是实验性的,其前缀为
_
。该功能将来可能会发生变化。
Vue 选择器允许通过组件名称和属性值来选择元素。该语法与所有属性选择器操作符非常相似属性选择器,并且支持所有属性选择器操作符。
在 Vue 选择器中,组件名称使用连字符-
间隔式命名(kebab-case)格式。
选择器示例:
- 按组件名称(Component)匹配:
_vue=book-item
- 按组件和准确的属性值匹配,区分大小写:
_vue=book-item[author = "Steven King"]
- 按不区分大小写的属性值匹配:
_vue=[author = "steven king" i]
- 按组件和属性值匹配:
_vue=my-button[enabled]
- 按组件和指定的布尔值(Boolean)匹配:
_vue=my-button[enabled = false]
- 按属性值包含指定文本匹配:
_vue=[author *= "King"]
- 按组件和多个属性匹配:
_vue=book-item[author *= "king" i][year = 1990]
- 按嵌套的属性值匹配:
_vue=[some.nested.value = 12]
- 按组件和属性值前缀匹配:
_vue=book-item[author ^= "Steven"]
- 按组件和属性值后缀匹配:
_vue=book-item[author $= "Steven"]
要在树中查找 Vue 元素名称,请使用Vue 开发工具。
Vue 选择器支持 Vue2 及更高版本。
Vue 选择器,以及Vue 开发工具,只适用于未最小化构建的应用程序。
id
, data-testid
, data-test-id
, data-test
选择器
Playwright支持使用某些属性选择元素的简写。目前,仅支持以下属性:
id
data-testid
data-test-id
data-test
// Fill an input with the id "username"
await page.fill('id=username', 'value');
// Click an element with data-test-id "submit"
await page.click('data-test-id=submit');
# Fill an input with the id "username"
page.fill('id=username', 'value')
# Click an element with data-test-id "submit"
page.click('data-test-id=submit')
属性选择器不是 CSS 选择器,因此不支持任何特定
:enabled
于 CSS 的东西。有关更多功能,请使用适当的 CSS 选择器,例如css=[data-test="login"]:enabled
属性选择器穿透Shadown DOM.要选择退出此行为,
:light
请在属性后使用后缀,例如page.click('data-test-id:light=submit')
从查询结果中选择第N个匹配项
有时页面包含许多相似的元素,很难选择一个特定的元素。例如:
<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 的。
// Click the third "Buy" button
await page.click(':nth-match(:text("Buy"), 3)');
# Click the third "Buy" button
page.click(':nth-match(:text("Buy"), 3)')
使用 Page.WaitForSelector(Selector[,Options])等待指定数量的元素出现 :nth-match()
也很有用。
// Wait until all three buttons are visible
await page.waitForSelector(':nth-match(:text("Buy"), 3)');
# Wait until all three buttons are visible
page.waitForSelector(':nth-match(:text("Buy"), 3)')
与
:nth-child()
不同,元素不必是同级,它们可以位于页面上的任何位置。在上面的代码片段中,所有三个按钮都匹配:text("Buy")
选择器,并:nth-match()
选择第三个按钮。通常可以通过某些属性或文本内容来区分元素。在这种情况下,最好使用 文本 或 CSS 选择器,而不是
:nth-match()
。
链式选择器
多个选择器可以用>>
字符拼接,例如 selector1 >> selector2 >> selectors3
。当选择器被链接时,会相对于前一个选择器的结果来查询下一个选择器。
例如,
css=article >> css=.bar > .baz >> css=span[attr=value]
相当于JavaScript中DOM操作:
document
.querySelector('article')
.querySelector('.bar > .baz')
.querySelector('span[attr=value]')
如果选择器需要包含 >>
在主体中,则应在字符串中进行转义,以免与链接分隔符混淆,例如 text="some >> text"
。
中间匹配
默认情况下,链式选择器返回的是由最后一个选择器查询到的元素。但是也可以为选择器添加前缀*
,来捕获并返回中间的选择器查询到元素。
例如,css=article >> text=Hello
捕获带有文本 Hello
的元素,并 *css=article >> text=Hello
(注意 *
)捕获包含带有文本 Hello
的某些元素的 article
元素。
最佳实践
选择器的选择直接影响自动化脚本的健壮性和维护成本。以下策略可帮助您构建更可靠的测试用例。
1. 选择器优先级策略
第一优先级:用户可感知属性
优先选择与UI交互直接相关的属性,这些属性通常与视觉呈现或功能语义强关联。特别是,在多语言环境中,语义化属性比文本内容更可靠,因为它们不会受到语言变化的影响。
属性类型 | 示例 | Playwright语法 |
---|---|---|
文本内容 | "Login"按钮 | text="Login" |
占位符文本 | 搜索框placeholder | [placeholder="Search"] |
ARIA角色 | 关闭按钮 | [aria-label="Close"] |
组合查询 | 导航栏中的登录文本 | nav >> text=Login |
示例
// 推荐使用语义化属性,避免仅使用纯文本选择器(适用于多语言场景)
await page.click('[aria-label="Submit form"]');
# 推荐使用语义化属性,避免仅使用纯文本选择器(适用于多语言场景)
page.click('[aria-label="Submit form"]')
反例:避免仅使用文本选择器
// 反例:在多语言环境中,避免使用纯文本选择器
await page.click('text="登录"'); // 如果语言切换,"登录"文本将会变化
# 反例:在多语言环境中,避免使用纯文本选择器
page.click('text="登录"') # 如果语言切换,"登录"文本将会变化
第二优先级:专用测试属性
当用户可见属性不稳定时,与开发团队约定测试专用属性(如data-testid
):
<!-- 开发侧添加测试属性 -->
<button data-testid="nav-login-btn">Login</button>
// 使用自定义的数据属性(data-testid)直接定位按钮
await page.click('data-testid=nav-login-btn');
// 使用标准的CSS属性选择器语法定位按钮
await page.click('[data-testid="nav-login-btn"]');
# 使用自定义的数据属性(data-testid)直接定位按钮
page.click('data-testid=nav-login-btn')
# 使用标准的CSS属性选择器语法定位按钮
page.click('[data-testid="nav-login-btn"]')
协作建议:
- 建立团队测试属性规范(如统一使用
data-testid
) - 在代码审查中检查关键元素的测试属性
- 通过ESLint规则确保测试属性不被误删
2. 避免结构耦合的选择器
高风险选择器特征
❌ XPath/CSS依赖DOM层级结构
❌ 包含nth-child
等位置索引
❌ 使用框架生成的随机ID
// 脆弱的选择器(依赖DOM结构)
await page.click('#root > div > header > div:nth-child(2) > button');
// 改进后的稳定选择器
await page.click('header [data-testid="user-menu"]');
# 高风险选择器
page.click('//*[@id="root"]/div/header/div[2]/button')
# 稳定选择器
page.click('header [data-testid="user-menu"]')
3. 超时策略优化
默认超时配置
通过context.setDefaultTimeout
设置全局等待阈值(默认30秒)。超时后未完成操作将抛出错误。
// 创建一个新的浏览器上下文
const context = await browser.newContext();
// 设置该浏览器上下文的默认超时时间为10秒
context.setDefaultTimeout(10000);
// 单个操作覆盖全局设置:点击按钮,如果5秒内未完成则抛出超时错误
await page.click('button#submit', { timeout: 5000 });
# 创建一个新的浏览器上下文
context = await browser.new_context()
# 设置该浏览器上下文的默认超时时间为10秒
context.set_default_timeout(10000)
# 单个操作覆盖全局设置:点击按钮,如果5秒内未完成则抛出超时错误
await page.click('button#submit', timeout=5000)
实践建议:
- 推荐优先使用显式等待(如
page.waitForSelector
)替代全局隐式等待 - CI环境建议设置更短的全局超时(如15秒)
- 关键操作单独设置合理超时(如登录操作设为8秒)
选择器诊断与调试
在Web自动化测试中,选择器的稳定性和准确性非常重要。以下是常见的选择器问题及解决方法:
- 选择器超时:选择器在执行过程中长时间无法找到元素。
- 选择器过长:生成的选择器过于冗长,难以维护。
- 选择器不易读:复杂的选择器让代码难以理解和调试。
本节将介绍如何生成、调试和优化选择器,以帮助你顺利完成Web自动化工作。
常见选择器生成方式
方法 | 优点 | 缺点 | 适用场景 |
---|---|---|---|
录制生成 | 快速生成基础脚本 | 选择器易受内容变化影响 | 快速原型开发 |
侦测器生成 | 可视化元素定位 | 需要手动验证选择器稳定性 | 复杂元素定位 |
开发者工具生成 | 获取原生CSS/XPath | 不支持Playwright扩展语法 | 基础元素分析 |
1. 通过录制生成选择器
录制功能是生成选择器的最常见方式。在CukeTest中启动Web录制后,你可以快速生成每一步操作的脚本和相关元素的选择器。录制生成的选择器最适用于快速原型开发,但如果脚本流程发生变化,选择器可能失效。
注意:如果某操作中输入了动态内容(例如用户名
"user1"
),录制时生成的选择器(如text=user1
)可能会在后续回放时失效,因为所用文本会随环境变化而不同。
2. 通过CukeTest侦测器生成选择器
在录制过程中,若需要调试某个选择器或为元素手动生成选择器,可以使用CukeTest侦测器。侦测器能够支持多种选择器语法,目前生成与录制时相同的选择器。
3. 通过浏览器开发者工具生成选择器
浏览器的开发者工具也能帮助你生成选择器。该方法仅支持Web原生的CSS和XPath选择器,并且不支持Playwright特有的扩展语法,如文本选择器或nth
选择器。
提示:如果在Electron应用中使用开发者工具进行调试,需要开发者提供相应的支持。详情参考Electron开发者工具扩展。
调试选择器
在使用Playwright时,选择器可能不会立刻抛出错误。通常,如果选择器匹配不到任何元素,Playwright会继续等待,直到超时。
注意:如果选择器本身存在语法错误,Playwright会立即抛出错误,此时可以根据提示修正选择器。
常见调试场景
选择器匹配环境变化
选择器匹配错误元素
匹配到多个元素:有时,选择器匹配到了多个元素,但目标元素不是第一个匹配项。比如,录制时生成的选择器仅适用于某些特定场景,在其他场景下可能匹配到错误的元素。此时可以使用
element.screenshot()
将匹配到的元素截图,进行进一步分析。匹配到不可见元素:当选择器匹配到一个不可见元素时,Playwright会一直等待,直到该元素变得可见为止。这通常会导致超时错误。为了避免这种情况,可以使用可见选择器(
visible=true
)来确保选择器仅匹配到可见的元素。
解决策略
- 修正易变内容:尽量避免在选择器中使用动态内容(如时间、随机
id
等)。可以使用动态匹配策略(如文本匹配或正则表达式)。 - 使用可见选择器:避免匹配到不可见元素,确保选择器只匹配到页面中实际可见的元素。
- 调试选择器:当遇到选择器不匹配时,可以通过截图、使用CukeTest侦测器或浏览器控制台调试选择器,确保选择器准确、稳定。