XPath expression for element based on containing text - xpath

I'm running out of ideas. I have identified for my Selenium test an div based on its text ("security administrator ") contained. Unfortunately, the div contains two other divs. See the example.
<div class="rich-stglpanel-marker">
<div class="rich-stglpnl-marker" id="j_id194:j_id198:2:j_id199_switch_on" style="display: none"></div>
<div class="rich-stglpnl-marker" id="j_id194:j_id198:2:j_id199_switch_off"></div>
security administrator
</div>
<div class="rich-stglpanel-marker">
<div class="rich-stglpnl-marker" id="j_id194:j_id198:2:j_id199_switch_on" style="display: none"></div>
<div class="rich-stglpnl-marker" id="j_id194:j_id198:2:j_id199_switch_off"></div>
technical administrator
</div>
... and so on
I tried that expressions:
//div[text()='security administrator']
//div[text()='security administrator ']
//div[text()='security administrator ']
//div[text()='security administrator${nbsp}'] (this is a special hack from selenium)
Nothing works. Any ideas?
Thanks in advance.

Can you try with this :
//div[contains(.,'security administrator')]
System.out.println(driver.findElementByXPath("//div[contains(.,'security adm')]").getText())
gave me security administrator

try this
//div[#class='rich-stglpanel-marker']

Try this: //div[#class='rich-stglpanel-marker' and text()!='']
EDIT
Finally got it!
Use this: //div[#class='rich-stglpanel-marker' and normalize-space(div[last()]/following-sibling::text())='security administrator']
I believe that in this situation, the text "security administrator" is counted as a node, and not as the sole text value of the first div node, which is why //div/text() will give you multiple return lines followed by the text you're searching for, and also why you cannot apply something like normalize-space(),translate(), or even contains() to div/text() and receive results. But, since the text node doesn't have a name, that makes it a funky XPath to figure out, so navigating to the closest possible sibling node was the only option I could think of.

Related

protractor using xpath //*[contains('text')] error element not visible

Hi I have this element from a dropdown menu I try to select:
<div class="tt-suggestion tt-selectable">
<strong class="tt-highlight">Auto Customer</strong>
</div>
If I use element(by.xpath("//strong[contains(text(),'Auto Customer')]")).click(); I can select it no problem. But if I use element(by.xpath("//*[contains(text(),'Auto Customer')]")).click(); I get "Failed: element not visible"
Can someone explain this to me please?
Thank you
Because the * in //*[contains(text(),'Auto Customer')] means any tag, not only the strong Tag. But //strong[contains(text(),'Auto Customer')] must be strong Tag.
//*[contains(text(),'Auto Customer')] should find more then one elements on page, and the first one is not visible. You can try this xpath in Chrome DevTool's Element Tab to see how many elements it can find and the first one is visible or not.

Xpath Index wont work

I need the third image with that class and parent. None of these xpaths seem to be valid.
xpath=(//div[#class='itemTileV5'])//img[#class='dealItem']/#src[3]
xpath=(//div[#class='itemTileV5']//img[#class='dealItem'])/#src[3]
xpath=(//div[#class='itemTileV5']//img[#class='dealItem']/#src)[3]
Notice I move the parentheses around and it's always an invalid path. Without parentheses it won't work either.
Please help.
<div class="itemTileV5">
<div class="top">
<a href="/Grocery_deals/p_pepperidge-farm-goldfish-variety-pack-bold-mix-29-4-ounce">
<img class="Item" src="https://img.google.com/ai/184x184/dealimage/1493649114.jpg" alt="Pepperidge Farm">
</a>
</div>
</div>
All three of your expressions are valid in all versions of XPath. If you're getting an error, please tell us what it is, and what XPath processor generated it.
The first two expressions aren't useful, because #src[3] selects the third attribute called "src" and there can only be one attribute with a given name.
Your informal requirement "the third image with that class and parent" seems to translate to (//div[#class='itemTileV5']/img[#class='dealItem'])[3]/#src

Select preceding-sibilings of element that contains child in xpath

I have code that looks like this
<div id="content">
<p>text</p>
<p>text1</p>
<p>text3</p>
<p><iframe></iframe></p>
<p>text4</p>
<p>text5</p>
</div>
I need to select all "p" elements before "p" that contains child "iframe", I tried something like this
//div[#id='content']//p[iframe]/preceding-sibiling::p
but with no luck.
I am stuck here for a few days so any help would be great.
Your XPath logic was actually fine! You just have a few typos it appears.
//div[#id='content']/p[iframe]/preceding-sibiling::p
You also don't need the extra / after the div block. Here's the full working xpath:
//div[#id='content']/p[iframe]/preceding-sibling::p

discover a certain part of a page with selenium

I have a webpage looks something like this:
<html>
...
<div id="menu">
...
<ul id="listOfItems">
<!--- repeated block start -->
<li id="item" class="itemClass">
...
<span class="spanClass"><span class="title">title</span></span>
...
</li>
<!-- repeated block end-->
<li id="item" class="itemClass">
...
<span class="spanClass"><span class="title">title something</span></span>
...
</li>
<li id="item" class="itemClass">
...
<span class="spanClass"><span class="title">title other thing</span></span>
...
</li>
</ul>
...
</div>
...
</html>
I would like to know what is the xpath of the titles ("title", "title something", "title other thing"). The point is that the order of the <li> elements are not specified. It could be different after every page loading. Is there any method how to discover a certain structure of the page with xpath? I have an notion about how to solve this issue, but before I'm going to write iterations with C# to discover the page I ask you.
Thanks in advance!
First of all, id's should be unique, so your portrayed webpage would not work well when it comes to testing.
I did however test, and got some XPath locators to work for selecting specific titles (although I recommend you fix your webpage instead of actually using this):
//li[#id='item']/span/span
//li[#id='item'][1]/span/span
//li[#id='item'][3]/span/span
If you're after all three titles, you could try Dimitre Novatchev's suggestion:
//span[#class='title']
This should get all titles on the page.
I would like to say one thing however, if you're getting into Selenium, I recommend you download the Selenium IDE extension for Firefox. It's a great tool for beginners. It helps you both to make your Selenium tests by recording your clicks on a website, and it also helps you auto-generate and test your XPath locators and other locators.
And again: I urge you to not make a website with duplicate id elements :-)
Does Selenium support XPath expressions like:
//span[#class='title']
If yes, than use the above XPath expression. It selects every span element in the XML document, whose class attribute has string value of "title".
I recommend to use a tool like the XPath Visualizer to play with different XPath expressions and see the selected nodes highlighted in the source XML document.

xpath locator works in FF3, but won't work in IE7

After switching from firefox testing to internet explorer testing, some elements couldn't be found by selenium anymore.
i tracked down one locator:
xpath=(//a[#class='someclass'])[2]
While it works as it should under firefox, it could not find this element in ie.
What alternatives do i have now? JS DOM? CSS Selector? How would this locator look like?
Update:
I will provide an example to make my point:
<ul>
<li>
<a class='someClass' href="http://www.google.com">BARF</a>
</li>
<li>
<a class='someClass' href="http://www.google.de">BARF2</a>
</li>
</ul>
<div>
<a class='someClass' href="http://www.google.ch">BARF3</a>
</div>
The following xpath won't work:
//a[#class='someclass'][2]
In my understanding this should be the same as:
//a[#class='someclass' and position()=2]
and i don't have any links that are the second child of any node. All i want is, to address one link from the set of links of class 'someClass'.
Without knowing the rest of your HTML source it's difficult to give you alternatives that are guaranteed to work. Hopefully the following suggestions will help point you in the right direction:
//a[#class='someClass'][2]This is like your example, but the parantheses are not needed.
//a[contains(#class, 'someClass')][2] This will work even if the link has other classes.
css=a.someClass:nth-child(2) This will only work if the link is the 2nd child element of it's parent.
Update
Based on your update, try the following: //body/descendant::a[#class='someClass'][2]

Resources