Diffulties in identifying web page element in salesforce application - java

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

Related

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

Need xpath for selecting checkbox in selenium web driver

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();

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

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.

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