Issue selecting Radio button in Selenium Webdriver - selenium

<table id="Content_Content_Content_ctlCaseInfo_rdochldplcm" class="fltLeft">
<tr>
<td><input type="radio" id="Content_Content_Content_ctlCaseInfo_rdochldplcm_0" name="ctl00$ctl00$ctl00$Content$Content$Content$ctlCaseInfo$rdochldplcm" value="0" /><label for="Content_Content_Content_ctlCaseInfo_rdochldplcm_0">No</label></td><td><input type="radio" id="Content_Content_Content_ctlCaseInfo_rdochldplcm_1" name="ctl00$ctl00$ctl00$Content$Content$Content$ctlCaseInfo$rdochldplcm" value="1" /><label for="Content_Content_Content_ctlCaseInfo_rdochldplcm_1">Yes</label></td>
</tr>
</table>
When I try
driver.FindElement(By.Id("Content_Content_Content_ctlCaseInfo_rdochldplcm")).Click();
it clicks to "Yes"
When I try driver.FindElement(By.Id("Content_Content_Content_ctlCaseInfo_rdochldplcm_0")).Click();
OR
driver.FindElement(By.Id("Content_Content_Content_ctlCaseInfo_rdochldplcm_1")).Click();
Nothing happens and no radio button gets selected.
Please suggest ways to handle this situation ..thanks a lot!!

It would probably be better to click the Radio buttons through XPath.
In your specific case, the XPath for:
Yes - Radio Button:
"//input[contains(#id, 'rdochldplcm') and contains(#value, 1)]"
No - Radio Button:
"//input[contains(#id, 'rdochldplcm') and contains(#value, 0)]"
In this instance, if you wanted to click the 'Yes' Radio button, you can do this:
string yesRadioButtonXPath = "//input[contains(#id, 'rdochldplcm') and contains(#value, 1)]"
IWebElement yesRadioButton = driver.FindElement(By.XPath(yesRadioButtonXPath));
yesRadioButton.Click();
For the 'No' Radio button, you would use this:
string noRadioButtonXPath = "//input[contains(#id, 'rdochldplcm') and contains(#value, 0)]"
IWebElement noRadioButton = driver.FindElement(By.XPath(noRadioButtonXPath));
yesRadioButton.Click();
Since you're using a table, there may be a chance that the XPath may return more than one element. You'd need to use a different method to sort out the elements in that case, but for what you're looking for, this method should work.

this solved my problem perfeclty
I have a page with 18 radio buttons in 6 groups which represented "Yes" "No" and "No Answer"
I was trying to get them by ID but it was randomized by the app
But using a name and value tags made it work.
radios were defined basically like this:
input value="2" class=" x-form-radio x-form-field" autocomplete="off" id="randID_13578" name="emailNotifiyOptionAllow" type="radio">
and every time i opened this page id was different so using
"//input[contains(#name, 'emailNotifyOptionAllow') and contains(#value, 1)]"
solved it.
Thanx

Use this :
//First get the list of values from the radio button
List < WebElement > elements = driver.findElements(By.cssSelector("table[id='Content_Content_Content_ctlCaseInfo_rdochldplcm'] > td"));
WebElement value;
//use loop for searching the particular element
for(WebElement element : elements){
//Getting the value of the element
value = element.findElement(By.cssSelector("label")).getText();
//condition to click on the element
if(value.trim().equals("No")){ //Here value is hard coded. You can take from excel sheet also
// If condition satisfies, it will click on the element
element.findElement(By.cssSelector("input").click();
}
}
This can be used as a common function also.

try [0] and [1] instead of the underscore.

Try your code with the given below CSS :
Step 1:
By Provided HTML Piece we can derive the CSS of the Radio Button
css=#Content_Content_Content_ctlCaseInfo_rdochldplcm input
Step 2:
Click on the radio button using Web Driver Code
driver.findElement
(By.cssSelector("#Content_Content_Content_ctlCaseInfo_rdochldplcm input"))
.click();

Related

Not able to Enter Text in a TextBox using Selenium Webdriver

I have a TextBox that appears on Radio Button Selection and I have to enter values in a particular format(XYZ989898-99). However I am unable to do so by using the commonly used methods of entering text in selenium.
Background info related to Textbox :
TextBox appears when user clicks on Yes radio button.
TextBox has default value as XYZ already entered.
SendKeys do not concatenate the text given without XYZ as well.
TextBox is inside an Iframe to which focus is shifted correctly.
The code does not fail, it just remained clicked on textbox without entering anything.
Approach 1 :
driver.findElement(locator).SendKeys("989898-99");
Approach 2 :
driver.findElement(locator).clear();
driver.findElement(locator).SendKeys("XYZ989898-99");
Approach 3 :
WebElement element = driver.findElement(locator);
Actions action1 = new Actions(driver);
action1.movetoElement(element).click().perform();
action1.sendKeys("XYZ989898-99");
HTML Sample :
<div class="value" ng-show="selectedValue" style="">
<label class="labelAboveTextBox">XYZ Number*</label>
<input type="text" class="Value" ng-model="XYZNumber" ng-
req="XYZNumber" xyz-input="" maxlength="12" style="value"
id="value" value="XYZ" required="required">
<!-- ngIf: invalidtspmessage -->
<span style="font-family: 'NeueHaasGroteskText';font-size:
0.7rem;color: black;">
Note: Enter XYZ is this format: XXXXXXXXX-XX
</span>
</div>
I would like to know If there is any other approach that can be used to get this problem resolved and also why does the above approaches failed to work.
You have used the wrong methods for sending the keys. (in approach 1 and 2)
Instead of .SendKeys(), you have to use .sendKeys() method for writing anything on UI side
Into the third approach, you have used the wrong method .movetoElement(). The method name is .moveToElement().
For sendKeys() don't need to use Actions class. basically, it is for Keyboard events and for mouse events.
(WebElement).sendKeys("989898-99"); // first approach you can use
(WebElement).clear(); // second approach you can use
(WebElement).sendKeys("XYZ989898-99");
Hope this will help you to solve your errors.
Other way you can use is to set the text is by using the JavaScriptExecutor. Give some delay before performing the action.
Try the below sample code :
Thread.sleep(3000);
((JavascriptExecutor) driver).executeScript("document.getElementById('value').value='XYZ989898-99';");
As the id is unique, you can use the JavaScript's getElementById() function to set the value.
If you want to set the text through the sendKeys() method and before that if you want to clear the text then simple clear() may not work instead you can try to delete the XYZ values first and try to send the values like below again :
// Wait for some time
Thread.sleep(3000);
// Locate the element first and store it in some variable
WebElement element = driver.findElement(By.id("value"));
// Fetch the existing text from the field first
String existingValue = element.getAttribute("value");
// Wait for some time
Thread.sleep(3000);
// Click on that element first so the focus will shift to there
element.click();
// Wait for some time
Thread.sleep(2000);
// Loop until the existing value length
for(int i=0;i<existingValue.length();i++) {
// Remove the existing character text one by one
element.sendKeys(Keys.BACK_SPACE);
}
// Try to send the text at the end, make sure that you should append XYZ as a prefix
element.sendKeys("XYZ989898-99");
I hope it helps...

How to validate Check box if xpaths are same in case of selected and unselected

M unable to validate checkbox, if it's selected or not
because both the HTML are same
I tried isSelected(), but it's not working
Below is the HTML code for both selected and unselected
1) Selected
<label class="c-account-access-panel__checkbox " for="23336" data-js-checkbox-label="">
<input id="23336" class="c-account-access-panel__checkbox-input" type="checkbox"
data-label-for-value-missing="Please select at least one account from the options below" data-form-field-validation-on-grid=""
required="" checked="" data-js-checkbox="" value="DE29973399" name="payer"/>
<div class="c-account-access-panel__checkbox-symbol"/>
2) Unselected
<label class="c-account-access-panel__checkbox " for="23336" data-js-checkbox-label="">
<input id="23336" class="c-account-access-panel__checkbox-input" type="checkbox"
data-label-for-value-missing="Please select at least one account from the options below" data-form-field-validation-on-grid=""
required="" checked="" data-js-checkbox="" value="DE29973399" name="payer"/>
<div class="c-account-access-panel__checkbox-symbol"/>
Thanks in advance!
As per the Java Docs isSelected() method determines whether the element is selected or not. This operation only applies to <input> elements such as checkboxes, options within a <select> tag and radio buttons.
To validate if the desired checkbox is selected or not you can use the following code block:
boolean checkboxSelected = driver.findElement(By.xpath("//input[#class='c-account-access-panel__checkbox-input' and #name='payer']")).isSelected();
If isSelected() is not working for you. Then , you can use JavascriptExecutor to do your task. Following JS statements shall let you know the state of target checkbox.
document.getElementById("23336").click();
document.getElementById("23336").checked;
The checked method returns true or false depending on the checkbox state.
You can validate using getAttributemethod.
First select the webElement using any of the unique locator,
WebElement checkbox=driver.findElement(By.xpath(".//input[#type='checkbox']"));
If the checkbox is selected, then checkbox.getAttribute("checked")will give the result as true else, it will give the result as null. So, you can add the condition using checkbox.getAttribute("checked")
Use xpath expression like: (//div [#id='23336')[1] or (//div [#id='23336')[2] to make them into unique element then do .isselected ()

How to Select a checbox by its corresponding label name

I am relatively new to xpath and I'm having an issue with Selecting a checkbox.
The following expression works fine
:xpath=//div/label[#for='chkCat2']
But I need to select a checkbox based on its label name (Music in this case)
Unfortunately, this -
xpath=.//div[label[contains(text(),'Music')]
is clicking on the label, not on the checkbox.
How is it possible to do that? I also tried this one but its not able to locate the element:
xpath=.//div[label[contains(text(),'Music')]/preceding-sibling::label]
That's the sample of the code:
<input name="ctl00$cphContent$ThreeMedia$categoriesRepeater$ctl01$ctl00"
data-bind="attr:{'id': 'chkCat' + id, 'data-id': id}, checked: selected" id="chkCat2" data-id="2" type="checkbox">
<label data-bind="attr:{'for': 'chkCat' + id}" for="chkCat2" class=" firepath-matching-node"></label>
<label class="chkbox-content margin-bottom-0" data-bind="text: name">Music</label>
Thanks for the help
But I need to select a checkbox based on its label name (Music in this case)
Assuming div is the parent element of the provided checkbox element, try using below xpath :-
.//div[normalize-space(.)='Music']/input
or more specific
.//div[normalize-space(.)='Music']/input[#type='checkbox']
one more
.//div[label[text() = 'Music']]/input
Try this below mentioned xpath
//label[text()= 'Music']/..//preceding-sibling::input[#id='chkCat2']
Explanation of xpath:- Use text method along with <label> tag and move ahead with <input> tag using preceding-sibling keyword.

How to check if radio button is selected or not using Selenium WebDriver?

<div class="my_account_module_content">
<h3 class="my_account_module_content_title">
Mi Dirección 1
<br>
<span>Predeterminada</span>
<div class="selectCard_left">
<input id="17390233" class="default_shipping_address" type="radio" name="address" checked="true">
<span>Seleccionar como tarjeta predeterminada</span>
</div>
this is the HTML code
If radio button selected is true then print the class span value?
please help me..
In Java, this would do it:
if(driver.findElement(By.id("17390233")).isSelected()){
System.out.println(driver.findElement(By.xpath("//input[#id='17390233']/following-sibling::span[1]")).getText());
}
If the radio button is selected, then the text will show. If you want to use the text somewhere, I suggest you put it in a string instead:
String spanText = driver.findElement(By.xpath("//input[#id='17390233']/following-sibling::span[1]")).getText();
Hope this answers your question.
EDIT: Here is an update of other ways to try.
If the className default_shipping_address is unique (e.g. not used anywhere else on the page), you may try locating the element by className:
if(driver.findElement(By.className("default_shipping_address")).isSelected()){
System.out.println(driver.findElement(By.xpath("//input[#class='default_shipping_address']/following-sibling::span[1]")).getText());
}
If that class is not unique, maybe the DIV's className selectCard_left is?
if(driver.findElement(By.className("selectCard_left"))){
System.out.println(driver.findElement(By.xpath("//div[#class='selectCard_left']/span[1]")).getText());
}
If none of the classNames are unique, a complete xpath expression is required. If you still are unable to get that text, I refer to reading up on how to use xpath: http://www.w3schools.com/XPath/xpath_syntax.asp
I hope that you find this information useful.

How can I select checkboxes using the Selenium Java WebDriver?

How can I check the checkboxes using an id or XPath expression? Is there a method similar to select by visibletext for a dropdown?
Going through the examples given for all other related questions, I could not find a proper solution that works in a concise way that by few line or method I can check a chekbox or radio button.
A sample HTML section is below:
<tbody>
<tr>
<td>
<span class="120927">
<input id="ctl00_CM_ctl01_chkOptions_0" type="checkbox" name="ctl00$CM$ctl01$chkOptions$0"/>
<label for="ctl00_CM_ctl01_chkOptions_0">housingmoves</label>
</span>
</td>
</tr>
<tr>
<td>
<span class="120928">
<input id="ctl00_CM_ctl01_chkOptions_1" type="checkbox" name="ctl00$CM$ctl01$chkOptions$1"/>
<label for="ctl00_CM_ctl01_chkOptions_1">Seaside & Country Homes</label>
</span>
</td>
</tr>
</tbody>
Selecting a checkbox is similar to clicking a button.
driver.findElement(By.id("idOfTheElement")).click();
will do.
However, you can also see whether the checkbox is already checked. The following snippet checks whether the checkbox is selected or not. If it is not selected, then it selects.
if ( !driver.findElement(By.id("idOfTheElement")).isSelected() )
{
driver.findElement(By.id("idOfTheElement")).click();
}
It appears that the Internet Explorer driver does not interact with everything in the same way the other drivers do and checkboxes is one of those cases.
The trick with checkboxes is to send the Space key instead of using a click (only needed on Internet Explorer), like so in C#:
if (driver.Capabilities.BrowserName.Equals(“internet explorer"))
driver.findElement(By.id("idOfTheElement").SendKeys(Keys.Space);
else
driver.findElement(By.id("idOfTheElement").Click();
If you want to click on all checkboxes at once, a method like this will do:
private void ClickAllCheckboxes()
{
foreach (IWebElement e in driver.FindElements(By.xpath("//input[#type='checkbox']")))
{
if(!e.Selected)
e.Click();
}
}
Solution for C#
try
{
IWebElement TargetElement = driver.FindElement(By.XPath(xPathVal));
if (!TargetElement.Selected)
{
TargetElement.SendKeys(Keys.Space);
}
}
catch (Exception e)
{
}
You can use the following code:
List<WebElement> checkbox = driver.findElements(By.name("vehicle"));
((WebElement) checkbox.get(0)).click();
My HTML code was as follows:
<.input type="checkbox" name="vehicle" value="Bike">I have a bike<br/>
<.input type="checkbox" name="vehicle" value="Car">I have a car<br/>
To get the checkbox for 'Seaside & Country Homes', use this XPath:
//label[text()='Seaside & Country Homes']/preceding-sibling::input[#type='checkbox']
To get the checkbox for 'housingmoves', use this XPath:
//label[text()='housingmoves']/preceding-sibling::input[#type='checkbox']
The principle here is to get the label with the text you want, then get the checkbox that is before the label, since that seems to be how your HTML is laid out.
To get all checkboxes, you would start a little higher up and then work down, so that is to say get the table, and then get any checkbox within a span:
//table/descendant::span/input[#type='checkbox']
I found that sometimes JavaScript doesn't allow me to click the checkbox because was working with the element by onchange event.
And that sentence helps me to allow the problem:
driver.findElement(By.xpath(".//*[#id='theID']")).sendKeys(Keys.SPACE);
This should help -
IWebElement elementToClick = driver.findElement(By.xpath(""//input[contains(#id, 'lstCategory_0')]"));
elementToClick.Click();
You can also pass an id.
If you want something like visible text you can "find element" by name if they have names.
The below code will first get all the checkboxes present on the page, and then deselect all the checked boxes.
List<WebElement> allCheckbox = driver.findElements(By
.xpath("//input[#type='checkbox']"));
for (WebElement ele : allCheckbox) {
if (ele.isSelected()) {
ele.click();
}
}
A solution using WebDriver and C# is below. The key idea is to get the ID of the checkbox from the labels' 'for' attribute, and use that to identify the checkbox.
The code will also set the checkbox state only if it needs to be changed.
public void SetCheckboxStatus(string value, bool toCheck)
{
// Get the label containing the checkbox state
IWebElement labelElement = this.Driver.FindElement(By.XPath(string.Format("//label[.='{0}']",value)));
string checkboxId = labelElement.GetAttribute("for");
IWebElement checkbox = this.Driver.FindElement(By.Id(checkboxId));
if (toCheck != checkbox.Selected)
{
checkbox.Click();
}
}
Maybe a good starting point:
isChecked = driver.findElement((By.id("idOftheElement"))).getAttribute("name");
if(!isChecked.contains("chkOptions$1"))
{
driver.FindElement(By.Id("idOfTheElement")).Click();
}
Running this approach will in fact toggle the checkbox; .isSelected() in Java/Selenium 2 apparently always returns false (at least with the Java, Selenium, and Firefox versions I tested it with).
The selection of the proper checkbox isn't where the problem lies -- rather, it is in distinguishing correctly the initial state to needlessly avoid reclicking an already-checked box.
To select a checkbox, use the "WebElement" class.
To operate on a drop-down list, use the "Select" class.
Step 1:
The object locator supposed to be used here is XPath. So derive the XPath for those two checkboxes.
String housingmoves="//label[contains(text(),'housingmoves')]/preceding-sibling::input";
String season_country_homes="//label[contains(text(),'Seaside & Country Homes')]/preceding-sibling::input";
Step 2:
Perform a click on the checkboxes
driver.findElement(By.xpath(housingmoves)).click();
driver.findElement(By.xpath(season_country_homes)).click();
For a partial match, do the following:
getDriver().findElement(By.cssSelector("<tag name>[id*='id pattern to look for']")).click();
Here is the C# version of Scott Crowe's answer. I found that both IEDriver and ChromeDriver responded to sending a Key.Space instead of clicking on the checkbox.
if (((RemoteWebDriver)driver).Capabilities.BrowserName == "firefox")
{
// Firefox
driver.FindElement(By.Id("idOfTheElement")).Click();
}
else
{
// Chrome and Internet Explorer
driver.FindElement(By.Id("idOfTheElement")).SendKeys(Keys.Space);
}
I tried with various approaches, but nothing worked. I kept getting "Cannot click element" or ElementNotVisibleException.
I was able to find the input, but I couldn't check it. Now, I'm clicking on the div that contains the checkbox and it works with following HTML (CSS based on Bootstrap).
#foreach (var item in Model)
{
<tr>
<td>
<div id="#item.Id" class="checkbox">
<label><input type="checkbox" class="selectone" value="#item.Id"></label>
</div>
</td>
<td val="#item.Id">
#item.Detail
</td>
<td>
<div>#item.Desc
</div>
</td>
<td>
#Html.ActionLink("Edit", "Create", new { EditId = item.Id })
</td>
</tr>
}
This is the code for WebDriver:
var table = driver.FindElement(By.TagName("table"));
var tds = table.FindElements(By.TagName("td"));
var itemTds = tds.Where(t => t.Text == itemtocheck);
foreach (var td in itemTds)
{
var CheckBoxTd = tds[tds.IndexOf(td) - 1];
var val = td.GetAttribute("val");
CheckBoxTd.FindElement(By.Id(val)).Click();
}
In this approach, I give the item id as id for the div and also add an attribute for td with that id. Once I find the td of the item that needs to be checked, I can find the div before that td and click it. We can also use the XPath query that supports before (here is the example http://learn-automation.com/how-to-write-dynamic-xpath-in-selenium/).