Could not select sibling using CSS Selector in Selenium

Viewed 544

Selenium WebDriver throws InvalidSelectorException when trying to click on next sibling element using CSS Selector.

Consider my DOM looks like this:

<div class="checkbox-group">
   <div>     
       <span class="checkbox">::after</span> <!--click on this span makes the checkbox checked-->
       <span class="checkbox-name">Male</span> <!--click on this span doesn't make the checkbox checked-->
   </div>
   <div>
      <span class="checkbox">::after</span>
      <span class="checkbox-name">Female</span>
   </div>
</div>

And my Java code is:

@FindAll(@FindBy(css=".checkbox-name"))
List<WebElement> checkboxes;

public void selectCheckbox(String value){
    for(WebElement checkbox : checkboxes){
        String text = checkbox.getText();
        if(text.equalsIgnoreCase(value)){
            WebElement control = checkbox.findElement(By.cssSelector("+.checkbox"));//Exception thrown here     
            control.click();
        }
    }
}

Exception thrown as:

org.openqa.selenium.InvalidSelectorException: invalid selector: An invalid or illegal selector was specified. 
** Element info: {Using=css selector, value=+.checkbox} 
2 Answers

Instead of fetching the element by class checkbox-name and checking if it contains the String value, you can directly fetch that element using the text in the xpath.
After finding that element, you can use following-sibling in the xpath to get to the span which is clickable.

You can do all of this in one xpath only, like:

public void selectCheckbox(String value){
    WebElement checkBox = driver.findElement(By.xpath("//div[@class='checkbox-group']//span[text()="+value+"]//following-sibling::span"));
    checkBox.click();
}

Before other people point out that this problem can be easily solved using xpath, let me tell you that I have that solution already. But intent of this question is to find out why selenium doesnt work even when my CSS selector is correct.

Xpath solution:

public void selectCheckbox(String value){
    for(WebElement checkbox : checkboxes){
        String text = checkbox.getText();
        if(text.equalsIgnoreCase(value)){
            WebElement control = checkbox.findElement(By.xpath("./parent::div/span[@class='checkbox']"));
            control.click();
        }
    }
}
Related