Creating selenium getText () method for element?

I am trying to create a Selenium getText () method that either gets the text node or gets the child text of the node + element. By default, the Selenium behavior seems to use the Xpath. // string () method to get the text and including the text of the immediate children. I want to take advantage of XPaths to allow me to get text in a more targeted manner. My question is: I don't understand this or is there a better way to achieve this?

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;
} 

      

Here's a snippet of HTML:

<h5 class="class-name clearfix">Inner Text
   <a class="info-link class-description" href="#">i</a>
</h5>

      

The problem is that I get Inner Texti text when I use Selenium to make a text call like this:

driver.findElement(".//h5").getText();

      

My expectation was to get the Inner Text value . Having created the method above, I hope to call it like this:

String text = elementHelper.getText(By.xpath(".//h5"),false);

      

+3


source to share


1 answer


string()

is an XPath 2.0 construct, but most (if not all) browsers only support XPath 1.0. Moreover, I don't really like rushing with XPath to query the DOM tree. XPath estimation has significant overhead. So adapting my answer here , I would suggest:

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);
}

      



The parameter locationOfText

can be any method By

that Selenium supports.

In your code, you are using ByChained

for location

which you presumably want to switch to executeScript

, but forgot to do. I can't see how this would work, even if you added location

to your call executeScript

(and corrected the script to capture arguments[0]

). ByChained

will support things like mixing CSS selector with XPath, etc. Selenium can apparently resolve the combination by doing multiple queries, but the browser's XPath engine will not accept any combination of CSS and XPath.

+3


source







All Articles