Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use XPath preceding-sibling correctly

I am writing tests for my site using Selenium IDE and I am having trouble with having selenium click on a button using preceding-sibling

<td> <div class="btn-group"> <button class="btn btn btn-danger block" title="Warning, Delete" name="delete" type="button"> <button class="btn btn btn-default block" title="View History" name="history" type="button"> <button class="btn btn btn-default block" title="View Settings" name="settings" type="button"> <button class="btn btn btn-default block" name="device" type="button"> <span class="glyphicon glyphicon-pencil"/>  Arcade Reader </button> </div> </td> 

My path

xpath=//button[contains(.,'Arcade Reader')]/../preceding-sibling::button[@name='settings'] 
like image 730
jquerynoob Avatar asked May 08 '14 13:05

jquerynoob


People also ask

Do we have preceding-sibling in XPath?

Following and preceding siblings are just a few of the Axis that can be used in Selenium to discover elements on a web page using XPath. All siblings are referred to be the parent node's children.

What is preceding-sibling XPath?

The preceding-sibling axis indicates all the nodes that have the same parent as the context node and appear before the context node in the source document.

What is preceding and following in XPath?

This is a concept very similar to Following-Siblings. The only difference in functionality is that of preceding. So, here, in contrast to Following-Sibling, you get all the nodes that are siblings or at the same level but are before your current node.

What is the difference between preceding and preceding-sibling?

In this diagram, the preceding:: nodes are circled, and the more specific preceding-sibling:: nodes are given a red border. The preceding-siblings are nodes that share the same parent node, and come before the current node in the document. The preceding:: node is any node that comes before the element in the document.


2 Answers

You don't need to go level up and use .. since all buttons are on the same level:

//button[contains(.,'Arcade Reader')]/preceding-sibling::button[@name='settings'] 
like image 104
alecxe Avatar answered Sep 28 '22 09:09

alecxe


I also like to build locators from up to bottom like:

//div[contains(@class,'btn-group')][./button[contains(.,'Arcade Reader')]]/button[@name='settings'] 

It's pretty simple, as we just search btn-group with button[contains(.,'Arcade Reader')] and get it's button[@name='settings']

That's just another option to build xPath locators

What is the profit of searching wrapper element: you can return it by method (example in java) and just build selenium constructions like:

getGroupByName("Arcade Reader").find("button[name='settings']"); getGroupByName("Arcade Reader").find("button[name='delete']"); 

or even simplify more

getGroupButton("Arcade Reader", "delete").click(); 
like image 41
Vitaliy Moskalyuk Avatar answered Sep 28 '22 08:09

Vitaliy Moskalyuk