Get the value of a particular css element id from

2019-07-16 00:20发布

问题:

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

回答1:

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 NoSuchElementExceptions).

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 +



回答2:

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

Fiddle



回答3:

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