44

我正在使用 selenium 测试我的 Web 应用程序,并且可以使用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" ) );

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

顺便说一句:有时我需要找到一个<div>具有某个后继节点的节点。如何在 xpath 中询问“<div>包含<span>带有文本的 a 'hello world'”?

4

5 回答 5

86

根据JavaDocs,您可以这样做:

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

我如何在 xpath 中询问“包含文本‘hello world’的跨度的 div-tag”?

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

XPath 规范在这方面是一个令人惊讶的好读物。

于 2012-05-09T17:44:32.653 回答
5

如果您必须等待,则有一种方法presenceOfNestedElementLocatedBy采用“父”元素和定位器,例如By.xpath

WebElement subNode = new WebDriverWait(driver,10).until(
    ExpectedConditions.presenceOfNestedElementLocatedBy(
        divA, By.xpath(".//div/span")
    )
);
于 2016-07-20T17:25:05.910 回答
1

要查找所有子节点,您可以使用以下代码段

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

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

请注意,这将使所有子节点处于同一级别 - > 如果您有这样的结构:

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

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

希望有帮助!

于 2015-05-14T19:40:16.290 回答
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")
于 2012-05-09T18:17:34.087 回答
-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选择器搜索父元素并使用xpath作为它的子元素,你必须在连接之前检查类型......在这种情况下,Slanec的解决方案(在WebElement上使用findElement)好多了。

于 2013-07-16T13:42:31.590 回答