如何在 Playwright 中获取元素的最近父级?

How to get closest parent of element in Playwright?

我是剧作家的新手,我找不到如何获取元素父元素的解决方案? 这是我目前所拥有的:

    const deliveryItems = await page.locator('.js-delivery-container'); //Items
    const deliveryMethod = deliveryItems.locator('input[value="50"]'); //input in items selected by value
    const example_parent = await deliveryMethod.closest('.js-delivery-name'); //name what i want to check
    await expect(example_parent).toHaveText('Osobní odběr'); //check if selected right delivery

但是当我 运行 它时.. 控制台中出现错误弹出窗口:

 TypeError: deliveryMethod.closest is not a function

  33 |
  34 |         const deliveryMethod = deliveryItems.locator('input[value="50"]');
> 35 |         const example_parent = await deliveryMethod.closest('.js-delivery-name');

有人能给我解释一下吗?谢谢

我的结构是这样的:

<div class="select-content-box js-delivery-container">
   <div class="select-content delivery-icon-factory">
        <div class="extended-title transport-icon js-delivery-name">Osobní odběr</div>
        <div class="extended-price js-delivery-price"></div>
        <div class="select-btn">
            <label class="label toggle">
                <input type="radio" name="radio-delivery" value="50">
                <div class="toggle-control"></div>
            </label>
        </div>
        <div class="cleaner"></div>
        <div class="select-address" style=""></div>
    </div>
</div>

您正在尝试的ElementHandle.closest()方法目前在API中不存在(或者在您使用的Playwright版本中还不可用,我只在这个讨论中找到它#6015).这就是错误的原因。

问题

您想根据其值 (input[value="50"]) 找到输入字段与 .js-delivery-name 元素之间的连接,这是不可能的,或者至少任何 .parentElement?.parentElement?.nextSibling?.nextSibling... 结构都可以非常脆弱,同样适用于 XPath axes(它们甚至不在 child-ancestor 关系中,而是有点 "second niece/nephew-second aunt/uncle 关系).

可能的解决方案

我建议如下。 “剧作家可以 select elements based on the page layout。这些可以与常规 CSS 结合以获得更好的效果。”

1-2.) desired name within + delivery items: 使用 child combinator and universal selector 您可以编写可以在容器元素中获取所需元素的模式,例如:.js-delivery-container > * .js-delivery-name

3.) above this input: 当你有准确的选择器时,你可以通过找到最接近的元素匹配另一个 CSS 选择器查询 在特定方向使用:above():below():near():left-of():right-of()方法,例如:above(input[value="50"])。正如文档所说:“匹配位于与内部选择器匹配的任何元素之上的元素”。

//                                delivery items       desired name within    above this input     
//                           ______________________  __  _______________  ________________________
//                          |                      ||  ||               ||                        |
const parent = page.locator('.js-delivery-container > * .js-delivery-name:above(input[value="50"])')
await expect(parent).toHaveText(/Osobní odběr/)

注意:布局选择器使用bounding client rect计算元素的距离和相对位置,所以这些abovebelow等. 方向是严格意义上的布局位置,而不是 DOM 祖先。