Requesting help specifying which element to interact with. (Java w/Selenium) - java

The code from the page is as follows:
<td align="center" width="50%">
<input type="button" id="M_860735" value="Continue" class="entereclass" style="background-image: initial; background-attachment: initial; background-origin: initial; background-clip: initial; background-color: rgb(244, 244, 244); width: 100px; visibility: hidden; background-position: initial initial; background-repeat: initial initial; " onclick="this.disabled= true; this.value='Loading...'; M_3275409(1);"><br>
<input type="button" id="M_1723091" value="Continue" class="enterclass" style="background: #F4F4F4; width: 100px; margin-top: 3px; visibility: hidden;" onclick=" this.disabled= true; this.value='Loading...'; M_3275409(2);">
</td>
<td align="center" width="50%">
<input type="button" id="M_2802510" value="Continue" class="enterclass" style="background: #F4F4F4; width: 100px; visibility: hidden;" onclick="this.disabled= true; this.value='Loading...'; M_3275409(3);"><br>
<input type="button" id="M_1860441" value="Continue" class="enterclass" style="background-image: initial; background-attachment: initial; background-origin:n initial; background-clip: initial; background-color: rgb(244, 244, 244); width: 100px; margin-top: 3px; visibility: visible; background-position: initial initial; background-repeat: initial initial; " onclick="this.disabled= true; this.value='Loading...'; M_3275409(4);">
</td>
I would like to be able to take each element and store the four IDs in temp variables to be used with each time I try to click.
(The ID's for the buttons are randomly generated, and the class of them cycle through three different choices ["enterclass", "forward", and "inputsubmit"])
All that I do to go through each of the classes and click the button when logging in is:
try{ driver.findElement(By.ByClassName.ByClass("enterclass")).click(); } catch {exception e {}
Then change the "enterclass" to the other options, and paste.
But I cannot do this here, as they are all the same.
Maybe instead of getting the IDs each time, I could have the program recognize that there are four, and try a click on each one?
(Again, not sure how to do that either, lol)
I am still new to Java, so I don't quite know the most proficient ways to do these things.
If anyone can help me, a reply would be greatly appreciated. ^_^
Thanks!
~ Ben King of Moria
UPDATE:
Fail...I figured it out. :P
I just did:
try{
driver.findElement(By.xpath("/html/body/div/div/table/tbody/tr/td[2]/div[2]/center/table[13]/tbody/tr[3]/td/table/tbody/tr/td/input")).click();
} catch(Exception e){}
try{
driver.findElement(By.xpath("/html/body/div/div/table/tbody/tr/td[2]/div[2]/center/table[13]/tbody/tr[3]/td/table/tbody/tr/td/input[2]")).click();
} catch(Exception e){}
try{
driver.findElement(By.xpath("/html/body/div/div/table/tbody/tr/td[2]/div[2]/center/table[13]/tbody/tr[3]/td/table/tbody/tr/td[2]/input")).click();
} catch(Exception e){}
try{
driver.findElement(By.xpath("/html/body/div/div/table/tbody/tr/td[2]/div[2]/center/table[13]/tbody/tr[3]/td/table/tbody/tr/td[2]/input[2]")).click();
} catch(Exception e){}

That is a very long xpath. I would suggest instead getting all the 'input' elements on the page by using 'FindElements' instead of 'findElement' and then filtering through those by accessing their id's and such. Eg.
elements = driver.findElements(By.xpath("/input");
foreach(IWebElement e in elements)
{
sting class = elements[0].getAttribute("class");
if (class == "whatever")
;//do your stuff! :)
}
Outside of the xpath just looking ridiculously long, this is very unmaintainable. If there was to be even a slight UI change on the page your xpath could easily become incorrect. IMHO, it's better to get a subset of the pages elements and then sift through them logically. However, if it works it works! :)

Related

Simple way to display currency symbol in html2pdf for iText 7

I updated my code from iText 5.0 to iText 7 and html2pdf 2.0 according to this post. In earlier version rupee symbol was rendering properly, but because of css issue i changed the code. Now complete page is converting properly to pdf except rupee symbol.
Tried adding font in html style tag itself like * { font-family: Arial; }.
Changed value of rupee symbol from &#x20b9, ₹ and also added directly ₹ , but no use.
My Html:
<html>
<head>
<style>
* { font-family: Arial; }
</style>
<title>HTML div</title>
</head>
<body>
<p style="margin-bottom: 0in; padding-left: 60px;">
<div style="font-size: 450%; text-indent: 150px;">
<strong>BUY <span style="color: #ff420e;">2</span> GET
</strong>
</div>
</p>
<div
style="float: left; display: inline-block; margin: 10px; text-align: right; font-size: 70%; line-height: 27; transform: rotate(270deg);">Offer
Expiry Date : 30/11/2017</Div>
<div
style="float: left; display: inline-block; margin: 10px; text-align: right; font-size: 350%;">
₹
<!-- ₹ -->
</div>
<div
style="float: left; display: inline-block; margin: auto; font-size: 1500%; color: red; font-weight: bold;">99</div>
<div
style="float: left; display: inline-block; margin: 10px; text-align: left; font-size: 250%; line-height: 10;">OFF</div>
<div
style="position: absolute; height: 40px; font-size: 250%; line-height: 600px; color: red; text-indent: 50px">Pepsi
2.25 Pet Bottle ltr</div>
<div
style="position: absolute; height: 40px; font-size: 245%; line-height: 694px; text-indent: 50px">
MRP: ₹ <span style="color: #ff420e;">654</span>
</div>
</body>
</html>
Java Code :
public class Test {
final static String DEST = "D://Workspace_1574973//POP//sample_12.pdf";
final static String SRC = "D://Workspace_1574973//POP//src//com//resources//test.html";
public static void main(String[] args) throws Exception {
createPdf(SRC, DEST);
}
public static void createPdf(String src, String dest) throws IOException {
HtmlConverter.convertToPdf(new File(src), new File(dest));
}
}
Earlier code, which was working with symbols.
log.info("Creating file start");
OutputStream file = new FileOutputStream(new File("font_check.pdf"));
Document document = new Document(PageSize.A4);
PdfWriter writer = PdfWriter.getInstance(document, file);
document.open();
InputStream is = new ByteArrayInputStream(fileTemplate.getBytes());
XMLWorkerHelper.getInstance().parseXHtml(writer, document, is);
document.close();
file.close();
log.info("Creating file end");
Is there any simple approach to achieve this, with minimal and optimized code ?
Because I've to generate thousands of pdf in one go, So the performance should not affect.
Please let me know, if anyone achieved this through latest version.
Edit : Also how to set particular paper type in this like A6, A3, A4 etc.
Hope you are not mad, because I don't have reputation to write simple comments... so I'll post a full answer instead. I parse HTML for my work, and I read SO sometimes. There is a lot on the subject regarding UTF-8 here. Most software systems support the "greater than char #256" (UTF-8) codes - for instance the Indian Rupee Symbol. However, most of the time the programmer has to include a specific request for such a desired behavior, explicitly.
In HTML, for instance - adding this line usually helps:
String UTF8MetaTag = "<meta http-equiv='Content-Type' content='text/html; charset=utf-8' />";
Anyway, not having used HTMLToPDF - I might not be the right guy to post answers to your questions - but, because I have dealt with UTF-8 foreign language characters for three years, I know that setting a software setting to handle the 65,000 or so chars is usually VERY EASY, BUT ALSO ALWAYS VERY MANDATORY.
Here is an SO post about using HTMLToPDF and UTF-8 to handle Japanese Kanji characters. Most likely, it should handle all UTF-8, but that is not a guarantee.
HTML2PDF support for japanese language(utf8) is not working
Here are a few posts about it using HTML2PDF in PHP:
Converting html 2 pdf (php) using hebrew returns "???"
Having æøå chars in HTML2PDF charset

INPUT box-sizing border-box with 100% height and width inside TD issue in Chrome

I found a nearly identical case to mine here. But the accepted answer does not work for me so I hope it's OK that I make a new question.
The pic below is what I want to achieve in all major browsers (at least IE8+, Firefox and Chrome). INPUTs placed inside TDs fills their parents both width and height.
My issue is that I can't get it done in Chrome with below code snippet. Thanks in advance
UPDATE: My issue on Chrome explained:
If you take a closer look, there's 1 or 2px padding at top and bottom border. This is me on Chrome Version 47.0.2526.111 m on Windows 7 (Please open in new windows to see clearer)
UPDATE2: Big mistake on the sample. DIVs adapt their parent just fine without using the box-sizing. What I actually want is the INPUT to adapt their parent as well. Just updated my code snippet again.
table {
border-collapse: collapse;
width: 100%
}
td {
height: 100px;
border: 1px #ccc solid;
}
input {
border: 1px #ccc solid;
height: 100%;
width: 100%;
box-sizing: border-box; /* works fine with IE8+ */
-moz-box-sizing: border-box; /* works fine Firefox */
-webkit-box-sizing: border-box; /* height is not correct in Chrome */
/*-webkit-box-sizing: content-box; width is not correct in Chrome */
}
<table>
<tr>
<td>
<input type="text" value="this INPUT need to adapt to its parent TD">
</td>
</tr>
</table>
This is an odd one, but I think what you are seeing is a td with a fixed height of 100px, and border widths on top and bottom of 1px throwing off the child divs height 100% calculation.
Would it be possible to assign the height to the div instead of the td like below? This works for me in chrome.
table {
border-collapse: collapse;
width: 100%
}
td {
border: 1px #ccc solid;
}
div {
border: 1px #ccc solid;
height: 100px;
width: 100%;
box-sizing: border-box; /* works fine with IE8+ */
-moz-box-sizing: border-box; /* works fine Firefox */
-webkit-box-sizing: border-box; /* height is not correct in Chrome */
/*-webkit-box-sizing: content-box; width is not correct in Chrome */
}
<table>
<tr>
<td>
<div>BOX1</div>
</td>
<td>
<div>BOX2</div>
</td>
<td>
<div>BOX3</div>
</td>
</tr>
</table>
why not use simple css layouts rather than doing an over kill with tables?
Fiddle
html,
body {
width: 100%;
height: 100%;
margin: 0;
padding: 0;
}
.container {
width: 100%;
}
.padding {
height: 100px;
}
.outer_border {
padding: 1px;
border: 1px solid black;
}
input {
border: 1px black solid;
height: 100%;
width: 100%;
box-sizing: border-box;
-moz-box-sizing: border-box;
-webkit-box-sizing: border-box;
}
HTML
<div class="container">
<div class="outer_border">
<div class="padding">
<input type="text" value="this INPUT need to adapt to its parent TD">
</div>
</div>
</div>
I'm actually looking for the answer to this question for quite a time now (since 2014). Lying around the internet are some post say that this is a bug of Chromium. I managed to recall a link here. Nonetheless, I doubt there will be answer soon.
Meanwhile, I would like to propose a quick and dirty fix for anyone who got in the same problem as me: For chrome, wrap all the INPUTs inside a DIV.
$(function() {
// if agent is of Chrome
var isChrome = /chrom(e|ium)/.test(navigator.userAgent.toLowerCase());
if (isChrome) {
$("table td>:input").wrap($("<div>", {"class": "input-container"}));
}
});
table {
border-collapse: collapse;
width: 100%
}
td {
height: 100px;
border: 1px #ccc solid;
}
input {
border: 1px #ccc solid;
height: 100%;
width: 100%;
box-sizing: border-box; /* works fine with IE8+ */
-moz-box-sizing: border-box; /* works fine Firefox */
/*-webkit-box-sizing: border-box; height is not correct in Chrome
*-webkit-box-sizing: content-box; width is not correct in Chrome */
}
div.input-container {
height: 100%;
width: 100%;
-webkit-box-sizing: border-box;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table>
<tr>
<td>
<input type="text" value="this INPUT need to adapt to its parent TD">
</td>
</tr>
</table>

Selenium WebDriver Java - Clicking on element by label not working on certain labels

I am trying to click on element by the label. Here is the code I am using:
driver.findElement(By.xpath("id(//label[text() = 'LABEL TEXT HERE']/#for)")).click();
It works for (Select All) & Hayward but cant find Los Angeles, San Fran, or San Jose.
UPDATE:
For now I guess this may be my best option until I see something better. This will allow the user to pass the full String and the function in the method will grab the last word of the string and insert it into the contains xpath.
public void subStringLocationTest(String location) {
String par = location.substring(location.lastIndexOf(" ") + 1);
driver.findElement(By.xpath("//label[contains(text(), '" + par + "')]")).click();
}
Here is the HTML code:
<div id="ReportViewer1_ctl04_ctl03_divDropDown" onclick="event.cancelBubble=true;" onactivate="event.cancelBubble=true;" style="border: 1px solid rgb(169, 169, 169); font-family: Verdana; font-size: 8pt; overflow: auto; background-color: window; display: inline; position: absolute; z-index: 11; left: 131px; top: 41px; width: 188px;">
<span><table cellpadding="0" cellspacing="0" style="background-color:window;">
<tbody><tr>
<td nowrap="nowrap"><span style="font-family:Verdana;font-size:8pt;"><input id="ReportViewer1_ctl04_ctl03_divDropDown_ctl00" type="checkbox" name="ReportViewer1$ctl04$ctl03$divDropDown$ctl00" onclick="$get('ReportViewer1_ctl04_ctl03').control.OnSelectAllClick(this);"><label for="ReportViewer1_ctl04_ctl03_divDropDown_ctl00">(Select All)</label></span></td>
</tr><tr>
<td nowrap="nowrap"><span style="font-family:Verdana;font-size:8pt;"><input id="ReportViewer1_ctl04_ctl03_divDropDown_ctl02" type="checkbox" name="ReportViewer1$ctl04$ctl03$divDropDown$ctl02" onclick="$get('ReportViewer1_ctl04_ctl03').control.OnValidValueClick(this, 'ReportViewer1_ctl04_ctl03_divDropDown_ctl00');"><label for="ReportViewer1_ctl04_ctl03_divDropDown_ctl02">Hayward</label></span></td>
</tr><tr>
<td nowrap="nowrap"><span style="font-family:Verdana;font-size:8pt;"><input id="ReportViewer1_ctl04_ctl03_divDropDown_ctl03" type="checkbox" name="ReportViewer1$ctl04$ctl03$divDropDown$ctl03" onclick="$get('ReportViewer1_ctl04_ctl03').control.OnValidValueClick(this, 'ReportViewer1_ctl04_ctl03_divDropDown_ctl00');"><label for="ReportViewer1_ctl04_ctl03_divDropDown_ctl03">Los Angeles</label></span></td>
</tr><tr>
<td nowrap="nowrap"><span style="font-family:Verdana;font-size:8pt;"><input id="ReportViewer1_ctl04_ctl03_divDropDown_ctl04" type="checkbox" name="ReportViewer1$ctl04$ctl03$divDropDown$ctl04" onclick="$get('ReportViewer1_ctl04_ctl03').control.OnValidValueClick(this, 'ReportViewer1_ctl04_ctl03_divDropDown_ctl00');"><label for="ReportViewer1_ctl04_ctl03_divDropDown_ctl04">San Francisco</label></span></td>
</tr><tr>
<td nowrap="nowrap"><span style="font-family:Verdana;font-size:8pt;"><input id="ReportViewer1_ctl04_ctl03_divDropDown_ctl05" type="checkbox" name="ReportViewer1$ctl04$ctl03$divDropDown$ctl05" onclick="$get('ReportViewer1_ctl04_ctl03').control.OnValidValueClick(this, 'ReportViewer1_ctl04_ctl03_divDropDown_ctl00');"><label for="ReportViewer1_ctl04_ctl03_divDropDown_ctl05">San Jose</label></span></td>
</tr>
</tbody></table><input type="hidden" name="ReportViewer1$ctl04$ctl03$divDropDown$ctl01$HiddenIndices" id="ReportViewer1_ctl04_ctl03_divDropDown_ctl01_HiddenIndices" value=""></span>
</div>
You can use xpath locater. For example:
d.findElement(By.xpath("//...../label[contains(#for,'ReportViewer1_ctl04_ctl03_divDropDown_ctl02')]")).click();
Use following xpaths :
//label[text()='(Select All)']
//label[text()='Hayward']
//label[text()='Los Angeles']
//label[text()='San Francisco']
//label[text()='San Jose']
You can also do a contains like this:
"//label[contains(text(), 'TEXT_TO_FIND')]"
Try to use id instead of xpath:
//for Select All
driver.findElement(By.id("ReportViewer1_ctl04_ctl03_divDropDown_ctl00")).click();
//for Hayward
driver.findElement(By.id("ReportViewer1_ctl04_ctl03_divDropDown_ctl02")).click();
//for Los Angeles
driver.findElement(By.id("ReportViewer1_ctl04_ctl03_divDropDown_ctl03")).click();
//for San Francisco
driver.findElement(By.id("ReportViewer1_ctl04_ctl03_divDropDown_ctl04")).click();
//for San Jose
driver.findElement(By.id("ReportViewer1_ctl04_ctl03_divDropDown_ctl05")).click();
If still have problem or id is changing dynamically you cane use xpath like:
//label[contains(.,'(Select All)')]
//label[contains(.,'Hayward')]
//label[contains(.,'Los Angeles')]
//label[contains(.,'San Francisco')]
//label[contains(.,'San Jose')]
driver.findElement(By.xpath("//label[text()='LABEL TEXT']/../input")).click();
Try CSS:
driver.findElement(By.CSS("label:contains('Partial or full text')");
try this, maybe good startpoint:
System.out.print(driver.findElement(By.xpath("//div[#id='ReportViewer1_ctl04_ctl03_divDropDown']/span/table/tbody/tr[" + i +"]/td/span/label")).getText());
driver.findElement(By.xpath("//div[#id='ReportViewer1_ctl04_ctl03_divDropDown']/span/table/tbody/tr[" + i +"]/td/span/label")).click();
i = 3; //Los Angeles
i = 4; //San Francisco
I hope, my xpath is correct.
Use below code to click on label or choose label
driver.findElement(By.xpath("//label[#for='your id which you want to click']")).click();

Regarding the Link / text / image that stays static even when the webpage is scrolled

are there any Java script or any sample available for the Link / text / image that stays static even when the webpage is scrolled.
I am looking for something similar to the one on the bottom left side of the webpage borders(Helpful?, "Yes", "No").
http://www.ehow.com/facebook-for-business/
Regards,
Gourav
Try this code this may help you. but this code required lot more css and javascript code to make this same as ehow.
<style>
.mainDiv {
height: 1000px;
border: solid 1px #000000;
}
.fixDiv {
height: 250px;
width: 20px;
border: solid 1px #000000;
position: fixed;
margin-top: 200px;
}
</style>
<html>
<body>
<div class="fixDiv">h e l p f u l l? Yes No</div>
<div class="mainDiv">Gaurav</div>
</body>
</html>
This can be done using simple css
create a style for div with id="poll" and give this style
div#poll {
position: fixed;
left: 0;
top: 100px;
}
<div id="poll">
<img src="image.jpg" alt="image" class="contimage" border="0"/></div>
This div will be shown in the left side of the window

Creating CSS from a HTML file

I have an html file which contains many elements:
<div>
<div id="imgElt11289447233738dIi15v" style="BORDER-RIGHT: 0px; BORDER-TOP: 0px; Z-INDEX: 1; LEFT: 795px; BORDER-LEFT: 0px; WIDTH: 90px; CURSOR: auto; BORDER-BOTTOM: 0px; POSITION: absolute; TOP: 186px; HEIGHT: 93px" lineid="lineid" y2="279" y1="186" x2="885" x1="795">
<img style="WIDTH: 90px; HEIGHT: 93px" height="21" alt="Image" src="../images//k03.jpg" width="25" name="imgElt11289447233738dIi15vNI1m6G" tag="img"></img></div>
<div id="imgElt11288263284216dIi15v" style="BORDER-RIGHT: 0px; BORDER-TOP: 0px; Z-INDEX: 1; LEFT: 660px; BORDER-LEFT: 0px; WIDTH: 147px; CURSOR: auto; BORDER-BOTTOM: 0px; POSITION: absolute; TOP: 1964px; HEIGHT: 22px" lineid="lineid" y2="1986" y1="1964" x2="807" x1="660">
<img style="WIDTH: 147px; HEIGHT: 22px" height="21" alt="Image" src="../images//k03.jpg" width="25" name="imgElt11288263284216dIi15vNI1m6G" tag="img"></img></div>
<div id="txtElt11288262779851dIi15v" style="BORDER-RIGHT: 0px; BORDER-TOP: 0px; Z-INDEX: 2872735; LEFT: 250px; BORDER-LEFT: 0px; WIDTH: 95px; CURSOR: auto; BORDER-BOTTOM: 0px; POSITION: absolute; TOP: 1514px; HEIGHT: 18px" selectedindex="0" pos_rel="false" lineid="lineid" y2="1532" y1="1514" x2="345" x1="250" tag="div">
<p><strong><font face="arial,helvetica,sans-serif" size="2">Course Name</font></strong></p>
</div>
<div id="txtElt11288262309675dIi15v" style="BORDER-RIGHT: 0px; BORDER-TOP: 0px; Z-INDEX: 1565881; LEFT: 40px; BORDER-LEFT: 0px; WIDTH: 430px; CURSOR: auto; BORDER-BOTTOM: 0px; POSITION: absolute; TOP: 1464px; HEIGHT: 34px" selectedindex="0" pos_rel="false" lineid="lineid" y2="1498" y1="1464" x2="470" x1="40" tag="div">
<p><strong>
<font face="arial,helvetica,sans-serif" size="2" tag="font">16. Please
write below the Course Name in order of preference.</font></strong></p>
<p tag="p"><strong><font face="Arial" size="2" tag="font"> (Please
see the "Instructions to Candidate" for list of courses)</font></strong></p>
</div>
</div>
As can be seen, 1 div has many divs in it. Now I want to create a css file that will contain all the styling of this html page (need not be same). Have to write something in java code. I have the DOM object of this file available to me.
Basically, I want all the styles to be removed from here and will be kept under a CSS file like for div with id = imgElt11289447233738dIi15v css will be:
#imgElt11289447233738dIi15v{BORDER-RIGHT: 0px; BORDER-TOP: 0px; Z-INDEX: 1; LEFT: 795px; BORDER-LEFT: 0px; WIDTH: 90px; CURSOR: auto; BORDER-BOTTOM: 0px; POSITION: absolute; TOP: 186px; HEIGHT: 93px}
I am don't till this part but since I don't know how many levels of hierarchy of elements will be there is there any way to do the same for all child elements as well?
I used the following code
public static Document getStyleInCSSfile(Document aoDoc, String aoPathToWrite, String aoFileName) throws ApplicationException {
String loValue = null;
String loID = null;
String lsContent = "";
Element loRoot = aoDoc.getRootElement();
List loTempElementList = loRoot.getChildren();
int liCounter;
for (liCounter = 0; liCounter < loTempElementList.size(); liCounter++) {
Element loTemplateEle = (Element) loTempElementList.get(liCounter);
String loId=loTemplateEle.getAttribute("id").getValue();
loID = loTemplateEle.getAttributeValue("id");
if(null != loID)
{
loValue = loTemplateEle.getAttributeValue("style");
if(loValue!=null && loValue.trim().length()>0)
{
loTemplateEle.removeAttribute("style");
lsContent = lsContent.concat("#"+loID+"{"+loValue+"}\n");
}
}
}
SaveFormOnLocalUtil.writeToFile(aoPathToWrite,aoFileName,lsContent);
return aoDoc;
}
Edit : got to know that some regular expression may help by getting a string of SAX parser object and and using regular expression on it... any idea? any one? how to implement it
is it effective to define a style for each single tag?
if i were you i'd checked if any other tag has the same style and if all elements with one style had the same 'tag_name' i'd used the following:
tag_name{text-transform:uppercase;text-align:center;}
and every element with this tag name (if its' style isn't set in any other way) would have this style.
if there's a lot of different tags with the same style:
.class_name{text-transform:uppercase;text-align:center;}
<tag class="class_name">content</tag>
I think you should use SAX instead of DOM. In SAX you can register the handler that is called every time the parser sees new tag, attribute etc. In this case every time you see attribute "style" you should extract its value to CSS file.
The next approach is using Digester from jakarta.apache.org. It uses SAX and allows XML configuration (see DigesterDigester) that maps your value object directly yo your XML document.
Absolutely different solution may made using unix shell commands like grep and sed. The preference to one of the solution depends on your system requirements and how often do you have to run this code. If it is one time transformation use unix shell scripting. If it must be something robust and change the pages on the fly use java solution.

Categories