Java Selenium使用Css定位表中的单元格

Java Selenium使用Css定位表中的单元格,java,firefox,selenium,selenium-webdriver,Java,Firefox,Selenium,Selenium Webdriver,Selenium似乎无法在我使用以下代码指定的表中找到输入元素: driver.findElement(By.cssSelector("td:contains('Community Member')+td+td>input:contains('ACTION_DELETE')")).click(); 它抛出了一个无效的选举例外。以下是我正在使用的页面源中的行的片段: <tr id="aui_3_2_0_1240" class="portlet-section-alternate re

Selenium似乎无法在我使用以下代码指定的表中找到输入元素:

driver.findElement(By.cssSelector("td:contains('Community Member')+td+td>input:contains('ACTION_DELETE')")).click();
它抛出了一个无效的选举例外。以下是我正在使用的页面源中的行的片段:

<tr id="aui_3_2_0_1240" class="portlet-section-alternate results-row alt lfr-role lfr-role-community last">
    <td class="align-left col-1 first valign-middle" headers="issq_col-1" colspan="1"> Community Member </td>
    <td class="align-left col-2 valign-middle" headers="issq_col-2" colspan="1">
    <td id="aui_3_2_0_1239" class="align-left col-3 valign-middle" headers="issq_col-3"     colspan="1">
        <input id="aui_3_2_0_1211" type="checkbox" name="10124_ACTION_DELETE"/>
    </td>
    <td class="align-left col-4 valign-middle" headers="issq_col-4" colspan="1">
    <td class="align-left col-5 valign-middle" headers="issq_col-5" colspan="1">
    <td class="align-left col-6 valign-middle" headers="issq_col-6" colspan="1">
    <td class="align-left col-7 valign-middle" headers="issq_col-7" colspan="1">
    <td class="align-left col-8 valign-middle" headers="issq_col-8" colspan="1">
    <td class="align-left col-9 last valign-middle" headers="issq_col-9" colspan="1">
</tr>
关于如何最好地完成此任务或修复现有代码,有什么建议吗

尝试使用此Xpath:

//*[@type='checkbox'][contains(@name,'_ACTION_DELETE')]
编辑

编辑:在Jim Evans评论后更正

尝试使用以下Xpath:

//*[@type='checkbox'][contains(@name,'_ACTION_DELETE')]
编辑

编辑:在Jim Evans评论后更正

尝试使用此xpath单击与“社区成员”相关的复选框:

尝试使用此xpath单击与“社区成员”相关的复选框:


您正试图在CSS选择器中使用:contains伪选择器。此伪选择器不是任何已发布CSS标准的一部分。不幸的是,由于jQuery使用的JavaScript CSS选择器引擎实现允许使用它,所以它变得很常见。由于驱动程序实现依赖于浏览器的本机CSS选择器引擎实现,因此它们不支持:contains伪选择器,并抛出您看到的异常。另外,我注意到您正试图找到一个复选框,其中name属性而不是element内容包含您要搜索的字符串。在这种情况下:contains无论如何都不会工作

撇开使用元素中包含的文本查找元素的固有不稳定性不谈,如果您真的想这样做,那么通过XPath查找可能是您唯一的选择。此外,复选框元素不是包含要查找的文本的元素的后代。相反,它是一个同级元素,CSS选择器不允许您在DOM树上找到父元素。同样,这是XPath最好处理的特性

我将使用以下方法处理此问题:

public void clickCheckboxInTable(String value, String action) {
  // Assume the WebDriver instance is stored in a class-level
  // variable named 'driver'.
  WebElement tableCell = driver.findElement(By.xpath("//td[contains(., '" + value + "')]"));
  WebElement checkbox = tableCell.findElement(By.xpath("..//input[contains(@name, '" + action + "')]"));
  checkbox.click();
}
请注意,此解决方案执行两个查找。分两个步骤执行此操作,使您有机会在需要时执行与包含您的值的单元格相关的其他操作。否则,您可以使用如下单个XPath表达式:

// Using the 'direct parent' operator ('..'), but you could also
// use other axis functions like 'following-sibling'.
findElement(By.xpath("//td[contains(., '" + value + "')]/..//input[contains(@name, '" + action + "')]"));

您正试图在CSS选择器中使用:contains伪选择器。此伪选择器不是任何已发布CSS标准的一部分。不幸的是,由于jQuery使用的JavaScript CSS选择器引擎实现允许使用它,所以它变得很常见。由于驱动程序实现依赖于浏览器的本机CSS选择器引擎实现,因此它们不支持:contains伪选择器,并抛出您看到的异常。另外,我注意到您正试图找到一个复选框,其中name属性而不是element内容包含您要搜索的字符串。在这种情况下:contains无论如何都不会工作

撇开使用元素中包含的文本查找元素的固有不稳定性不谈,如果您真的想这样做,那么通过XPath查找可能是您唯一的选择。此外,复选框元素不是包含要查找的文本的元素的后代。相反,它是一个同级元素,CSS选择器不允许您在DOM树上找到父元素。同样,这是XPath最好处理的特性

我将使用以下方法处理此问题:

public void clickCheckboxInTable(String value, String action) {
  // Assume the WebDriver instance is stored in a class-level
  // variable named 'driver'.
  WebElement tableCell = driver.findElement(By.xpath("//td[contains(., '" + value + "')]"));
  WebElement checkbox = tableCell.findElement(By.xpath("..//input[contains(@name, '" + action + "')]"));
  checkbox.click();
}
请注意,此解决方案执行两个查找。分两个步骤执行此操作,使您有机会在需要时执行与包含您的值的单元格相关的其他操作。否则,您可以使用如下单个XPath表达式:

// Using the 'direct parent' operator ('..'), but you could also
// use other axis functions like 'following-sibling'.
findElement(By.xpath("//td[contains(., '" + value + "')]/..//input[contains(@name, '" + action + "')]"));

你可以尝试输入[name*='ACTION\u DELETE']你可以尝试输入[name*='ACTION\u DELETE']这如何区分这一行?这只是具有相同类型输入单元格的多个单元格中的一行,所有单元格都有ACTION_DELETE复选框。我需要通过第一列Community Member中的值来区分这一行。这个答案取决于您提供的一个tr?页面是否包含更多具有相同属性的tr?是的,它是一个多行表。为了简洁起见,我刚刚加入了我正在处理的那一行。好了,明白了。诀窍是使用规范化空间来删除文件中不必要的空间text@SaifurXPath对于提供的DOM结构不起作用。输入元素不是包含搜索文本的td元素的后代;它是一个兄弟姐妹的后代。但这如何区分这一行呢?这只是具有相同类型输入单元格的多个单元格中的一行,所有单元格都有ACTION_DELETE复选框。我需要通过第一列Community Member中的值来区分这一行。这个答案取决于您提供的一个tr?页面是否包含更多具有相同属性的tr?是的,它是一个多行表。为了简洁起见,我刚刚加入了我正在处理的那一行。好了,明白了。诀窍是使用规范化空间来删除文件中不必要的空间text@SaifurXPath对于提供的DOM结构不起作用。输入元素不是td元素contai的后代
对搜索到的文本进行排序;这是一个兄弟姐妹的后代。我要感谢你对吉姆的上述解释。我一直在思考为什么CSS选择器中没有使用“contains”。瞧!以上我现在明白了@JimEvans非常感谢您的出色回答和深刻见解。解释如果您愿意删除您的答案中未测试代码的表示,那么它将非常有效。我要感谢您对@Jim的上述解释。我一直在思考为什么CSS选择器中没有使用“contains”。瞧!以上我现在明白了@JimEvans非常感谢您的出色回答和深刻见解。解释如果您愿意删除答案中未经测试的代码的表示,那么它将非常有效。
// Using the 'direct parent' operator ('..'), but you could also
// use other axis functions like 'following-sibling'.
findElement(By.xpath("//td[contains(., '" + value + "')]/..//input[contains(@name, '" + action + "')]"));