user2416212
user2416212

Reputation: 165

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?

Upvotes: 15

Views: 90927

Answers (4)

Mathias M&#252;ller
Mathias M&#252;ller

Reputation: 22647

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"]]

Upvotes: 27

Andersson
Andersson

Reputation: 52685

The link text contains unnecessary spaces from the right side of the main text, so you need the following to get rid of them:

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

Upvotes: 2

NarendraR
NarendraR

Reputation: 7708

Use the following XPath expression:

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

or

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

or

//a[@href='SOME URL']/i

or using cssSelector -

a[href='SOME URL']>i

Upvotes: 0

lordkain
lordkain

Reputation: 3109

With an XPath expression, you can check if the element contains a certain text with the below statement:

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

Upvotes: 2

Related Questions