0

I am trying to locate the element div based on its descendant text nodes.

Below is the HTML:

<html><head></head><body>

<div>
<div class="d x">Foo</div>
<span>Mumbai</span>
<h1>DEF</h1>
</div>

</body></html>

Selenium code:

driver.findElement(By.xpath("//div[.='FooMumbaiDEF']"));

As per my understanding and after referring to the stackoverflow posts, Testing text() nodes vs string values in XPath the string-value of an element node is the concatenation of the string-values of all text node descendants of the element node in document order.

But I am getting NoSuchElementException: Unable to locate element: //div[.='FooMumbaiDEF']

Any idea why it is not able to find an element ?

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

4 Answers4

1

Try below xpath because the one you have used is not correct.

driver.findElement(By.xpath("//div[contains(text(),'FooMumbaiDEF')]"));
Ledjon
  • 105
  • 8
0

//div[.='FooMumbaiDEF'] is not valid XPath if you want to deal with web element based on its text then you can use contains() function within Xpath expression which is used to search for the web elements that contain a particular text.

Try below xpath to handle Foo text from your webpage :

driver.findElement(By.xpath("//div[contains(text(),'Foo')]"));
SeleniumUser
  • 4,065
  • 2
  • 7
  • 30
0

As per the HTML:

<html>
    <head>
    </head>
    <body>
        <div>
            <div class="d x">Foo</div>
            <span>Mumbai</span>
            <h1>DEF</h1>
        </div>
    </body>
</html>

there is no descendant text nodes as such. But there are descendant <div>, <span> and <h1> nodes with text.


Solution

To identify the parent <div> element with respect to the text within the descendant <div>, <span> and <h1> nodes you can use either of the following based Locator Strategies:

  • Using the descendant <div>:

    driver.findElement(By.xpath("//div[./div[text()='Foo']]"));
    
  • Using the descendant <div>:

    driver.findElement(By.xpath("//div[./span[text()='Mumbai']]"));
    
  • Using the descendant <div>:

    driver.findElement(By.xpath("//div[./h1[text()='DEF']]"));
    

Ideally, you need to induce WebDriverWait for the visibilityOfElementLocated() and you can use either of the following locator strategies:

  • Using the descendant <div>:

    new WebDriverWait(driver, 20).until(ExpectedConditions.visibilityOfElementLocated(By.xpath("//div[./div[text()='Foo']]")))
    
  • Using the descendant <div>:

    new WebDriverWait(driver, 20).until(ExpectedConditions.visibilityOfElementLocated(By.xpath("//div[./span[text()='Mumbai']]")))
    
  • Using the descendant <div>:

    new WebDriverWait(driver, 20).until(ExpectedConditions.visibilityOfElementLocated(By.xpath("//div[./h1[text()='DEF']]")))
    
undetected Selenium
  • 183,867
  • 41
  • 278
  • 352
  • The `div` element does have descendant text nodes, just ran the `$x("/descendant-or-self::node()/div//text()")`, it returned 7 descendant text nodes... – Sandesh Sawant Aug 24 '20 at 14:58
0

First run the $x("//div/descendant::text()") to check all the descendant text nodes of the div element. It showed seven descendant text nodes. So, it contained four text nodes having data as \n i.e. new-line character along with the above 3 text nodes i.e. Foo, Mumbai and DEF.
So, the Xpath expression to select the above div node should be:

$x("//div[.='\nFoo\nMumbai\nDEF\n']")