You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Playwright是否有类似Puppeteer的locator.race元素定位竞争方法?

Playwright是否支持类似Puppeteer的Locator竞速功能?

通常一个HTML元素可以通过不同的定位器找到。以查找<h2>...</h2>元素为例:

<div>
   <section>
      <div class="articleheader">
             <h2 class="headline"
                 role="heading" aria-level="2" 
                 data-label="articleheadline">Locator race</h2>
      </div>
      <div class="articlebody">
      <p>Who finds the node <span>locator</span> first </p>
      </div>
   </section>
</div>

可使用以下Playwright定位器:

// 不同方式的定位器
const byClass = page.locator('h2.headline');
const byRole = page.locator('h2[role="heading"][aria-level="2"]');
const byDataLabel = page.locator('h2[data-label="articleheadline"]');
const byHierarchy = page.locator('section > div.articleheader > h2:first-of-type');

Puppeteer有一个locator.race方法,定义如下:

创建多个定位器的竞速,并行尝试查找元素,但确保只有单个元素会被执行操作。

其签名为:

class Locator {
  static race<Locators extends readonly unknown[] | []>(
    locators: Locators,
  ): Locator<AwaitedLocator<Locators[number]>>;;
}

使用该方法的代码示例:

await puppeteer.Locator.race([
    targetPage.locator('h2.headline'),
    targetPage.locator('h2[role="heading"][aria-level="2"]'),
    targetPage.locator('h2[data-label="articleheadline"]'),
    targetPage.locator('section > div.header > h2:first-of-type'),    
]);

Playwright目前提供了两种替代方式:

// 使用多个选择器(逗号分隔)
await page.locator('button:has-text("Log in"), 
                    button:has-text("Sign in")').click();
// 使用or方法
const newEmail = page.getByRole('button', { name: 'New' });
const dialog = page.getByText('Confirm security settings');

await expect(newEmail.or(dialog).first()).toBeVisible();

if (await dialog.isVisible())
  await page.getByRole('button', { name: 'Dismiss' }).click();
await newEmail.click();

问题:Playwright是否有类似race的功能,可通过首个匹配的选择器找到元素?


更新

我正在开发一个测试页以验证相关答案是否可用,以下是测试页的代码片段:

JavaScript代码

function setAttribute(css_selector, attribute, value) {
   const element = document.querySelector(css_selector);
   if (element) {
   element.setAttribute(attribute, value);
   }
}

const changes = [
  { css_selector:'section h2', attribute:'class',value:'headline'},
  { css_selector:'section h2', attribute:'class',value:'new-headline'},
  { css_selector:'h2[role="presentation"][aria-level="2"]',
    attribute: 'role', value: 'heading' },    
  { css_selector:'h2[data-label="articleheadline"]', 
    attribute: 'data-label', value: 'new-articleheadline' },
  { css_selector: 'section > div.articleheader > h2:first-of-type',
    attribute: 'id', value: 'new-id' }
];

 function applyRandomChange() {
const randomIndex = Math.floor(Math.random() * changes.length);
const change = changes[randomIndex];
setAttribute(change.css_selector, change.attribute, change.value);
 }

 window.addEventListener('load', () => {
   applyRandomChange(); // 页面加载时应用一次修改
   setInterval(applyRandomChange, 1500); // 每1.5秒随机修改一次
 });

CSS代码

h2.headline { color: red; }
h2.new-headline {  color: green; }
h2[role="heading"][aria-level="2"] {
    border: 1px solid blue;
}
section > div.articleheader > h2 {
    background: lightgrey;
}
h2[data-label="articleheadline"] {
  color: purple;
  text-decoration: underline;
}
h2[data-label="new-articleheadline"] {
  color: blue;
  text-decoration: underline;
}

HTML代码

<section>
 <div class="articleheader">
  <h2 role="presentation" aria-level="2" 
      data-label="articleheadline">Locator race</h2>
 </div>
 <div class="articlebody">
 <p>Who finds the node <span>locator</span> first </p>
 </div>
</section>

内容的提问来源于stack exchange,提问作者surfmuggle

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.14 23:37:07