为元素创建Selenium getText()方法?

时间:2015-06-04 23:38:15

标签: javascript selenium selenium-webdriver webdriver

我正在尝试创建一个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);

1 个答案:

答案 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的组合。