Selecting an element with xpath and Selenium
Asked Answered
T

4

15

I have HTML which looks basically like the following:

...    
  <a class="btnX btnSelectedBG" href="#"><span>Sign in</span></a>
...

The following xpath in Selenium fails to find an element:

//a[contains(text(), 'Sign in') and contains(@class,'btnX')]

The following xpaths in Selenium succeed, but are not specific enough for me.

//a[contains(text(), 'Sign in')]
//a[contains(@class, 'btnX')]

Why is the xpath failing to find an element, and what can I do to get it to work?

Tryck answered 27/4, 2011 at 18:41 Comment(3)
//a[contains(text(), 'Sign in')] shouldn't select that elementIllustrative
Yeah, of the two options that work I would agree that the first should not work -- unless it is fetching the text() of the subelements and joining them, as JavaScript does. However, I was having trouble reconciling that with the fact that it didn't work in conjunction with the other test except when I made up some sort of fuzzy logic that once I used a particular "context" element for the expression, it was unable to evaluate the rest of the expression outside of that context.Tryck
It will work because it is collecting the text of sub-elements as well. This can be a pain and a boon :)Faircloth
S
27

Match cases where Sign in is directly child of a or child of another element:

//a[contains(@class,'btnX') and .//text()='Sign in']

I mean

<a class="btnX btnSelectedBG" href="#">Sign in</a>

and

<a class="btnX btnSelectedBG" href="#"><b>Sign in</b></a>

Swarm answered 27/4, 2011 at 20:19 Comment(0)
F
7

//a[contains(@class,'btnX') and span[text()='Sign in']] is not a good idea because you are going to search through the DOM for every anchor and then try and compary it to your search criteria.

You ideally want to key your XPath to the first ascendant element that has an ID and then work your way down the tree.

e.g. if your html is

<div id="foo">   
  <a class="btnX btnSelectedBG" href="#"><span>Sign in</span></a>
</div>

You could use:

//div[@id='foo']/a[contains(@class, 'btnX')][span[.='Sign in']]

Unfortunatly I don't know the rest of the structure of the page so I can't give you anything more concrete than:

//a[contains(@class, 'btnX')][span[.='Sign in']]

but it is really not a very nice xpath.

(My XPath's look slightly different to you because I have used . as a shortcut for text() and a second set of [] as a shortcut for and)

Faircloth answered 28/4, 2011 at 13:51 Comment(1)
I was curious about the . notation and when it could be used. Thanks for the example.Tryck
T
0

Yaaa for me. I think this is the best answer, but open to other solutions!

//a[contains(@class,'btnX') and span[text()='Sign in']]
Tryck answered 27/4, 2011 at 19:13 Comment(2)
Of course: //a[contains(@class,'btnX') and contains(.,'Sign in')]. Do not address text nodes in mixed content schemas like XHTML.Illustrative
You do realise that that is functionally identical to //a[contains(@class, 'btnX')][span[.='Sign in']] Instead of using an and I have just broken them into two conditions :)Faircloth
S
0

For and operation the below point is important.

“and” is case-sensitive, you should not use the capital “AND”.

Syntax: //tag[XPath Statement-1 and XPath Statement-2]

Here you can also find many other ways to find Xpath in Selenium: https://www.swtestacademy.com/xpath-selenium/

Sherysherye answered 25/10, 2021 at 9:13 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.