Select a row element based on another row element in Selenium - java

I want to select a checkbox based on another element in the row in Selenium. Eg: How do I select the checkbox corresponding to Cricket?
<body>
<table id="MyTable">
<tbody>
<tr>
<td>
<input type="checkbox" />
</td>
<td>Football</td>
</tr>
<tr>
<td>
<input type="checkbox" />
</td>
<td>Cricket</td>
</tr>
</tbody>
</table>
</body>

Try the following xpath:
driver.findElement(By.xpath("//table[#id='MyTable']//tr[contains(., 'Cricket')]//input[#type='checkbox']")).click();

See check boxes in general are input tag, you if you want to select that using Cricket keyword, you can use the below xpath :
//td[text()='Cricket']/preceding-sibling::td/input
and in code :-
driver.findElement(By.xpath("//td[text()='Cricket']/preceding-sibling::td/input")).click();
or
you could try with Explicit waits as well :
new WebDriverWait(driver, 10).until(ExpectedConditions.elementToBeClickable(By.xpath("//td[text()='Cricket']/preceding-sibling::td/input"))).click();

Related

How to access a webtable element using xpath if the webtable element is inside a td tag

I am not able to access the webtable elements inside the table2 , please see the page source below :
<table id="table1">
<tr class="head">
<td class="left" colspan="2">
<!--PAGE LINKS-->
</td>
</tr>
<tr>
<td class="left_link">
<h1>
<a name="nav_home" href="index.html" id="home_link" class="home">HOME</a><br>
<a name="nav_adopt" href="adoption.html" id="adoption_link">ADOPTION</a><br>
<a name="nav_about" href="about.html" id="about_link">ABOUT</a><br>
<a name="nav_contact" href="contact.html" id="contact_link">CONTACT</a><br>
</h1>
</td>
<td class="content">
<h1>
CONTACT US
</h1>
<hr>
<p>
Use the form below to contact us if you have any questions, queries or even any requests.
We are always happy to hear from you all.
</p>
<h1 class="subhead">Contact Form</h1>
<form name="message_form">
<table id="table2" class="inner_table">
<tr>
<td>Enter Name</td>
<td><input type="text" name="name_field"></td>
</tr>
<tr>
<td></td>
<td>
<input type="radio" id="rinfo" name="rbutton" value="information">Information
<input type="radio" id="rdona" name="rbutton" value="Donation">Donation
<input type="radio" id="radop" name="rbutton" value="Donation">Adoption
</td>
</tr>
For example i am not able to access the name inside the table2.
I tried accessing using below but failed .
driver.findElements(By.xpath("//*[#class='table1']/tbody/tr[2]/td[2]/form/table[#class='inner_table']/tr[1]/td[1))
Try this below xpath
//table[#id='table2']/..//following::input[#name='name_field']
Explanation of xpath:- Use id attribute of <table> tag and move ahead with <input> tag using following keyword.
This above xpath will locate the Enter Name field text box.
Note:- Instead of using absolute xpath, Use relative xpath.
It is not recommended to use xpath on selenium, since elements might tend to change and you have to refactor your selector if you add another element.
To answer your question, you can use the id for table2 and select the desired element.
It should be a CSS selector as simple as input[name='name_field'] or if that isn't specific enough, use #table2 input[name='name_field'].
Try xpath like below:
to access input filed with name 'name_field' use below xpath
driver.findElement(By.xpath("//table[#id='table2' and #class= 'inner_table']//input[#type='text' and #name='name_field']")
Hope it will help.
In web tables, you can use xPath to reach parent of an element and then finding the preceding-sibling or the following-sibling of td tags
This tutorial will help you:
http://www.seleniumtests.com/2011/10/using-xpath-to-reach-parent-of-element.html

Selenium Webdriver: Click on radio button not working

I have a code which clicks on a radio button, at first I was using Chrome. Using the code below:
driver.findElement(By.id("radioButton1"))).click();
I got the error:
"org.openqa.selenium.WebDriverException: Element is not clickable at point (411, 675). Other element would receive the click: ..."
Doing research, I changed the code to:
actions.moveToElement(driver.findElement(By.id("radioButton1"))).click().perform();
Now, I am trying to use Internet Explorer driver. But it does not perform the click.
I tried the following:
driver.findElement(By.id("radioButton1")).sendKeys(Keys.ENTER);
actions.moveToElement(driver.findElement(By.id("radioButton1"))).click().perform();
((JavascriptExecutor) driver).executeScript("arguments[0].click()", driver.findElement(By.id("radioButton1")));
But none works. The first one just focuses on the button, so I added another sendKeys, but it doesn't work. The 2nd and 3rd, nothing happens.
Edit:
Adding HTML snippet.
<input name="btn1" class="w-rdo-native" id="radioButton1" type="radio" value="value1" bh="RDOINP" isrefresh="false">
<label class="w-rdo w-rdo-dsize" bh="RDO"></label>
And when I click on the radio button, the label gets an additional property upon click.
<label class="w-rdo w-rdo-dsize" bh="RDO" AWMouseDown="true"></label>
Additional edit:
The set of buttons look like this:
and as stated before, one button + label block has the following HTML structure:
<tr>
<td>
<div class="w-rdo-container">
<input name="radioButtons" class="w-rdo-native" id="button1" type="radio" value="button1" bh="RDOINP" isrefresh="false">
<label class="w-rdo w-rdo-dsize" bh="RDO">
</label>
</div>
</td>
<td class="sectionHead">Option 2
</td>
</tr>
Upon clicking a button, the corresponding label gets an additional attribute:
<label class="w-rdo w-rdo-dsize" bh="RDO" AWMouseDown="true"></label>
It seems AWMouseDown seems to be the trigger to 'officially' click the button.
Edit :
Full HTML snippet of table. (Please note that this table has been cleansed so apologies for some mistake if I committed one.)
<table border="0" cellpadding="0" cellspacing="0" class="a-cptp-tbl">
<tbody>
<tr>
<td>
<div class="w-rdo-container">
<input checked class="w-rdo-native" id="btn1" name="radioBtn" type="radio" value="btn1"><label class="w-rdo w-rdo-dsize"></label>
</div>
</td>
<td class="sectionHead">Option 1</td>
</tr>
<tr>
<td></td>
</tr>
<tr>
<td>
<div class="w-rdo-container">
<input class="w-rdo-native" id="btn2" name="radioBtn" type="radio" value="btn2"><label class="w-rdo w-rdo-dsize"></label>
</div>
</td>
<td class="sectionHead">Option 2</td>
</tr>
<tr>
<td></td>
</tr>
<tr>
<td>
<div class="w-rdo-container">
<input class="w-rdo-native" id="btn3" name="radioBtn" type="radio" value="btn3"><label class="w-rdo w-rdo-dsize"></label>
</div>
</td>
<td class="sectionHead">Option 3</td>
</tr>
<tr>
<td></td>
</tr>
<tr>
<td>
<div class="w-rdo-container">
<input class="w-rdo-native" id="btn4" name="radioBtn" type="radio" value="btn4"><label class="w-rdo w-rdo-dsize"></label>
</div>
</td>
<td class="sectionHead">Option 4</td>
</tr>
<tr>
<td></td>
</tr>
<tr>
<td>
<div class="w-rdo-container">
<input class="w-rdo-native" id="btn5" name="radioBtn" type="radio" value="btn5"><label class="w-rdo w-rdo-dsize"></label>
</div>
</td>
<td class="sectionHead">Option 5</td>
</tr>
<tr>
<td></td>
</tr>
<tr>
<td>
<div class="w-rdo-container">
<input class="w-rdo-native" id="btn6" name="radioBtn" type="radio" value="btn6"><label class="w-rdo w-rdo-dsize"></label>
</div>
</td>
<td class="sectionHead">Option 6</td>
</tr>
<tr>
<td></td>
</tr>
</tbody>
</table>
Try using JavaScript like below:
WebElement radioBtn1 = driver.findElement(By.id("radioButton1"));
((JavascriptExecutor) driver).executeScript("arguments[0].checked = true;", radioBtn1);
If you are using QMetry Automation Framework, you should create custom radio button component like where you can override click method with such custom implementation.
Use ExplicitWait to wait for element until clickable and then have to click on that element
WebElement element = driver.findElement(By.id("radioButton1"));
WebDriverWait wait = new WebDriverWait(driver, 120);
wait.until(ExpectedConditions.elementToBeClickable(element));
element.click();
EDITED
If it is causing problem in IE browser. The cause is preventing to find element in IE browser is ActiveX Controls
So just you need to follow these steps -
Go to Internet options > Advanced > security and do check below mentioned checks -
after check > apply and then don't forgot to restart your PC
Now simply run your script and try to click on that element using id
driver.findElement(By.id("button1")).click();
Hope this will work. Let us know if still face the same issue.
Can you try identifying the radio buttons using a list and then clicking on an element in the list using its index with get()?
List<WebElement> radioGrp = driver.findElements(By.name("xxxxxxxx"));
radioGrp.get(0).click();
Not sure what is causing the problem.It works for me thought:
public static IWebDriver driver;
[Test]
public void TestMethod1()
{
driver = new PhantomJSDriver();
driver.Navigate().GoToUrl("file:///C:/Users/utripra/Desktop/test.html");
driver.FindElement(By.Id("radioButton1")).Click();
It seems that the radio button is combination of the <input> and <label> tags, i.e. the <div> with class="w-rdo-container" or its <td> parent. I think so because the rapper <td> and the <td> where the label Option 2 is are siblings.
class="w-rdo-container" doesn't seem to be unique, so you can use xpath to go up the html tree from id="button1"
driver.findElement(By.xpath("//div[input[#id='button1']]")).click(); // to click the div
// or
driver.findElement(By.xpath("//td[div[input[#id='button1']]]")).click(); // to click the td
Try following for clicking on Option 2 radio button:
driver.findElement(By.xpath("//td[normalize-space(text())='Option 2']/preceding::input[1]")).click();
Write a method that will accept the position of the radio button and click on the button by using cssSelector as follows:
driver.findElement(By.cssSelector("table.a-cptp-tbl > tbody > tr:nth-child(" + checkBoxPosition + ") > td > div > input")).click();
Full method:
public void selectOption(int positionOfCheckBox){
By locator = By.cssSelector("table.a-cptp-tbl > tbody > tr:nth-child(" + positionOfCheckBox + ") > td > div > input");
//wait for your element to be visible
WebDriverWait wait = new WebDriverWait(driver, 30);
wait.until(ExpectedConditions.visibilityOfElementLocated(locator));
//click element after it is visible/clickable
driver.findElement(locator).click();
}
Just add Thread.sleep(5000); above your script for radio button.
For example like this
Thread.sleep(5000);
driver.findElement(By.id("uniform-id_gender2")).click();
It works for me.
:)

Selenium Java findElement Query not valid for unique ID or Xpath

I am trying to select the email, password, and signin elements from here.
The element has a unique ID and I'm able to copy the Xpath from inspecting it.
I have tried these queries and unable to figure out why Selenium cannot find it.
WebElement emailfield = driver.findElement(By.id("lid"))
WebElement emailfield = driver.findElement(By.xpath("//*[#id=\'lid\']"));
WebElement emailfield = driver.findElement(By.xpath("//*[#id=lid]"));
The drive is able to open and launch chrome to do this. However, I am not lucky.
Please let me know in what way these are not valid. As I understand it, the id should be completely unique but neither the By.id and By.xpath methods are not finding the element.
Here is my code.
String email = "myemail";
String password = "the_password";
WebElement emailfield = driver.findElement(By.id("lid"));
emailfield.sendKeys(email );
WebElement passwordfield = driver.findElement(By.xpath("//*[#id=pwd]"));
passwordfield.sendKeys(password );
WebElement login = driver.findElement(By.id("submit_but"));
login.click();
Here is HTML table.
<table width="260" align="center" class="mob_width" cellspacing="2" cellpadding="1">
<tbody><tr>
<td colspan="2">
<h3 class="signintxt">Sign In</h3>
</td>
</tr>
<tr>
<td align="center" colspan="2"><span id="msgpanel"></span></td>
</tr>
<tr>
<td class="label">Email / Phone:</td>
<td align="left"><input name="lid" class="input usrbx" id="lid" onkeypress="clearmsg()" type="email" value=""></td>
</tr>
<tr>
<td class="label">Password:</td>
<td align="left"><input name="pwd" class="input passbx" id="pwd" onkeypress="clearmsg()" type="password"></td>
</tr>
<tr>
<td class="label"></td>
<td align="left"><div class="forgotpasslink"><span onclick="goToForgotPassword();">Forgot Password?</span></div>
</td></tr>
<tr id="hiptr" style="display: none;">
<td class="label"> </td><td align="left"> </td>
</tr>
<tr>
<td class="emptytd"></td>
<td height="30" class="mobile-height">
<div class="sectxt">
<label>
<input name="rem" id="rem" type="checkbox" value="10">
<span class="securetxt">Keep me signed in</span>
</label>
</div>
</td>
</tr>
<tr>
<td class="emptytd"></td>
<td align="left">
<button name="submit" class="submit_mobile" id="submit_but" type="submit">Sign In</button>
</td>
</tr>
</tbody></table>
Here is an Explicit wait that compiles, and wait 10 seconds and gives same error.
//explicit
WebDriverWait wait = new WebDriverWait(driver, 10);
WebElement aboutMe;
aboutMe= wait.until(ExpectedConditions.visibilityOfElementLocated(By.xpath(".//form[#id='login']//*[#id='lid']")));
aboutMe.click();
The fields are inside <iframe>. You need to switch to it first
driver.switchTo.frame("zohoiam"); // switch by iframe ID
WebElement emailfield = driver.findElement(By.id("lid"));
// some more code
driver.switchTo().defaultContent(); // switch out of the iframe
For more switch options look here.
You have made syntactical error while writing the xpath,
//*[#id=\'lid\']
has wrong syntax [You can verify this using firebug & firepath].
Try below xpath it should work,
.//*[#id='lid']
However you can add the parent Form node to make it more robust,
.//form[#id='login']//*[#id='lid']
Finally, you need to make sure that you wait till the page is loaded completely before going for element identification.
For more on explicit wait, refer Selenium webdriver explicit wait

Selenium Webdriver - Unticking all the chekboxes in a complicated table

I am having some problems currently trying to untick checkboxes in an iframe. The situation is it is currently possible to set some checkboxes to default ticked and some not. I need 1 specific checkbox ticked, so the sensible thing to do is run a loop that iterates through all the checkboxes and unchecks them all.
Here is where I am running into issues. I will post a sample of the HTML that the checkboxes are contained in. (This isn't mine so I can't edit the HTML unfortunately).
This is how the example looks in a situation where there are 3 different types of checkbox in the iframe.
<fieldset id="testing">
<legend>testing</legend>
<table>
<tbody>
<tr>
<td class="EXAMPLE">
<table id="CHECKBOXTYPE1">
<tbody>
<tr>
<td style="vertical-align:top;white-space:nowrap;" title="">
<input id="CHECKBOXTYPE1-01" type="checkbox" value="on" onclick="DOES STUFF;"/>
</td>
<td style="vertical-align:top;white-space:nowrap;" title="">TITLE1</td>
</tr>
<tr>
<td/>
<td id="CHECKBOXTYPE2-01" style="display:none;white-space:nowrap;vertical-align:top;padding:0px;">
<table>
<tbody>
<tr>
<td style="vertical-align:top;" colspan="3">
<select id="field" style="width:100%;">
<option value="1">STUFF1 </option>
<option value="2">STUFF2 </option>
<option value="3">STUFF3 </option>
<option value="4">STUFF4 </option>
</select>
</td>
<td style="vertical-align:bottom;padding-left:6px;" rowspan="2">
<textarea id="CHECKBOXTYPE2-01-COMMENTS" cols="50" rows="2" style="margin:0px;height:50px;" type="text" onclick="DOES STUFF">Please Insert Notes...</textarea>
</td>
</tr>
<tr>
<td style="vertical-align:bottom;">
<input type="CHECKBOXTYPE2-01-BUTTON" onclick="DOES STUFF" value="<" style="height:100%;width:32px;"/>
</td>
<td style="vertical-align:bottom;">
<input id="CHECKBOXTYPE2-01-INPUT" type="input" readonly="" style="width:112px;"/>
</td>
<td style="vertical-align:bottom;">
<input type="CHECKBOXTYPE2-01-BUTTON" onclick="DOES STUFF" style="width:32px;height:100%;" value=">"/>
</td>
</tr>
</tbody>
</table>
</td>
</tr>
</tbody>
</table>
</td>
</tr>
<tr>
<td class="field_label">
<table id="CHECKBOXTYPE3">
<tbody>
<tr>
<td style="vertical-align:top;">
<input id="CHECKBOXTYPE3-01" type="checkbox" title="" onclick="DOES STUFF"/>
</td>
<td style="vertical-align:top;" title="">CHECKBOX NAME</td>
<td style="vertical-align:top;">
</tr>
</tbody>
</table>
</td>
</tr>
</tbody>
</table>
The code I have attempted to iterate is
try{
for(int i=0; i < 30; i++){
WebElement relCheckBoxes = driver.findElement(By.xpath("html/body/div[3]/fieldset/table/tbody/tr[i]/td/table/tbody/tr/td[1]"));
if(relCheckBoxes.isSelected()){
relCheckBoxes.click();
}
}
}
catch(Exception e){
System.out.printf("didn't work");
}
Obviously this is not the most optimised piece of code, but right now I'm just struggling to find something that works :\ I just want to run through the checkboxes, turn off all of them, then turn on the one that I need after.
Thank you.
If you want to uncheck all the checkboxes use the following code. It is much efficient!
//Get the complex table
WebElement mainTable = driver.findElement(By.xpath("html/body/div[3]/fieldset/table"));
//Find all the input tags inside the mainTable and save it to a list
List<WebElement> checkBoxes = mainTable.findElements(By.tagName("input"));
//iterate through the list of checkboxes and if checked, uncheck them
for (WebElement checkbox : checkBoxes) {
if (checkbox.isSelected()) {
checkbox.click();
}
}
I dont see any frame inside your code. If there is a frame use the below code 1st
//switch to the frame
driver.switchTo().frame("framename/index");
Hope this helps you :)
There are a couple of problems here:
1) Your XPath is incorrect. You have:
"html/body/div[3]/fieldset/table/tbody/tr[i]/td/table/tbody/tr/td[1]"
Instead, it should be:
"html/body/div[3]/fieldset/table/tbody/tr[" + i + "]/td/table/tbody/tr/td[1]"
Otherwise, you're just looking for a table row with a non-numerical index 30 times!
2) XPath indices are 1-based rather than 0-based (crazy, I know). Since your loop starts with i=0, it starts off by trying to find the non-existent zeroth element. findElement throws an exception when it cannot locate an element that matches the search criterion, so the loop ends immediately. Try starting the loop with i=1 instead.

How to select radio button in selenium webdriver ? dynamic select of radio button

<tbody>
<tr class="odd">
<td>
<input id="nodeAccountOid" type="radio" onclick="setNodeAccountIdToCredentialCheck('E9E2930C4493B569E040A8C0158E4ABD');" style="width:100%;border:0px">
</td>
<td>E9E2930C4493B569E040A8C0158E4ABD</td>
<td>monacho1</td>
<td>urn:dece:org:org:dece:dece:cs</td>
</tr>
<tr class="even">
<td>
<input id="nodeAccountOid" type="radio" onclick="setNodeAccountIdToCredentialCheck('E9E2930C4494B569E040A8C0158E4ABD');" style="width:100%;border:0px">
</td>
<td>E9E2930C4494B569E040A8C0158E4ABD</td>
<td>monacho1</td>
<td>urn:dece:org:org:dece:coord:cs</td>
</tr>
<tr class="odd">
<td>
<input id="nodeAccountOid" type="radio" onclick="setNodeAccountIdToCredentialCheck('E9E2930C4495B569E040A8C0158E4ABD');" style="width:100%;border:0px">
</td>
<td>E9E2930C4495B569E040A8C0158E4ABD</td>
<td>monacho1</td>
<td>urn:dece:org:org:dece:300</td>
</tr>
<tr class="even">
<td>
<input id="nodeAccountOid" type="radio" onclick="setNodeAccountIdToCredentialCheck('E9E2930C4495B569E040A8C0158E4ABD');" style="width:100%;border:0px">
</td>
<td>E9E2930C4495B569E040A8C0158E4ABD</td>
<td>monacho1</td>
<td>urn:dece:org:org:dece:10</td>
</tr>
</tbody>
</table>
i want to select the radio button corresponding to urn:dece:org:org:dece:10 which is fourth row in the html provided. the row may change sometimes based on some inputs in AUT. please provide me the way to select it.
thanks in advance
Since the text never changes, you can use that as a starting point within the DOM, and use XPath to navigate through to the input you need:
//td[.='urn:dece:org:org:dece:10']/parent::tr/descendant::input[#id='nodeAccountOid' and #type='radio']
Get the td that has it's text equal to urn:dece:org:org:dece:10
Get that td's parent tr
From that parent tr, get the input that has an id equal to nodeAccountOid and has a type of radio.
Therefore it doesn't matter where exactly the elements are, as long as the XPath locator can navigate up to the parent and back down again to the input you need.
The problem you are facing is to locate a certain element in the web page that may occur in different positions.
If there is another element which can be identified easily by its content, id or name and there is a static relation between this element and the one you would like to locate, then you could use xpath. There are also some examples for this in the selenium documentation as far as I know.

Categories