5
<a href="javascript:void(0)" title="home">
    <span class="menu_icon">Maybe more text here</span>
    Home
</a>

So for above code when I write //a as XPath, it gets highlighted, but when I write //a[contains(text(), 'Home')], it is not getting highlighted. I think this is simple and should have worked.

Where's my mistake?

kjhughes
  • 106,133
  • 27
  • 181
  • 240
Shoaib Akhtar
  • 1,393
  • 5
  • 17
  • 46
  • Is it's text the **only** thing you can match on? It will be pretty unstable. – Arran Sep 29 '17 at 10:12
  • Above xpath was working well earlier, I don't know why it is not working now. Though developer mentioned there is some changes done in html at parent label but this part of code seems to be same, so I think the code could have worked. Since similar code is written at other place I wanted to avoid changing xpath again for similar elements – Shoaib Akhtar Sep 29 '17 at 10:23

3 Answers3

6

Other answers have missed the actual problem here:

  1. Yes, you could match on @title instead, but that's not why OP's XPath is failing where it may have worked previously.
  2. Yes, XML and XPath are case sensitive, so Home is not the same as home, but there is a Home text node as a child of a, so OP is right to use Home if he doesn't trust @title to be present.

Real Problem

OP's XPath,

//a[contains(text(), 'Home')]

says to select all a elements whose first text node contains the substring Home. Yet, the first text node contains nothing but whitespace.

Explanation: text() selects all child text nodes of the context node, a. When contains() is given multiple nodes as its first argument, it takes the string value of the first node, but Home appears in the second text node, not the first.

Instead, OP should use this XPath,

//a[text()[contains(., 'Home')]]

which says to select all a elements with any text child whose string value contains the substring Home.

If there weren't surrounding whitespace, this XPath could be used to test for equality rather than substring containment:

//a[text()[.='Home']]

Or, with surrounding whitespace, this XPath could be used to trim it away:

//a[text()[normalize-space()= 'Home']]

See also:

kjhughes
  • 106,133
  • 27
  • 181
  • 240
1

You can try this XPath..Its just select element by attribute

 //a[@title,'home']
Zakaria Shahed
  • 2,589
  • 6
  • 23
  • 52
  • I know it will work in this case, but earlier I had written the xpath which I mentioned above which worked well, I don't know why it is not working now. Though developer mentioned there is some changes done in html at parent label but still I think the code could have worked – Shoaib Akhtar Sep 29 '17 at 10:21
  • I am not sure but your text home inside invited commas "Home" It can be a reason. – Zakaria Shahed Sep 29 '17 at 10:27
  • Tried giving with double quotes but didn't worked //a[contains(text(),'"Home"')] or //a[contains(text(),""Home"")] or //a[contains(text(),"""Home""")] not working – Shoaib Akhtar Sep 29 '17 at 10:35
  • Suppose I have text like "WE'd like to hear from you" Then Xpath will be something like //input[contains(@text,\"WE'd\"] Hope in this way you can solve your problem – Zakaria Shahed Sep 29 '17 at 10:42
  • Helpful (+1) but [***something more subtle is causing OP's problem***](https://stackoverflow.com/a/46488908/290085). – kjhughes Sep 29 '17 at 12:38
1

yes you are doing 2 mistakes, you're writing Home with an uppercase H when you want to match home with a lowercase h. also you're trying to check the text content, when you want to check check the "title" attribute. correct those 2, and you get:

//a[contains(@title, 'home')]

however, if you want to match the exact string home, instead of any a that has home anywhere in the title attribute, use @zsbappa's code.

hanshenrik
  • 19,904
  • 4
  • 43
  • 89
  • Helpful (+1) but [***something more subtle is causing OP's problem***](https://stackoverflow.com/a/46488908/290085). – kjhughes Sep 29 '17 at 12:38