使用两个文本标准(剧作家,js)从表中选择特定的行



我在使用潜在的唯一标识符从表中选择特定行时遇到麻烦。

给定下表

#events {
font-family: Arial, Helvetica, sans-serif;
border-collapse: collapse;
width: 100%;
margin: 10px 0 20px 0;
}
#events td,
#events th {
border: 1px solid #ddd;
padding: 8px;
}
#events tr:nth-child(even) {
background-color: #f2f2f2;
}
#events tr:hover {
background-color: #ddd;
}
#events th {
padding-top: 12px;
padding-bottom: 12px;
text-align: left;
background-color: #04AA6D;
color: white;
}
<div>
<table id="events" class="table table-striped">
<thead>
<tr>
<th data-qaid="checkbox"><input type="checkbox" /></th>
<th data-qaid="event">Event</th>
<th data-qaid="date">Date</th>
<th data-qaid="location">Location</th>
<th data-qaid="purchase-date">Ticket Purchased</th>
</tr>
</thead>
<tbody>
<tr>
<td data-qaid="checkbox"><input type="checkbox" /></td>
<td data-qaid="event">Movie</td>
<td data-qaid="date">06/06/2022</td>
<td data-qaid="location">Frankfort</td>
<td data-qaid="purchase-date">06/06/2022</td>
</tr>
<tr>
<td data-qaid="checkbox"><input type="checkbox" /></td>
<td data-qaid="event">Concert</td>
<td data-qaid="date">06/06/2022</td>
<td data-qaid="location">Frankfort</td>
<td data-qaid="purchase-date">06/06/2022</td>
</tr>
<tr>
<td data-qaid="checkbox"><input type="checkbox" /></td>
<td data-qaid="event">Park</td>
<td data-qaid="date">06/10/2022</td>
<td data-qaid="location">Memphis</td>
<td data-qaid="purchase-date">06/06/2022</td>
</tr>
<tr>
<td data-qaid="checkbox"><input type="checkbox" /></td>
<td data-qaid="event">Concert</td>
<td data-qaid="date">06/10/2022</td>
<td data-qaid="location">Memphis</td>
<td data-qaid="purchase-date">06/06/2022</td>
</tr>
<tr>
<td data-qaid="checkbox"><input type="checkbox" /></td>
<td data-qaid="event">Sport</td>
<td data-qaid="date">06/12/2022</td>
<td data-qaid="location">Atlanta</td>
<td data-qaid="purchase-date">06/06/2022</td>
</tr>
</tbody>
</table>
</div>
<div id="change-location">
<label>New Location</label>
<input type="text" />
<button>Update Selected</button>
</div>

使用剧作家定位器,我希望能够选择2022年6月10日音乐会的行,然后能够单击该行上的复选框。

我已经能够使用单列定位器并选择遇到的第一行(使用.nth(#))来做到这一点。

const child_locator = page.locator('[data-qaid="Event"]', { hasText: "Concert" }).nth(0);
const row_locator = page.locator("#events tbody tr", { has: child_locator });
row_locator.locator('[data-qaid="checkbox"] input').setChecked();

但是这不起作用,因为我想要的行不会是第一个遇到的行结果。

我想要一些更健壮/动态的东西。我也不知道该怎么做。我尝试过各种各样的事情,比如组合定位器,使用生成的定位器数组来限制后续搜索。我认为这源于我对剧作家定位器尽可能完整的理解。我正在研究文档,但还没有弄清楚这个问题。

我认为我唯一真正的解决方案可能是得到整行的文本,只是正则表达式。但是,如果要搜索的文本出现在一行的另一列中,则可能出现误报的问题。例如,在给定的示例中,如果我想选择日期为"06/06/2022"的音乐会,我的正则表达式仍然会选择日期为"06/10/2022"的音乐会。因为购买的票也将匹配"06/06/2022">

既然没有任何可以绑定的显式选择器,那么唯一的选择就是减少:

  1. 你收集了所有的trs。
  2. 选择含有Concert类型的td类型的tr类型
  3. 从中选择trs,tds出现在06/10/2022
  4. 点击收集的元素

我是这么想的:

/**
* options {{page: Page, search_array: [{column_index: number, needle: string}], tr_selector: Locator}}
*/
static async getRowByValues(options) {
// get the table data
const table_data = await options.page.locator(table_selector).allInnerTexts();
let row_index = table_data.findIndex( (row_text) => {
const text_array = row_text.split("t");
// loop through the search_array data and match to text_array
for (const col_data of options.search_array) {
// fail immediately if false, continue if true.
if (text_array[col_data.column_index] !== col_data.needle) {
return false;
}
}
return true;
});
if (row_index >= 0) {
return options.page.locator(tr_selector).nth(row_index);
} else {
return null;
}
}

可以这样使用:

const desired_row = await getRowByValues({
page: page,
search_array: [
{
column_index: 1,
needle: "Concert"
},
{
column_index: 2,
needle: "06/10/2022"
}
],
tr_selector: page.locator('#events tbody tr')
});
if (desired_row) {
await desired_row.locator('[data-qaid="checkbox"] input').setChecked(true);
await expect(desired_row.locator('[data-qaid="checkbox"] input')).toBeChecked();
}

最新更新