Selenium的ByChained课程如何真正起作用?

时间:2014-03-13 14:08:19

标签: selenium selenium-webdriver webdriver

我对documentation for ByChained class提及的内容感到非常困惑。它说:

  
    

用于使用一系列其他查找来定位文档中的元素的机制。该类将找到匹配的所有DOM元素     每个定位器按顺序排列,例如driver.findElements(新     ByChained(by1,by2))将找到匹配by2和的所有元素     出现在与by1匹配的元素下。

  

在code.google.com上还有一个issue selenium,为ByChained类引发,有人评论说它用于使用多个定位器查找元素/元素。

我不明白。为什么by1和by2是两个不同元素的定位器?当我最初遇到这个课程时,我觉得通过使用不同的定位器来帮助定位元素。因此,如果一个定位器不起作用,则下一个定位器将起作用。但是当我几乎使用这个类时,它表现得非常奇怪,并且一直抛出NoSuchElementException。

例如,如果我的html是:

<html>
  <body>
    <div id="details">
      <input id="firstName" class="personName" type="text"/>
    </div>
  </body>
</html>

我想通过在ByChained中使用两个定位器来找到输入字段:
1.使用By.id("firstName")
2.使用By.className("personName")

所以我的代码变成了:

By myBy = new ByChained(By.id("firstName"),By.className("personName"));
driver.findElement(myBy);

执行时,我得到了NoSuchElementException。我期待如果我的第一个By不起作用,那么它将在系列中找到具有下一个By的元素。

有人可以解释一下这个类如何使用一个例子以及在哪些场景下可以使用它?

3 个答案:

答案 0 :(得分:17)

这个类的功能是允许你使用dom中的heirarchy来定位一个元素。

我们可以说出于某些原因你有以下html:

<html>
    <body>
        <div id="details">
            <input id="firstName" class="personName" type="text"/>
        </div>
        <input id="firstName" class="personName" type="text"/>
    </body>
</html>

并且你希望获得div之间的元素而不是它自己的元素。您可以使用ByChained by通过执行以下操作来指定您想要该元素:

new ByChained(By.id("details"),By.id("firstName"));

它会发现第一个元素然后在dom heirarchy中搜索下面列表中的选择器。基本上这个By只是一个很好的清洁方式,不再需要执行以下操作:

details = driver.findElement(By.id("details"));
input = details.findElement(By.id("firstName"));

答案 1 :(得分:8)

您的请求将被称为ByAny的内容满足,该内容将返回与任何传递的By参数匹配的元素。没有这样的AFAIK级别。

但是,ByChained的工作方式不同。它找到第一个参数匹配的元素,然后使用第二个参数等搜索它们的后代。所以,如果你有这样的HTMl:

<html>
    <body>
        <div id="details">
            <input id="firstName" class="personName" type="text"/>
        </div>
        <div id="notDetails">
            <input id="secondName" class="personName" type="text"/>
        </div>
    </body>
</html>

并且您想在class=personName下找到id=details元素,您可以使用CSS选择器,XPath表达式或

new ByChained(By.id("details"), By.className("personName"))

请注意,还有一个ByAll类,用于搜索与传递的所有By个参数匹配的元素。

答案 2 :(得分:1)

值得注意的是(因为我从未见过有人提到过这一点),ByChained应该像其他任何By定位器一样使用,如下所示:

driver.findElements( new ByChained(By.id("details"), By.className("personName")) )

driver.findElements( new ByAll(By.id("err1"), By.className("errBox")) )