Take the 2-minute tour ×
Stack Overflow is a question and answer site for professional and enthusiast programmers. It's 100% free, no registration required.

I am building a selenium-based test application uses CSS Selectors or XPath strings, and am attempting to test menu items that appear on hover. Using "Inspect Element" in Chrome and in FireFox by right clicking, can verify that the right html is being highlighted, but when I copy the CSS Selector or the XPath, it sometimes selects multiple elements. For instance:

"#myId > li:nth-child(2) > a"

was what Chrome gave me, but it represents 13 elements in the DOM (each in a different sub-menu). The selector I need is the ninth element of the selector's result:

$("#myId > li:nth-child(2) > a")[9]

My main question is whether this can be represented as a CSS selector? I searched for an example but didn't find this particular problem.

$("#myId > li:nth-child(2) > a(9)")

Does not work - returns empty array.

share|improve this question
1  
> a:nth-child(9) –  Blazemonger 2 days ago
2  
This would be a lot easier if you post some html –  Huangism 2 days ago
    
@Huangism - Yes, but the page is an internal one, and the DOM is pretty huge and non-specific. I am not really sure if the id is unique or not to be honest. I believe that BoltClock's answer is what I needed and am checking it now. –  Robb Sadler 2 days ago

1 Answer 1

up vote 4 down vote accepted

CSS does not provide a selector for the nth element matching some complex selector. jQuery makes up for this with the :eq() selector:

$("#myId > li:nth-child(2) > a:eq(8)")

Note that :eq() is 0-indexed, unlike :nth-child() which is 1-indexed, so this will return the ninth element that matches the selector #myId > li:nth-child(2) > a.

The equivalent XPath, should you choose to use that instead, is:

(id('myId')/li[2]/a)[9]

Your situation is unique, however, because if we assume that #myId is unique, as it should be, then you can use the CSS pseudo-class :nth-of-type() to find the ninth a child of the second li child of the element #myId:

$("#myId > li:nth-child(2) > a:nth-of-type(9)")

Note that :nth-of-type() and :eq() are not the same. :nth-of-type() behaves much like :nth-child() in that it considers children of the same parent, except that it looks at the element type, or the tag name. In this case, the element type we're concerned with is a.

The use of > combinators in your existing selector implies a parent-child relationship between your li and a elements, which is compatible with the :nth-of-type() selector. This is why I believe it can be used in your specific situation.

share|improve this answer
    
Wouldn't #myId > li:nth-child(2) > a:nth-child(9) work? Or can you not double up the nth-child? –  Huangism 2 days ago
    
@Huangism: No, that's different - a:nth-child(9) means the ninth child, which means each li must have at least 9 children, and the 9th child is an a. –  BoltClock 2 days ago
    
Oh I see now, I miss read the question and did not realize the :eq applies to the result instead of the anchor alone –  Huangism 2 days ago
    
@Huangism: I just looked at the selector again, and there's also the fact that > combinators are used. Assuming the ID is unique, #myId > li:nth-child(2) > a:nth-child(9) couldn't possibly match up to 13 DOM elements. But I think there's a different way around this that could be possible with CSS. –  BoltClock 2 days ago
    
OP mentions "#myId > li:nth-child(2) > a" matched 13 elements. I don't really know what to think now because I think the questions is not precise enough for me to understand. If we had the html and the OP mentions exactly what's needed, this would be easier –  Huangism 2 days ago

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.