I am using Selenium WebDriver wrapped in PHPUnit and Sausage to test clicking a button in a specific row in a table that's laid out similar to:
<tr id="dynamically generated 1">
<td class="foo">
<div class="bar"></div>
</td>
<td class = "mybutton">
<span class = "icon clickable"></span>
</td>
</tr>
<tr id="dynamically generated 2">
<td class="foo">
<div class="baz"></div>
</td>
<td class = "mybutton">
<span class = "icon clickable"></span>
</td>
</tr>
In particular, I want to click a specific element #mybutton > span.icon.clickable
whose sibling is .foo
with child .baz
. The " whose sibling is .foo
with child .baz
" requirement is the only way I can currently identify the correct element, as other rows in the same table have element #mybutton > span.icon.clickable
, and the ids for those rows are dynamically generated.
At the moment I am using XPath, but as you might expect, performance on FF
and IE
is horrendous. Is there a method for retrieving the value of tr#id
from the element tr#id div.bar
? If I can get this, I can use the id to use CSS to find the element I am looking for. I am using PHP, but a solution in any language would be useful.
Alternatively, a more straightforward CSS3 solution would work, but after quite a bit of reading, I've all but concluded that using a standard CSS3 selector is not an option for this case. Just in case there is something I'm missing, is there a CSS3 solution for this? I know there is a CSS4 solution, but I need full browser support, so until all the browsers I am testing support CSS4, I'll have to rely on CSS3.
Thanks in advance.
EDIT: Until there is better cross-browser support for CSS4, I need to use CSS3
The only way I can think to do this is to find a List<WebElement>
generated by By.cssSelector(".foo~span.icon.clickable")
and on each element do a findElement(By.cssSelector(".baz"))
surrounded by try/catch (catching NoSuchElementException
s).
When there isn't an error thrown, then you know that you have found your element.
Note: The ~
selects it if it has ANY proceeding .foo
siblings. If you want it to be the immediately previous sibling, use +
There is no CSS way to select this, because it would require a selector that looks at previous elements, which is not available in CSS3.
However, this would be quite simple in jQuery. I made a selector for your situation
$(".foo").has(".baz").siblings(".mybutton").find("span.icon.clickable").addClass('red');
$(".foo")
- selects elements with a class of foo
.has(".baz")
- only returns elements that has a sibling with a class of baz
. In this case, .foo
with a .baz
element .siblings(".mybutton")
- looks for an element with the class of mybutton
on the same level as the previous element. Since we used has()
instead of .foo .baz
, this will still target the .foo
element .find("span.icon.clickable")
- looks for a descending span from the previous element with classes of icon
and clickable
.addClass('red');
- just a function to finish the example There is a sibling selector in css called ~
and there are some css4
selectors which might help.
Perhaps this would work, if I understood the requirement correctly:
#mybutton > .foo ~ span.icon.clickable! > .baz
This should work in chrome, but its css4 so, it probably wont work in a lot of browsers.
Hint : It selects the span.icon.clickable
which has a child .baz
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.