htmlseleniumselenium-webdriverxpathplatform

Finding XPath expression of a link using link text


In Selenium WebDriver, how can I to use an XPath expression for the below HTML using the link text ("Add New Button")?

<a href="SOME URL">
  <span >
    <i class=""/>
  </span>Add New Button
</a>

I tried to inspect the element as below, but all didn’t work.

  1. //a[text()='Add New Button']
  2. //a[contains(text(),'Add New Button']
  3. //a/span/i[text()='Add New Button']
  4. //a/span/i[contains(text(),'Add New Button']

I know that 3 and 4 won't, but I just tried it.

So for such an HTML DOM, how can I find the link using the link text using XPath?


Solution

  • Some of the answers that were already given work, but others don't. And I think the OP would benefit from more explanations.

    Your original expression:

    //a[text()='Add New Button']
    

    Does not work because the text node that contains "Add New Button" also has a newline character at the end.

    The next one:

    //a[contains(text(),'Add New Button']
    

    Does not work (leaving aside the missing parenthesis), because text() returns a sequence of nodes and a function like contains() will only evaluate the first node in the sequence. In this case, the first text node inside a only contains whitespace and is not the one that contains "Add New Button".

    You can validate this claim with:

    //a[contains(text()[2],'Add New Button')]
    

    which will test whether the second text node of a contains "Add New Button"—and this expression will return the a element. But the best solution in this case is:

    //a[contains(.,'Add New Button')]
    

    . will evaluate to the so-called "string value" of an element, a concatenation of all its text nodes which will include "Add New Button".


    A solution with normalize-space() is also possible, but it has nested predicates:

    //a[text()[normalize-space(.) = "Add New Button"]]