1

I am trying to select an element based on the text. The problem I'm having is the element text exists multiple times in the source code. I was using xpath to find it (even though I try to avoid xpath), but that's all that I could get working.

Here is the html I'm working against:

<ul id="Dialogs_Dialogs_ctlAcknowledgeMessage_ConditionalDecline_cblMessage" class="cbl centered d2" style="width:511px;">
    <li>
        <input id="Dialogs_Dialogs_ctlAcknowledgeMessage_ConditionalDecline_cblMessage_0" name="ctl00$ctl00$Dialogs$Dialogs$ctlAcknowledgeMessage_ConditionalDecline$cblMessage$0" onclick="CannedCommentSelected(this);" value="Complexity of job requires extra charge" type="checkbox">
        <label for="Dialogs_Dialogs_ctlAcknowledgeMessage_ConditionalDecline_cblMessage_0">Complexity of job requires extra charge</label>
    </li>
    <li>
        <input id="Dialogs_Dialogs_ctlAcknowledgeMessage_ConditionalDecline_cblMessage_1" name="ctl00$ctl00$Dialogs$Dialogs$ctlAcknowledgeMessage_ConditionalDecline$cblMessage$1" onclick="CannedCommentSelected(this);" value="Complexity of job requires extra time" type="checkbox">
        <label for="Dialogs_Dialogs_ctlAcknowledgeMessage_ConditionalDecline_cblMessage_1">Complexity of job requires extra time</label>
    </li>
    <li>
        <input id="Dialogs_Dialogs_ctlAcknowledgeMessage_ConditionalDecline_cblMessage_2" name="ctl00$ctl00$Dialogs$Dialogs$ctlAcknowledgeMessage_ConditionalDecline$cblMessage$2" onclick="CannedCommentSelected(this);" value="Current workload requires extra time" type="checkbox">
        <label for="Dialogs_Dialogs_ctlAcknowledgeMessage_ConditionalDecline_cblMessage_2">Current workload requires extra time</label>
    </li>
    <li>
        <input id="Dialogs_Dialogs_ctlAcknowledgeMessage_ConditionalDecline_cblMessage_3" name="ctl00$ctl00$Dialogs$Dialogs$ctlAcknowledgeMessage_ConditionalDecline$cblMessage$3" onclick="CannedCommentSelected(this);" value="Distance to property requires extra charge" type="checkbox">
        <label for="Dialogs_Dialogs_ctlAcknowledgeMessage_ConditionalDecline_cblMessage_3">Distance to property requires extra charge</label>
    </li>
</ul>

I was using driver.findElement(By.xpath("//label[contains(text(), 'Complexity of job requires extra charge')]")); but I started getting the "Element is not currently visible and so may not be interacted with" error which led me to discover there are multiple labels with the "Complexity of job requires extra charge" text.

I tried driver.findElement(By.cssSelector("#Dialogs_Dialogs_ctlAcknowledgeMessage_ConditionalDecline_cblMessage > #Dialogs_Dialogs_ctlAcknowledgeMessage_ConditionalDecline_cblMessage_0 > label[text='Complexity of job requires extra charge']")); but it timed out trying to find the element.

What am I doing wrong?

I even tried driver.findElement(By.cssSelector("#Dialogs_Dialogs_ctlAcknowledgeMessage_ConditionalDecline_cblMessage > input[value='Complexity of job requires extra charge']")); which I was sure would work, but it times out looking for that also.

5
  • 1
    Use Css selector input[value='Complexity of job requires extra charge'] Commented Jul 15, 2016 at 15:42
  • When I do that, I get the "Element is not currently visible and so may not be interacted with" because there are multiple elements with that value. That's why I was trying to be more specific by starting with the ul id, I just can't seem to step the cssSelector down to that value text properly Commented Jul 15, 2016 at 15:46
  • When you used By.xpath why did you not use the for attribute for locating? It is unique in your example HTML. Commented Jul 15, 2016 at 16:26
  • One reason is if I can get the text option working, the code would be more readable. Another reason, is to be more adaptable and precise when coding instead of having to look at the source code of that particular page. I would love to be able to avoid xpath altogether if possible, but you are correct. It may work in this case if I can't get anything else working. Commented Jul 15, 2016 at 16:32
  • use driver.findElements(); store it in a list. iterate and check for element.isDisplayed and click the one that is displayed Commented Jul 15, 2016 at 16:40

3 Answers 3

1

In this case you should try using JavascriptExecutor to interact with this as below :-

WebElement el = driver.findElement(By.cssSelector("input[value='Complexity of job requires extra charge']"));

((JavascriptExecutor) driver).executeScript("arguments[0].click();",el);

Edited :-

List<WebElement> els = driver.findElements(By.cssSelector("input[value='Complexity of job requires extra charge']"));
for(WebElement el : els) 
{
  if(el.isDisplayed() && el.isEnabled())
  {
   el.click();
  }
}

Hope it helps...:)

Sign up to request clarification or add additional context in comments.

9 Comments

This goes past the code just fine, but it doesn't actually click on the element. My guess would be that it is finding on of the non-visible elements that exists in the source code which is breaking my initial xpath statement.
@DustinN You mean there are more invisible element with the same xPath???
Unfortunately, I cannot share the url. Yes, there are multiple hidden elements with the same input value. That's why I am trying to attach it to the ul id and drill down to the value
@DustinN Once execute driver.findElements(By.cssSelector("input[value='Complexity of job requires extra charge']")).size(); and let me know the result...
@DustinN Ok then in the loop replace el.click() to ((JavascriptExecutor) driver).executeScript("arguments[0].click();",el);..it should work
|
1

You have two problems with the cssSelector:

> is used for direct child, but the elements with id that ends with cblMessage and cblMessage_0 have another element between them, and the element with id that ends with cblMessage_0 and the element you are looking for are siblings.

You can use this cssSelector to locate the element with the text

driver.findElement(By.cssSelector("#Dialogs_Dialogs_ctlAcknowledgeMessage_ConditionalDecline_cblMessage_0 ~ label"));

~ represents sibling.

1 Comment

Thanks for pointing out the "sibling" piece. I was unaware of how to select siblings until now. This does work and I will use this for situations with better descriptive class names or id's.
0

Your CSS didn't work because it's trying to find the label as a child of the input, which is really a sibling. You can tell xpath to find that parent ul by ID too. The following XPath should work:

//ul[@id="Dialogs_Dialogs_ctlAcknowledgeMessage_ConditionalDecline_cblMessage"]/li/label[contains(text(), 'Complexity of job requires extra charge')]

and if you're actually interested in selecting the input so that you can check that box, try this:

//ul[@id="Dialogs_Dialogs_ctlAcknowledgeMessage_ConditionalDecline_cblMessage"]/li/label[contains(text(), 'Complexity of job requires extra charge')]/preceding-sibling::input

2 Comments

I keep getting the following error when using this: The given selector //ul[@id="Dialogs_Dialogs_ctlAcknowledgeMessage_ConditionalDecline_cblMessage"]/li/label[contains(text(), 'Complexity of job requires extra charge')] is either invalid or does not result in a WebElement
hmmm...that path works fine with FirePath in FireBug with a copy of the html from above. is the element occasionally hidden? Buried in an iframe? do you need to wait for the element to appear?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.