在selenium中定位WebElements的子节点

时间:2012-05-09 16:31:23

标签: java selenium xpath webdriver

我正在使用selenium来测试我的网络应用程序,我可以使用By.xpath成功找到标签。但是,我现在需要在该节点中找到子节点。

示例:

<div id="a">
    <div>
        <span />
        <input />
    </div>
</div>

我能做到:

WebElement divA = driver.findElement( By.xpath( "//div[@id='a']" ) )

但现在我需要找到输入,所以我可以这样做:

driver.findElement( By.xpath( "//div[@id='a']//input" ) )

然而,在代码中我只有divA,而不是它的xpath ......我想做这样的事情:

WebElement input = driver.findElement( divA, By.xpath( "//input" ) );

但是这样的功能不存在。 我能这样做吗?

BTW:有时我需要找到一个具有某个后代节点的<div>。我怎样才能在xpath中询问包含<div> <span>文字'hello world'&#34;的{{1}}?

5 个答案:

答案 0 :(得分:74)

根据JavaDocs,你可以这样做:

WebElement input = divA.findElement(By.xpath(".//input"));

  

如何在xpath中询问“包含跨度的div-tag”   发短信'hello world'“?

WebElement elem = driver.findElement(By.xpath("//div[span[text()='hello world']]"));

The XPath spec对此有一个令人惊讶的好读。

答案 1 :(得分:2)

如果你必须等待,有一个方法presenceOfNestedElementLocatedBy,它采用&#34;父母&#34;元素和定位符,例如By.xpath

WebElement subNode = new WebDriverWait(driver,10).until(
    ExpectedConditions.presenceOfNestedElementLocatedBy(
        divA, By.xpath(".//div/span")
    )
);

答案 2 :(得分:0)

几周前我也发现自己处于类似的位置。你也可以通过创建一个自定义的ElementLocatorFactory(或简单地将divA传递给DefaultElementLocatorFactory)来查看它是否是第一个div的子节点 - 然后你将调用相应的PageFactory initElements方法。

在这种情况下,如果您执行了以下操作:

PageFactory.initElements(new DefaultElementLocatorFactory(divA), pageObjectInstance));
// The Page Object instance would then need a WebElement 
// annotated with something like the xpath above or @FindBy(tagName = "input")

答案 3 :(得分:-1)

Selenium的By-Class的toString()方法产生类似的东西 “By.xpath:// XpathFoo”

所以你可以从冒号开始使用这样的子字符串:

String selector = divA.toString().substring(s.indexOf(":") + 2);

有了这个,你可以在其他元素中找到你的元素:

WebElement input = driver.findElement( By.xpath( selector + "//input" ) );

优点:你只需要在实际的SUT上搜索一次,这样就可以给你一个性能上的奖励。

缺点:丑陋......如果你想用css selectory搜索父元素并为它的子元素使用xpath,你必须在连接之前检查类型... 在这种情况下,Slanec的解决方案(在WebElement上使用findElement)要好得多。

答案 4 :(得分:-1)

对于查找所有ChildNodes,您可以使用以下代码段

List<WebElement> childs = MyCurrentWebElement.findElements(By.xpath("./child::*"));

        for (WebElement e  : childs)
        {
            System.out.println(e.getTagName());
        }

请注意,这将为所有子节点提供相同级别 - &gt; 就像你有这样的结构:

<Html> 
<body> 
 <div> ---suppose this is current WebElement 
   <a>
   <a>
      <img>
          <a>
      <img>
   <a>

这里只给我3个锚标签的标签名称。如果你想递归所有的子元素,你可以用上面的代码替换 MyCurrentWebElement.findElements(By.xpath(&#34; .//*&# 34;));

希望有助于!!