为元素创建 Selenium getText() 方法?
Creating a Selenium getText() method for an element?
我正在尝试创建一个 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();
我的期望是检索值 Inner Text 。通过创建上面的方法,我希望这样调用它:
String text = elementHelper.getText(By.xpath(".//h5"),false);
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 的某种组合。
我正在尝试创建一个 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();
我的期望是检索值 Inner Text 。通过创建上面的方法,我希望这样调用它:
String text = elementHelper.getText(By.xpath(".//h5"),false);
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 的某种组合。