在 selenium 中定位 WebElements 的子节点
Posted
技术标签:
【中文标题】在 selenium 中定位 WebElements 的子节点【英文标题】:Locating child nodes of WebElements in selenium 【发布时间】:2012-05-18 05:11:47 【问题描述】:我正在使用 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 中询问“包含 <span>
和文本 'hello world'
的 <div>
”?
【问题讨论】:
【参考方案1】:根据JavaDocs,你可以这样做:
WebElement input = divA.findElement(By.xpath(".//input"));
我如何在 xpath 中询问“包含跨度的 div 标记 文本“你好世界”?
WebElement elem = driver.findElement(By.xpath("//div[span[text()='hello world']]"));
The XPath spec 是一本令人惊讶的好书。
【讨论】:
非常感谢。我还不知道,我可以在 xpaths 内的[]
内使用 xpaths...
最新版本的XPath规范可以在here找到
漂亮!【参考方案2】:
如果您必须等待,有一个方法 presenceOfNestedElementLocatedBy
采用“父”元素和定位器,例如By.xpath
:
WebElement subNode = new WebDriverWait(driver,10).until(
ExpectedConditions.presenceOfNestedElementLocatedBy(
divA, By.xpath(".//div/span")
)
);
【讨论】:
正是我在完全不同的环境中搜索的内容。谢谢。【参考方案3】:要查找所有子节点,您可以使用以下代码段
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(".//*"));
希望有帮助!!
【讨论】:
这确实有效。我不知道为什么有人给它-1。感谢伙伴仍然保留它。 很高兴看到它对某人有用【参考方案4】:几周前我也发现自己处于类似的位置。您还可以通过创建自定义 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")
【讨论】:
【参考方案5】:Selenium 的 By-Class 的 toString() 方法产生类似 "By.xpath: //XpathFoo"
所以你可以从冒号开始取一个子字符串,如下所示:
String selector = divA.toString().substring(s.indexOf(":") + 2);
有了这个,你可以在你的另一个元素中找到你的元素:
WebElement input = driver.findElement( By.xpath( selector + "//input" ) );
优点:您只需在实际 SUT 上搜索一次,因此它可以为您带来性能奖励。
缺点:丑... 在这种情况下,Slanec 的解决方案(在 WebElement 上使用 findElement)要好得多。
【讨论】:
以上是关于在 selenium 中定位 WebElements 的子节点的主要内容,如果未能解决你的问题,请参考以下文章