Need xpath for selecting checkbox in selenium web driver - java

Below is the html code... I want to know which xpath can I use to select such a check box.
In actual HTML code I have multiple td for checkboxes, here I have shown only one.
I already tried
driver.findElement(By.id("cntMain_GridView1_chIndividual_0")).click();
but it gives an error saying no such element found on web page.
<table id="cntMain_GridView1" class="table iconTwo" cellspacing="0" cellpadding="3" style="width:100%;border-collapse:collapse;">
<tbody>
<tr>
<td class="no-sorting" valign="top" align="left" style="width:10px;">
<p class="defaultP" tabindex="35">
<span style="display:inline-block;width:5%;">
<div class="ez-checkbox">
<div class="ez-checkbox">
<input id="cntMain_GridView1_chIndividual_0" class="ez-hide" type="checkbox" onclick="javascript:RbtnOnOff(this.id);" name="ctl00$cntMain$GridView1$ctl02$chIndividual" tabindex="-1"/>
</div>
</div>
</span>
</p>
</td>
</tr>
</tbody>
</table>

Try changing the display style property of the element and then clicking on the element. Use JavascriptExecutor to make the element visible. Try the following code:
JavascriptExecutor js = (JavascriptExecutor) driver;
String domain_name = (String) js.executeScript("return document.getElementById(" +
"'cntMain_GridView1_chIndividual_0').style.visibility = 'visible'");
driver.findElement(By.id("cntMain_GridView1_chIndividual_0")).click();

Related

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.
:)

Diffulties in identifying web page element in salesforce application

Currently working on the automation of salesforce application.
I need a quick help to check the below code, i am unable to identify the element using java container. here is the HTML source for the page.
<div class="pbBody">
<span id="j_id0:j_id1:j_id5:matrixGrid">
<div id="j_id0:j_id1:j_id5:j_id7">
<div class="pbSubsection">
<table class="detailList" cellspacing="0" cellpadding="0" border="0">
<tbody>
<tr>
<tr>
<th class="labelCol vfLabelColTextWrap last " scope="row">
<td class="dataCol last ">EUR</td>
<th class="labelCol vfLabelColTextWrap last " scope="row">
<td class="dataCol last ">
<span id="j_id0:j_id1:j_id5:j_id7:j_id11:theDrPriceMatrix">Germany</span>
</td>
</tr>
</tbody>
</table>
JAVA Container is written here to identify element in tag
WebElement w5=driver.findElement(By.cssSelector("table.detailList"));
System.out.println(w5);
WebElement w6=w5.findElement(By.xpath("/html/body/form/span/div/div/div/div/div[1]/span/div/div/table/tbody/tr[2]"));
WebElement w7=w6.findElement(By.cssSelector("td.dataCol"));
List<WebElement> l3=w7.findElements(By.tagName("span"));
for (int i = 0; i <l3.size();i++)
{
System.out.println(l3.get(i).getText());
}
l3.get(0).getText();
actually the issue is I am not able to write anything for in the container

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 finds the "next" button of web application but click() doesn't work

This is on a FF browser.
I have a web application with a next button on a toolbar. My Selenium script finds the button and apparently clicks it as the element gets highlighted but the next page doesn't open.
How can I make it to go the the next page?
Here is an image of the toolbar in idle state:
And after the element is clicked:
As suggested in one other post I am clicking on a non-clickable element to get focus and then clicking the next button... but the button is highlighted but doesn't go to next page
driver.findElement(By.xpath("/html/body/form/span[1]/div/table/tbody/tr[4]/td/span")).click();
driver.findElement(By.xpath("/html/body/form/span[1]/div/table/tbody/tr[4]/td/span/div/div/div[1]/table/tbody/tr/td[11]/div")).click();
Part of the HTML is
<table id="ReportViewer1_fixedTable" cellspacing="0" cellpadding="0" style="table-layout:fixed;width:100%;height:100%;">
<tbody>
<tr style="background-color:#ECE9D8;">
<tr id="ParametersRowReportViewer1" style="display:none;">
<tr style="height:6px;font-size:2pt;display:none;">
<tr>
<td colspan="3">
<span id="ReportViewer1_Toolbar">
<div id="ReportViewer1_ctl06" style="font-family:Verdana;font-size:8pt;border-bottom:1px #CCCCCC Solid;background-color:#ECE9D8;background-image:url(/PlateTechManager/Reserved.ReportViewerWebControl.axd?OpType=BackImage&Version=10.0.30319.1&Color=%23ECE9D8&Name=Microsoft.Reporting.WebForms.Icons.toolbar_bk.png);">
<div style="padding-left:6px;">
<div class=" " style="display:inline-block;font-family:Verdana;font-size:8pt;vertical-align:top;">
<table cellspacing="0" cellpadding="0" style="display:inline;">
<tbody>
<tr>
<td height="28px">
<td width="4px"></td>
<td height="28px">
<td width="4px"></td>
<td height="28px">
<td width="4px"></td>
<td height="28px">
<td width="4px"></td>
<td height="28px">
<td width="4px"></td>
<td height="28px">
<div id="ReportViewer1_ctl06_ctl00_Next">
<div id="ReportViewer1_ctl06_ctl00_Next_ctl00" style="border: 1px solid transparent; background-color: transparent; cursor: default;">
<table title="Next Page">
<tbody>
<tr>
<td>
I tried this and didn't work
Actions builder = new Actions(driver);
WebElement we = driver.findElement(By.xpath("/html/body/form/span[1]/div/table/tbody/tr[4]/td/span/div/div/div[1]/table/tbody/tr/td[11]/div"));
builder.moveToElement(we).click().build().perform();
EDIT
After looking some more into this behavior, it seems like the element is highlighted but not actually clicked.(How do I know this? When the test ends the element stays highlighted. As soon as I move the mouse the element becomes normal) So don't know why the click is not happening
Two things to try:
move to an element and click:
Actions builder = new Actions(driver);
builder.moveToElement(link).click(link).build().perform();
click the link by executing javascript click():
((JavascriptExecutor) driver).executeScript("arguments[0].click();", link);
where link is a WebElement instance for the link (the result of findElement() call).

accessing <td> value with selenium

Using selenium i'm trying to read out a dynamically generated table, i got down to the right elements (using the findElement method) but using getText() on them returns nothing.
Probably because getText() looks for quotation marks when returning "text" and can't find any between the <td> tags. Some suggestions were to use xpaths but since the tables are generated dynamically the location of the value i need also changes.
here's the table i'm trying to get 3 data points from:
<table cellpadding="0" cellspacing="0" class="fleetinfo">
<tbody><tr>
<th colspan="2">Schepen:</th>
</tr>
<tr>
<td>Groot vrachtschip:</td>
<td class="value">
40 </td>
</tr>
<tr>
<td colspan="2"> </td>
</tr>
<tr>
<th colspan="2">Lading:</th>
</tr>
<tr>
<td>Metaal:</td>
<td class="value">
536.062 </td>
</tr>
<tr>
<td>Kristal:</td>
<td class="value">
289.008 </td>
</tr>
<tr>
<td>Deuterium:</td>
<td class="value">
92.750 </td>
</tr>
</tbody></table>
the ones i'm interested in are the ones inside the <td class="value"> tags but as i said before, using getText() on them returns null.
Any idea on how i can acces those values?
edit: here's how i'm doing it now
private int getMetalFromFleet(WebElement fleet)
{
int ret=0;
WebElement streak = fleet.findElement(By.className("starStreak"));
List<WebElement>fleetDetails = streak.findElements(By.tagName("tr"));
for(WebElement detail : fleetDetails)
{
List<WebElement> tabel = detail.findElements(By.tagName("td"));
if(tabel.size() != 2)
continue;
if(tabel.get(0).getText().equalsIgnoreCase("metaal:"))
{
ret = Integer.parseInt(tabel.get(1).getText());
break;
}
}
return ret;
}
edit: here's the relevant bit of html
<div id="fleet9965869" class="fleetDetails detailsOpened" data-mission-type="4" data-return-flight="false" data-arrival-time="1378241688">
<span class="timer tooltip" title="03.09.2013 22:54:48" id="timer_9965869">58m 48s</span>
<span class="absTime">22:54:48 Klok</span>
<span class="mission neutral textBeefy">Plaatsen</span>
<span class="allianceName"></span>
<span class="originData">
<span class="originCoords tooltip" title="killernerd">[5:213:8]</span>
<span class="originPlanet">
<figure class="planetIcon planet tooltip js_hideTipOnMobile" title="planeet"></figure>k7 </span>
</span>
<span class="marker01"></span>
<span class="marker02"></span>
<span class="fleetDetailButton">
<a href="#bl9965869" rel="bl9965869" title="Vlootdetails" class="tooltipRel tooltipClose fleet_icon_forward">
</a>
</span>
<span class="reversal reversal_time" ref="9965869">
<a class="icon_link tooltipHTML" href="http://uni107.ogame.nl/game/index.php?page=movement&return=9965869" title="Roep terug:| 04.09.2013<br>01:54:05">
<img src="http://gf2.geo.gfsrv.net/cdna2/89624964d4b06356842188dba05b1b.gif" height="16" width="16">
</a>
</span>
<span class="starStreak">
<div style="position: relative;">
<div class="origin fixed">
<img class="tooltipHTML" height="30" width="30" src="http://gf1.geo.gfsrv.net/cdnf0/af41c52dc08208b4463f4a4608e88c.png" title="" alt="">
</div>
<div class="route fixed">
<div style="display:none;" id="bl9965869">
<div class="htmlTooltip">
<h1>Vlootdetails:</h1>
<div class="splitLine"></div>
<table cellpadding="0" cellspacing="0" class="fleetinfo">
<tbody><tr>
<th colspan="2">Schepen:</th>
</tr>
<tr>
<td>Groot vrachtschip:</td>
<td class="value">
960 </td>
</tr>
<tr>
<td colspan="2"> </td>
</tr>
<tr>
<th colspan="2">Lading:</th>
</tr>
<tr>
<td>Metaal:</td>
<td class="value">
8.173.484 </td>
</tr>
<tr>
<td>Kristal:</td>
<td class="value">
6.325.966 </td>
</tr>
<tr>
<td>Deuterium:</td>
<td class="value">
7.474.821 </td>
</tr>
</tbody></table>
</div> </div>
</div>
<div class="destination fixed">
<img class="tooltipHTML" height="30" width="30" src="http://gf2.geo.gfsrv.net/cdnaa/af0b356fdbecc1cfc47130e990fa66.png" title="Aankomsttijd:| 03.09.2013<br>22:54:48" alt="">
</div>
</div>
</span><!-- Starstreak -->
<span class="destinationData">
<span class="destinationPlanet">
<span>
<figure class="planetIcon planet tooltip js_hideTipOnMobile" title="planeet"></figure>Hoelbrak </span>
</span>
<span class="destinationCoords tooltip" title="killernerd">[1:2:6]</span>
</span>
<span class="nextTimer tooltip" title="04.09.2013 03:52:31" id="timerNext_9965869">5u 56m 31s</span>
<span class="nextabsTime">03:52:31 Klok</span>
<span class="nextMission friendly textBeefy">Keer terug</span>
<span class="openDetails">
<a href="javascript:void(0);" class="openCloseDetails" data-mission-id="9965869" data-end-time="1378241688">
<img src="http://gf3.geo.gfsrv.net/cdnb6/577565fadab7780b0997a76d0dca9b.gif" height="16" width="16">
</a>
</span>
</div>
the values i need are the numeric values under "Metaal", "kristal" and "deuterium".
I would recommend using xpath in this scenario rather then relying on tagnames;
private int getMetalFromFleet(WebElement fleet)
{
By identifier = By.xpath("td[contains(text(),'Metaal')]/following-sibling::td[contains(#class,'value')]");
return Integer.parseInt(fleet.findElement(identifier).getText());
}
Obviously you will want some error handling in there, but hopefully this gives the idea that those loops are not always required, and Xpath isn't always the bogeyman it is made out to be by some.
EDIT
Just in case anyone is confused, it is okay for the XPath to not have leading slashes if the selector is performed on a WebElement rather than the WebDriver object.
You would have to add two leading slashes if this selector was used on the WebDriver object.
EDIT AGAIN!
Xpath may need some tweaking but you should get the idea of the approach. I cannot see "StarStreek" in your html but it was in your code so added it to my xpath.
I found some kind of an answer after digging through a ton of programming sites.
Apparently items that have the style="display:none"; flag set like this will be seen as "hidden" by selenium.
This is, unfortunately, a feature and not a bug of some sort as selenium "tries to emulate the user" and will therefore hide information that is not explicitely visible.
"The user can't see it so neither can selenium" is their thought progress.
Here is the source.
This, unfortunately, does not solve my issue. I can however try to get around this, I'll report back my findings.
EDIT: It's amusing how different HtmlUnitDriver is from FirefoxDriver. One thing that works on HtmlUnitDriver won't work on FirefoxDriver and vice versa.
EDIT-2: Found a solution! Finally.
Using selenium's JavascriptExecutor I can directly get the innerHTML from the found element like so:
By identifier = By.xpath("*[contains(#class,'starStreak')]//td[contains(text(),'Metaal:')]/following-sibling::td[contains(#class,'value')]");
String script = "return arguments[0].innerHTML";
String outcome = (String) ((JavascriptExecutor) driver).executeScript(script, fleet.findElement(identifier));
It's still annoying as hell that you can't just use getText() though. It should at least be an option.
Got similar problem - i want to click on a row in a table which has given value. Solution (id can be changed to class name etc.):
driver.findElement(By.xpath("//table[#id='<yourTableId>']//tr//td[contains(text(),'"+<givenValue>+"')]")).click();
When I get value of td, I can get for 12 td per tr tag. More than 12 must one click on td tag then getText()
This work for me correctly.

Categories