我正在尝试创建一个Selenium getText()方法,该方法获取节点文本或获取元素的节点+子文本。默认情况下,Selenium行为似乎使用Xpath .// string()方法获取文本并包含直接子项的文本。我想利用XPath的强大功能使我能够以更有针对性的方式获取文本。我的问题是:我是误解了这个还是有更好的方法来实现这个目标?
public String getText(By locationOfText, boolean childText)
{
By locator = null;
if ( childText)
{
locator = ByChained( locationOfText, By.xpath(".//string()"));
} else {
locator = ByChained( locationOfText, By.xpath(".//text()"));
}
JavascriptExecutor jse = (JavascriptExecutor)driver;
String elementText = jse.executeScript("document.evaluate(locator, document.body, null,
XPathResult.STRING_TYPE, null);");
return elementText;
}
以下是HTML代码段:
<h5 class="class-name clearfix">Inner Text
<a class="info-link class-description" href="#">i</a>
</h5>
问题是当我使用Selenium进行这样的文本调用时,我得到 Inner Texti 文本:
driver.findElement(".//h5").getText();
我的期望是检索值内部文字。通过创建上面的方法,我希望这样称呼它:
String text = elementHelper.getText(By.xpath(".//h5"),false);
答案 0 :(得分:3)
string()
是一个XPath 2.0构造,但大多数浏览器(如果不是全部)只支持XPath 1.0。而且,我不喜欢急于使用XPath来查询DOM树。 XPath评估具有显着的性能开销。所以adapting my answer here,我建议:
public String getText(By locationOfText, boolean childText)
{
WebElement el = driver.findElement(locationOfText);
if (childText)
{
return el.getText();
}
JavascriptExecutor jse = (JavascriptExecutor) driver;
return jse.executeScript(
"var parent = arguments[0]; "+
"var child = parent.firstChild; "+
"var ret = ""; "+
"while(child) { "+
" if (child.nodeType === Node.TEXT_NODE) "+
" ret += child.textContent; "+
" child = child.nextSibling; "+
"} "+
"return ret;", el);
}
locationOfText
参数可以是Selenium支持的任何By
方法。
在您的代码中,您使用ByChained
作为location
,这可能是您希望传递给executeScript
,但忘了这么做。即使您将location
添加到executeScript
来电(并修复了抓取arguments[0]
的脚本),我也看不出这是如何工作的。 ByChained
支持将CSS选择器与XPath混合等等。 Selenium 可以通过执行多次搜索来解决组合,但是浏览器的XPath引擎无法接受某些CSS和XPath的组合。