PhuLuong
PhuLuong

Reputation: 537

Selenium - get first level child by class name

I use Java Selenium 2.0. This is my HTML element, it contains comments and reply comments:

<div class="comment-list">
    <div class="comment">
       <a class="content">Comment 1</a>
       <div class="reply-comment">
           <div class="comment">
               <a class="content">Comment 1.1</a>
           </div>
           <div class="comment">
               <a class="content">Comment 1.2</a>
           </div>
       </div>
    </div>
    <div class="comment">
        <a class="content">Comment 2</a>
    </div>
</div>

How can I select contents within comments but without reply comments? This is the expected result:

- Comment 1
- Comment 2

Note: I don't want to use absolute css selector such as:

 comment-list > comment > content

Solved! This is my solution:

// Mark reply comments with a class "is-reply-comment"
JavascriptExecutor js = (JavascriptExecutor) driver;
List<WebElement> replyCommentElements = driver.findElements(By.cssSelector(".reply-comment .comment"));
for (WebElement replyCommentElement : replyCommentElements) {
    js.executeScript("arguments[0].className += ' is-reply-comment'", replyCommentElement);
}
// Find comments except comments were marked "is-reply-comment"
List<WebElement> parentCommentElements = driver.findElements(By.cssSelector(".comment:not(.is-reply-comment)")

Upvotes: 3

Views: 5551

Answers (2)

JeffC
JeffC

Reputation: 25542

You can use the XPath

//div[not(@class='reply-comment')]/div/a[@class='content']

but that's really not that much different than the CSS selector

div.comment-list > div.comment > a.content

but the CSS selector is faster, has better browser support, and is more consistently implemented between browsers than XPath.

Upvotes: 1

catch32
catch32

Reputation: 18572

Looks like XPath for such kind of selection will be a little bit long.

However, it is possible to achieve with not() and contains():

//a[@class='content' and not(contains(text(), '.'))]/text()

it selects exactly what you need:

enter image description here

BTW your <a> elements don't have closed tag </a>.

UPDATE:

I saw your comment and at this case I can suggest only following solution:

//div[@class='comment-list']/div/a[@class='content']/text()

Selection is still correct in this case.

Upvotes: 0

Related Questions