Javascript 剧作家有没有办法在动态表格中选择一个特定的按钮?

Javascript 剧作家有没有办法在动态表格中选择一个特定的按钮?,javascript,css-selectors,e2e-testing,playwright,Javascript,Css Selectors,E2e Testing,Playwright,我是新开发人员,在创建一个e2e测试时面临着一个真正的问题。 基本上,我有一个包含2行或更多行的表,每行有5列(title、x、y、z按钮)。 如何使用标题单击正确行上的按钮?(这是证明此表的删除过程有效的测试)。 我正在测试的应用程序是使用React框架编写的,因此所有表都会频繁更改,我需要一种方法来信任代码,并且不存在任何bug。 HTML 期望的行为 我的代码似乎没有遵循最佳实践,我需要一个分为两部分的解决方案。 1-将正确的行保存到变量中 2-单击保存行中包含的按钮快速回答 使用以下选

我是新开发人员,在创建一个e2e测试时面临着一个真正的问题。
基本上,我有一个包含2行或更多行的表,每行有5列(title、x、y、z按钮)。 如何使用标题单击正确行上的按钮?(这是证明此表的删除过程有效的测试)。 我正在测试的应用程序是使用React框架编写的,因此所有表都会频繁更改,我需要一种方法来信任代码,并且不存在任何bug。

HTML

期望的行为

我的代码似乎没有遵循最佳实践,我需要一个分为两部分的解决方案。
1-将正确的行保存到变量中
2-单击保存行中包含的按钮

快速回答 使用以下选择器组合可靠地单击右按钮

const row=wait page.waitForSelector('*css=tr>>text=Some title');
常量按钮=等待行。$(“按钮”);
等待按钮。单击();
深入解释 Playwright是一个很棒的工具,可能是迄今为止最好的web自动化工具之一。但它需要正确使用

1.选择正确的行
const row=wait page.waitForSelector('*css=tr>>text=Some title');
这一行指示剧作家在页面中找到一个
tr
元素,该元素包含一个文本内容与字符串
Some title
匹配的元素

表达式由两个单独的选择器组成,即
css=tr
text=Some title

第一个将使用
css
选择器引擎,只针对所有
tr
元素。第二个引擎使用
文本
引擎,从而匹配文本内容

>
指示剧作家将两个选择器合并为一个选择器。这是通过首先计算css=tr来实现的。在第一选择器的每个匹配元素上应用第二选择器

通常,组合选择器返回最右侧选择器的结果:
tr>>text=Some title
将为您提供元素
Some title
。 但是可以使用
*
标记所需的选择器(同时使用所有组合选择器缩小结果范围)

注意:asterix
*
强制明确指定选择器引擎(
css=
),否则剧作家会猜错引擎

2.选择按钮
const button=等待行。$(“按钮”);
一旦我们有了正确的行,在这种情况下选择按钮就更容易了。一个简单的查询选择器(
$
)就足够了,因为它是行中唯一存在的按钮元素

上调用
$
(而不是
)将只匹配
的DOM子树中的元素。这与组合匹配器的工作原理完全相同

下一节将解释为什么步骤1必须使用
waitForSelector()


正确的时机 就像你的例子一样,许多网站都是动态的。这意味着您在使用自动脚本查找页面中的内容时会遇到计时问题:当剧作家搜索所需内容时,表可能尚未呈现。更糟糕的是,如果它在你的计算机上工作,它可能会在几周后在另一台计算机上失败

这就是为什么查看与网页交互的每一行并确定是否存在时间问题很重要的原因

一些剧作家的方法会定期探测选择器是否匹配,只有在某个超时后才会失败。其他人不会等待并立即失败

有时方法在名称中指明它们是否正在等待(例如,
page.waitForSelector()
)。但情况并非总是如此(例如,
elementHandle.click()
实际上正在等待)

因此,必须仔细阅读这些描述

现在回到示例:

在步骤1中,我们必须使用等待方法,因为我们不知道动态表何时实际呈现到页面。在第2步中,不需要使用等待方法,因为我们可以确定在第1步成功后页面中是否存在该表。

我真的不知道您所说的右行是什么意思。行是堆叠的,它们不在左侧或右侧。也许你指的是一个专栏?是否要选择按钮所在的最右边的列?或者别的什么?我指的是我需要的那个,基本上,我在这个表中添加了一个元素,有一个特定的标题,现在我想删除我在第四列中添加的同一个元素,带有“right”的按钮,我指的是正确的那个,这回答了你的问题吗?
<table>
    <tr>
     <td>Some Title</td>
     <td>x</td>
     <td>y</td>
     <td>
       <button>I need to click this</button>
    </td>
    </tr>
    <!--other rows--!>
</table>  
const rows = await page.$$eval("tr", (row) =>
    row.map((e) => e.textContent)
);
const correctRowIndex = rows.findIndex((e) => e.includes(TITLE_I_KNOW));
await page.click(
    "//tr[normalize-space(.)='" + rows[correctRowIndex] + "']/td/button"
);