如何使用Playwright根据指定文本选择相邻的<td>元素
问题描述
我遇到了一个难题:使用Playwright验证表格数据时,需要实现给定文本“Cat”则检查“Dog”是否存在,给定“Space”则检查“Rocket”是否存在的功能。我尝试了以下代码:
const planet = (await page.locator('tr:has(td.col_d:has-text("Saturn")) >> a')).innerText();
但未能成功。我考虑过获取所有<td>的文本存入数组,通过索引判断对应位置的文本,但想知道是否有更简便的方法。
相关表格HTML结构如下(已修正部分语法错误):
<tbody> <tr> <td class="labelCol"> Title A </td> <td class="dataCol col02"><span> <a href="/00578000000VqXe" title="POS ""></a> <a href="/00578000000VqXe" id="lookup00578000000VqXelea1" onblur="LookupHo">Data A</a> </td> <td class="labelCol">Title X</td> <td class="dataCol">Data X</td> </tr> <tr> <td class="labelCol" > Cat </td> <td class="dataCol col02">Dog</td> <td class="labelCol" > Saturn </td> <td class="dataCol">Jupiter</td> </tr> <tr > <td class="labelCol" > Blue </td> <td class="dataCol col02">Red</td> <td class="labelCol" > Reason </td> <td class="dataCol">Space</td> </tr> <tr> <a href="/00578000000VqXe" id="lookup00578000000VqXelea1" onblur="LookupHo">Rocket</a> </tr> </tbody>
解决方案
1. 直接通过定位器关联标签与对应值
不需要将所有<td>存入数组,直接通过标签所在的<tr>定位对应数据单元格,更高效简洁:
验证"Cat"对应"Dog"
// 定位包含"Cat"的labelCol所在tr,再获取其下的dataCol文本 const dogText = await page.locator('tr:has(td.labelCol:has-text("Cat")) >> td.dataCol').innerText(); expect(dogText.trim()).toBe("Dog");
验证"Space"对应"Rocket"
根据HTML结构,"Space"在第三行的dataCol中,"Rocket"在相邻的下一行<tr>里,可通过相邻元素选择器定位:
// 找到包含"Space"的tr,定位其下一个tr中的a标签文本 const rocketText = await page.locator('tr:has(td.dataCol:has-text("Space")) + tr >> a').innerText(); expect(rocketText.trim()).toBe("Rocket");
2. 修复你原有代码的问题
你之前的代码失败原因:
- 选择器中的
td.col_d不存在,表格里没有col_d类,应替换为实际存在的td.labelCol或td.dataCol innerText()是异步方法,需正确添加await,原代码括号位置错误
修正后的示例(以Saturn为例):
const planet = await page.locator('tr:has(td.labelCol:has-text("Saturn")) >> td.dataCol').innerText(); expect(planet.trim()).toBe("Jupiter");
3. 封装通用验证函数(可选)
如果需要多次验证不同的标签-值对,可封装成复用函数:
async function verifyLabelAndValue(labelText, expectedValue, locatorSuffix = ">> td.dataCol") { const actualValue = await page.locator(`tr:has(td.labelCol:has-text("${labelText}")) ${locatorSuffix}`).innerText(); expect(actualValue.trim()).toBe(expectedValue); } // 使用示例 await verifyLabelAndValue("Cat", "Dog"); // 针对Space和Rocket的特殊结构,传入自定义定位后缀 await verifyLabelAndValue("Space", "Rocket", "+ tr >> a");
内容的提问来源于stack exchange,提问作者Huckleberry Carignan
相关产品推荐
相关产品推荐

