0

I'm facing a problem, where I'm unable to get the text of a span tag that has another span tag as a child:

<span class="abc">
        <span class="def">Inner Span</span> 
        Outer Span
</span>

When I'm using

driver.findElement(By.cssSelector(".abc")).getText()

Selenium returns "Inner Span" as well as "Outer Span". I guess innerText is used here. But I only need the text "Outer Span" of the outer span with the class "abc".

undetected Selenium
  • 183,867
  • 41
  • 278
  • 352

2 Answers2

1

The text Outer Span is a Text Node and is the lastChild of the parent <span> node. So extract the text you need to induce WebDriverWait for the visibilityOfElementLocated() and you can use either of the following Locator Strategies:

  • Using cssSelector:

    System.out.println(((JavaScriptExecutor)driver).executeScript("return arguments[0].lastChild.textContent;", new WebDriverWait(driver, 10).until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector("span.abc")))).toString());
    
  • Using xpath:

    System.out.println(((JavaScriptExecutor)driver).executeScript("return arguments[0].lastChild.textContent;", new WebDriverWait(driver, 10).until(ExpectedConditions.visibilityOfElementLocated(By.xpath("//span[@class='abc']")))).toString());
    
undetected Selenium
  • 183,867
  • 41
  • 278
  • 352
  • Great solution for non-straightforward issue. And awesome example of leveraging javascript and java in tangent. – Jortega Dec 21 '19 at 14:43
  • You have posted the same answer as mine. – KunduK Dec 21 '19 at 20:53
  • @KunduK Not sure why you felt _...posted the same answer as mine..._. However, here are the differences: 1) Your answer doesn't contains anything related to [**cssSelector**](https://stackoverflow.com/questions/16788310/what-is-the-difference-between-cssselector-xpath-and-which-is-better-with-resp/54606452#54606452). 2) Your answer speaks about `getAttribute()` and `split()` which have no place within my answer. 3) You are **forcefully** **`typecasting`** through `(String)` where as I have used the much **proven** and **efficient** `toString()`. Let me know if you have any questions/doubts. – undetected Selenium Dec 22 '19 at 12:40
0

Try JavascriptExecutor and get the textContent of lastChild

Induce WebDriverWait() and wait for visibilityOfElementLocated()

WebElement element = new WebDriverWait(driver, 20).until(ExpectedConditions.visibilityOfElementLocated(By.xpath("//span[@class='abc']")));
JavascriptExecutor js= (JavascriptExecutor) driver; 
String strtext=(String) js.executeScript("return arguments[0].lastChild.textContent;", element);
System.out.println(strtext.trim());

Or you can split lines and get the desire value using Index.

WebElement element = new WebDriverWait(driver, 20).until(ExpectedConditions.visibilityOfElementLocated(By.xpath("//span[@class='abc']")));
String text=element.getAttribute("textContent");
String[] lines = text.split("\\r?\\n");
System.out.println(lines[2].trim());
KunduK
  • 32,888
  • 5
  • 17
  • 41