Reputation: 3272
I apologize if this question has been answered ad-nauseum. I either haven't understood an answer or haven't found this type of situation directly answered. I need to select a child element using it's sibling as the identifier. Here's a code snippet example
<div class="my-groups-popup">
<div class="listbox-container">
<div class="list-item">
<div class="edit-box">
<div class="body">
<input type="text" value="The First Input">
</div>
</div>
<div class="controls">
<button class="image move-up"></button>
<button class="image move-down"></button>
<button class="image delete"></button>
</div>
</div>
<div class="list-item">
<div class="edit-box">
<div class="body">
<input type="text" value="The Second Input">
</div>
</div>
<div class="controls">
<button class="image move-up"></button>
<button class="image move-down"></button>
<button class="image delete"></button>
</div>
</div>
...
<div class="list-item">
<div class="edit-box">
<div class="body">
<input type="text" value="The nth Input">
</div>
</div>
<div class="controls">
<button class="image move-up"></button>
<button class="image move-down"></button>
<button class="image delete"></button>
</div>
</div>
</div>
</div>
As can be seen, I have a listbox container which has several list-items. Each list-item contains an input box and 3 button controls. But the input, which has the only uniqueness in the group, is a "cousin" to the button control which I need to select.
Normally, I would try something like:
css=.my-groups-popup .list-item:contains("The Second Input") button.move-up
But since the unique value is part of the element, I'm not sure how to form the selector. The button isn't a direct sibling of the input element. But the input's grandparent is the same as the button's grandparent. I was thinking something like:
css=.my-groups-popup .list-item input[value="The Second Input"] ~ .controls button.move-up
But when I tried that, it didn't work. Also, using "~ *" did not return an array of anything. So I suspect I am not getting close to the correct syntax.
Upvotes: 0
Views: 5378
Reputation: 724132
The ~
combinator represents two elements that are siblings only. As you note, the two elements in question are not direct siblings, because each element has its own set of ancestors. They are only related by the .list-item
element, which is much further up the hierarchy.
Since CSS selectors cannot ascend, so to speak, nor is there a selector like :contains()
but for attribute values, you will want to use XPath instead:
xpath=//div[@class='my-groups-popup']/div/div[descendant::input[@value='The Second Input']]//button[1]
Alternatively, if we study your HTML snippet, we can see that .my-groups-popup .listbox-container
only has .list-item
elements as children, and each of these children has exactly one input and one set of button controls. If we can assume that the HTML structure for .my-groups-popup
will always follow this pattern, we can use :nth-child()
on the .list-item
elements to find the button control corresponding to the appropriate input:
css=.my-groups-popup .list-item:nth-child(2) .controls button.move-up
Upvotes: 2