1

I asked this question today, but mistakenly I did not specify the scope of it, which is for use in Selenium Webdriver.

So I have this td:

<td>
<span id="PartComment">
REMAN WATER PUMP
<i>w/2.05" DIAMETER THERMOSTAT OUTLET - SUPPLIED w/PULLEY
</i>
</span>
</td>

And I want an xpath to locate only the text REMAN WATER PUMP to later convert it to a string.

 driver.findElement(By.xpath("//span[@id='lblPartComment']/text()"));

But the problem is that since I'm only locating the text, and not a DOM object, WebDriver won't be able to treat it as such:

Exception in thread "main" org.openqa.selenium.InvalidSelectorException: The given selector //span[@id='lblPartComment']/text() is either invalid or does not result in a WebElement. The following error occurred: InvalidSelectorError: The result of the xpath expression "//span[@id='lblPartComment']/text()" is: [object Text]. It should be an element.

Can you please provide an alternative to that xpath? One that locates the text I mentioned above, and excludes the text inside the i?

Also, related.

Thanks

Community
  • 1
  • 1
zuri
  • 73
  • 1
  • 9
  • I can offer you locator but can you tell me: is the text "REMAN WATER PUMP" changing? I mean, do you want to verify it for different test cases? Because there is an XPath syntax is for locating the span only by this partial text. – Anton Angelov Jul 03 '15 at 19:32
  • I want to locate the span and extract the text inside the span, and exclude any text in the i or any other child nodes that may come up. Yes the reman water pump text may change, but that's irrelevant because I'm locating the span. Additionally, reading around I found that //span[@id='PartComment']/[not(self::i)] could work, but this keeps adding the text in the other child nodes too, so it doesn't work for me. So basically what I need is a way for me to use the not function in xpath to exclude the i node (at least for now) – zuri Jul 03 '15 at 19:40

2 Answers2

1

You can use the following code:

var firstText = this.Driver.FindElement(By.XPath("//span[@id='lblPartComment']")).Text;
var firstChildText = this.Driver.FindElement(By.XPath("//span[@id='lblPartComment']/i")).Text;
firstText = firstText.Replace(firstChildText, string.Empty);

Locate both the parent and the child elements, get their text and replace the child's text with empty string. :)

Anton Angelov
  • 1,705
  • 13
  • 16
  • this is C# but the code for Java should be identical, the idea matters. :) – Anton Angelov Jul 03 '15 at 19:55
  • I am not fluent yet in translating code, could you translate that to java please? @Anton Angelov – zuri Jul 03 '15 at 20:06
  • String firstText = this.Driver.FindElement(By.XPath("//span[@id='lblPartComment']")).Text; String firstChildText = this.Driver.FindElement(By.XPath("//span[@id='lblPartComment']i")).Text; firstText = firstText.replace(firstChildText, ""); – Anton Angelov Jul 03 '15 at 20:08
  • I'm getting that //span[@id='lblPartComment']i is an invalid xpath...are we sure that the 'i' at the end is correct? @Anton Angelov – zuri Jul 03 '15 at 20:41
  • sorry it should be //span[@id='lblPartComment']/i – Anton Angelov Jul 03 '15 at 20:42
  • I don't actually use Java. Can you read the documentation for the replace method. The approach is correct you just need the proper syntax for it. :) – Anton Angelov Jul 03 '15 at 20:50
0

You can do this. referred from this

    JavascriptExecutor js = (JavascriptExecutor) driver;
    String text = (String) js.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;", driver.findElement(By.id("PartComment")));
Community
  • 1
  • 1
Madhan
  • 5,750
  • 4
  • 28
  • 61