I have written this loop below. It executes perfectly fine in the first iteration; however, in the second iteration, it returns the following error:
Unable to locate element:
{"method":"xpath","selector":"html/body/header[2]/div[2]/nav/ul/li[2]/a"}`
Command duration or timeout: `120.06` seconds
The loop code is mentioned below:
Workbook w2;
w2 = Workbook.getWorkbook(new File("C:\\Users\\pcs\\Desktop\\flightdata.xls")); //flight data destintion location will be same as source from flight data.
Sheet s2 = w2.getSheet(0);
for (k = 1; k < s2.getRows(); k++)
{
//redeem flow
d1.findElementByXPath("html/body/header[2]/div[2]/nav/ul/li[2]/a").click();
d1.findElementByXPath("html/body/header[2]/div[2]/nav/ul/li[2]/ul/li[3]/a").click();
d1.findElement(By.xpath("html/body/section/div[1]/form/div/div[2]/div[1]/div/div[1]/input")).sendKeys(s2.getCell(0, k).getContents());
//pause for list to be populated
try
{
Thread.sleep(1000L);
}
catch (Exception e)
{
}
//Get all items in autocomplete list
List<WebElement> items1 = d1.findElements(By.xpath("html/body/ul/li[3]/a"));
//Look for item
for( i= 0; i <items1.size();i++)
{
if(items1.get(i).getText().contains(s2.getCell(0, k).getContents()))
{
items1.get(i).click();
break;
}
}
//calendar handling
d1.findElementById("checkin").click();
d1.findElementByXPath("html/body/div[2]/div[2]/div/a/span").click();
d1.findElementByXPath("html/body/div[2]/div[2]/table/tbody/tr[3]/td[3]/a").click();
//Select Number of Rooms
d1.findElementById("roomscount").sendKeys("1");
//Select Room type
d1.findElementById("roomtype").sendKeys("Single");
//Occupant's Nationality
d1.findElementById("nationality").sendKeys("India");
//Click search button
d1.findElementByXPath("html/body/section/div[1]/form/div/div[2]/div[4]/input").click();
//after 2 min wait
d1.manage().timeouts().implicitlyWait(120, TimeUnit.SECONDS);
}
POST SEARCH HTML PAGE
<!DOCTYPE html>
<html>
<head>
<body class="" ondrop="return false;" ondragstart="return false;" onunload="" onpageshow="if (event.persisted) noBack();" onload="noBack();">
<header>
<div class="logo">
<div class="right">
<ul class="login">
<nav class="links">
<ul>
<li>
<li>
Redeem sMiles
<ul>
<li class="pointer sprite"> </li>
<li class="flight">
<li class="hotel">
<a href="hotel.html?action=hotels">
<span class="sprite"> </span>
Hotels
</a>
</li>
<li class="smiles">
</ul>
</li>
</ul>
</nav>
<div class="clear"></div>
</div>
<div class="clear"></div>
</header>
<div class="clear"></div>
<script src="/fm/travel/js/hotel.js" type="text/javascript">
<meta content="text/html; charset=utf-8" http-equiv="Content-Type">
<link type="text/css" rel="stylesheet" href="/fm/styles/demo_table_jui.css">
<link rel="stylesheet" href="/fm/travel/styles/ui-lightness/jquery-ui-1.10.4.css">
<link rel="stylesheet" href="/fm/travel/styles/ui-lightness/autocomplete.css">
<script src="/fm/travel/js/jquery-1.10.2.js" type="text/javascript">
<script src="/fm/travel/js/jquery-ui-1.10.4.js" type="text/javascript">
<script src="http://maps.googleapis.com/maps/api/js?key=AIzaSyDY0kkJiTPVd2U7aTOAwhc9ySH6oHxOIYM&sensor=false">
<script type="text/javascript">
<script type="text/javascript">
<script type="text/javascript">
<div id="loader" style="display: none;">
<div id="modifySearchBlock" style="display: block;">
<div class="clear"></div>
<footer>
<script src="/fm/travel/js/jquery.js">
<script src="/fm/js/bootstrap.min.js">
<script src="/fm/js/jquery.meanmenu.js">
<script>
<script src="/fm/js/jquery.simpleGal.js">
<script>
<script src="/fm/js/owl.carousel.js">
<script>
<div id="ui-datepicker-div" class="ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all"></div>
<ul id="ui-id-1" class="ui-autocomplete ui-front ui-menu ui-widget ui-widget-content ui-corner-all " tabindex="0" style="display: none;"></ul>
</body>
</html>
The above code belongs to the page where I return once search is completed.
Again I need to go to the below link to do the search:
<li class="flight">
<li class="hotel">
<a href="hotel.html?action=hotels">
<span class="sprite"> </span>
Hotels
</a>
</li>
<li class="smiles">
</ul>
</li>
The above code belongs to the link which I need to click. please provide same suggestions.
First you should have a look to other selector than xpath which is unreadble and can be dangerous, here you will a lot a way to find elements. For example cssSelector is a very reliable way to find element.
Another advantage is that your code become more readable.
If I understand, the first iteration no problem, then the seconde one, this is the click on the dropdown at the top of your page that cause the crash.
A possible solution is that your page is not come back to its original state at the end of your loop. You could refresh the page at the end of the loop:
driver.navigate().refresh();
Or check in which state you are at the end of the loop.
Hope that helps.
Well, the problem which my code was facing is that when search gets finished, I was trying trying to click the web elements with the same old xpaths. Actually, on close analysis I found that the xpaths of the same webelements on the results page got altered slightly due to which my script was not able to recognize the elements on new location.
Hence, i just changed the xpaths and problem got resolved.
Related
I need to click on or find element "Compute vmSwitch". I tried many ways using xpath (class & contains), cssSelector as well, but could not able to locate element:
driver.findElement(By.xpath("//span[contains(#class,'nopadding vm-create-text-style-3 block-with-text-4 ng-binding') and contains(text(), 'Compute vmSwitch')]")).click();
The code is given below:
<div class="w-full"><br>
<img class="img-responsive center-block m-t-47" src="/src/icon/background/create_vm_img5.png">
<div class="col-md-12 m-t-md wordwrap">
<p class="nopadding vm-create-text-style-3 block-with-text-4 ng-binding">
Compute vmSwitch</p>
</div>
Why do you try with the span tag?
If this is your html:
<html>
<head></head>
<body>
<div class="w-full">
<br>
<img class="img-responsive center-block m-t-47" src="/src/icon/background/create_vm_img5.png">
<div class="col-md-12 m-t-md wordwrap">
<p class="nopadding vm-create-text-style-3 block-with-text-4 ng-binding"> Compute vmSwitch</p>
</div>
</div>
</body>
</html>
you could try:
WebElement elem2= driver.findElement(By.xpath("//div[#class='w-full']"));
elem2.findElement(By.xpath(".//p[text()=' Compute vmSwitch']")).click();
<!doctype html>
<html>
<head>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"> </script>
<meta charset="utf-8">
<title>Chat</title>
<script src="http://code.jquery.com/jquery-latest.min.js"></script>
<script>
$(document).ready(function() {
$('#button').click(function() {
$.get('/backEnd', function(data) {
$("#textarea").html(data);
});
});
});
</script>
</head>
<body>
<label for="textarea">
<blockquote>
<ul>
<ul>
<li><strong>Session Progress</strong></li>
</ul>
</ul>
</blockquote>
</label>
<p>
<textarea name="textarea" cols="88" rows="33" id="textarea"></textarea>
</p>
<button id="button">Update</button>
<p> </p>
<p>
<label for="textarea2">
<ul>
<ul>
<li><strong>Session Message input</strong></li>
</ul>
</ul>
</label>
<textarea name="textarea2" cols="44" rows="11" id="textarea2"></textarea>
</p>
<p>
<input type="button" name="button" id="button" value="Send">
</p>
</body>
</html>
the above is the jsp for the chat page, the user should type text into textarea2 and accordingly it should appear in textarea1 if it was sent successfully, but how can i do this in order for 2 clients to talk with each other
One way to do it
You should have a servlet which has an action where the messages from both sides are posted. This servlet should hold those messsages in some kind of data structure. Now both conversation sides should poll a different action in certain time interval to check if new messages have appeared in this collection and update those text areas accordingly.
This is one of many many ways to implement your requirements.
I trying to do like this:
$("iframe.cke_dialog_ui_input_file").contents()
but it returns:
< #document(gquery, error getting the element string representation: (TypeError) #com.google.gwt.dom.client.DOMImplMozilla::toString(Lcom/google/gwt/dom/client/Element;)([JavaScript object(8570)]): doc is null)/>
But document is not null!
Help me please to solve this problem :(
UPD. HTML CODE:
<iframe id="cke_107_fileInput" class="cke_dialog_ui_input_file" frameborder="0" src="javascript:void(0)" title="Upload Image" role="presentation" allowtransparency="0">
<html lang="en" dir="ltr">
<head>
<body style="margin: 0; overflow: hidden; background: transparent;">
<form lang="en" action="gui/ckeditor/FileUploadServlet?CKEditor=gwt-uid-7&CKEditorFuncNum=0&langCode=en" dir="ltr" method="POST" enctype="multipart/form-data">
<label id="cke_106_label" style="display:none" for="cke_107_fileInput_input">Upload Image</label>
<input id="cke_107_fileInput_input" type="file" size="38" name="upload" aria-labelledby="cke_106_label">
</form>
<script>
window.parent.CKEDITOR.tools.callFunction(90);window.onbeforeunload = function() {window.parent.CKEDITOR.tools.callFunction(91)}
</script>
</body>
</html>
</iframe>
First get the iframe element using javascript like your existing cod and store it into Iframe of GWT
IFrameElement iframe = (IFrameElement) element;
Now use iframe to get content
iframe.getContentDocument().getBody().getInnerText();
Hope it help you to get values.
The contents() method returns the HTMLDocument, so normally you have to find the <body> to manipulate it.
$("iframe.cke_dialog_ui_input_file").contents().find("body");
A common mistake is to query the iframe before it has been fully loaded, so code a delay using a Timer, Scheduler or GQuery.delay(). For instance:
$("iframe.cke_dialog_ui_input_file")
.delay(100,
lazy()
.contents().find("body")
.css("font-name", "verdana")
.css("font-size", "x-small")
.done());
Is there anything wrong with my code? My if else statement is not working.
<%
String pages = request.getParameter("page");
%>
<input type="hidden" id="page" value="<%=pages%>"/>
<div class="navbar navbar-fixed-bottom">
<div class="navbar-inner">
<a class="brand" href="index.jsp">PeachMangoPie</a>
<ul class="nav pull-right">
<li <%if(pages=="papoy"){out.write("class='active' ");}%>>Papoy</li>
<li class="divider-vertical"></li>
<li <%if(pages=="chuckie"){out.write("class='active' ");}%>>Chuckie</li>
<li class="divider-vertical"></li>
<li <%if(pages=="dutchmill"){out.write("class='active' ");}%>>Dutch Mill</li>
<li class="divider-vertical"></li>
<li <%if(pages=="icecream"){out.write("class='active' ");}%>>Ice Cream</li>
<li class="divider-vertical"></li>
<li <%if(pages=="chicken"){out.write("class='active' ");}%>>Chicken</li>
<li class="divider-vertical"></li>
<li <%if(pages=="straberrycake"){out.write("class='active' ");}%>>Strawberry-Cake</li>
</ul>
</div>
</div>
You need to use the .equals method to test for string equality.
Try this instead:
<li <%if(pages.equals("papoy")){out.write("class='active' ");}%>>Papoy</li>
To fix your code: use equals to compare Strings (as shown in Harshal Pandya's answer).
To really fix your code: stop using scriptlets as explained here: How to avoid Java code in JSP files?. Rewrite all this using EL, JSTL and JavaScript. I wrote a basic example on this to omit all that hard-to-maintain scriptlet and HTML code:
<script type="text/javascript">
window.onload = function() {
var page = '<c:out value="${param.page}" />';
var ulOptions = document.getElementById('ulOptions');
var liItems = ulOptions.getElementsByTagName("li");
for(var i = 0; i < liItems.length; i++) {
var liItem = liItems[i];
var a = liItem.getElementsByTagName("a")[0];
if (a !== undefined && a.innerText.toLowerCase() === page) {
liItem.setAttribute("class", "brand");
}
}
};
</script>
<input type="hidden" id="page" value="${param.page}"/>
<div class="navbar navbar-fixed-bottom">
<div class="navbar-inner">
<a class="brand" href="index.jsp">PeachMangoPie</a>
<%--
provided id for ul HTML component in order to ease
JavaScript onload function development
--%>
<ul id="ulOptions" class="nav pull-right">
<li>Papoy</li>
<li class="divider-vertical"></li>
<li>Chuckie</li>
<li class="divider-vertical"></li>
<li>Dutch Mill</li>
<li class="divider-vertical"></li>
<li>Ice Cream</li>
<li class="divider-vertical"></li>
<li>Chicken</li>
<li class="divider-vertical"></li>
<li>Strawberry-Cake</li>
</ul>
</div>
</div>
Explanation of the provided code:
${param.page} replaces request.getParameter("page");
window.onload = function() { ... }; defining a JavaScript function to execute after loading the page (more info: onload Event).
<c:out> will print text directly on the generated HTML. More info: <c:out>.
document.getElementById returns an HTML element by its id (the function name explains this pretty straightforward).
getElementsByTagName returns a NodeList that contains all the inner HTML elements with the corresponding tag name (the function name explains this pretty straightforward).
for(var i = 0; i < liItems.length; i++) traverse all the <li> elements inside ulOptions.
liItem.getElementsByTagName("a")[0] as explained before, get the <a> element in position 0.
a !== undefined && a.innerText.toLowerCase() === page verifying that a exists (this for those <li> without the <a> element inside) and verifying the inner text against the page request parameter.
This is better approach (without scriptlets):
<li <c:out value="${param.page=='papoy'?'class=active':''}"/>">
Papoy
</li>
I have a tree generated with JSTree in my JSP page (part of a Struts2 webapp) as follows:
<div class="panel">
<div id="demo1" class="demo">
<ul>
<li id="node"><s:property value="product"/>
<ul>
<li id="node">
Dependents
<ul>
<s:iterator value="dependentsList" id="dependent">
<li id="node">
<a href="#">
<s:property value="productName"/></a>
<ul>
<li>
<a href="#">
Version Number: <s:property value="version" />
</a>
</li>
<s:if test="documentationLink != ''">
<li>
<a href="<s:property value="documentationLink" />">
Link to Product Documentation
</a>
</li>
</s:if>
</ul>
</li>
</s:iterator>
</ul>
</li>
</ul>
</li>
</ul>
</div>
<script type="text/javascript" >
$(function () {
$("#demo1").jstree(
{
"core" :
{
"initially_open" : [ "#node" ]
},
"themes" :
{
"theme" : "default",
"icons" : false
},
"plugins" : [ "themes", "html_data", "ui"]
});
});
</script>
Thing is the links to product documentation show up on my browser (I tried using both Firefox and Internet Explorer) on the bottom status bar, but when I click on them, nothing pops up (I checked my HTML source code, and the anchor tags are showing the correct URL links). Could anyone figure out why my links aren't working? I am using both the latest versions of JQuery and JSTree. Thanks!
I got the links to work after removing the UI plugin, I guess the UI plugin doesn't like to work with HTML links...