how to get body holding the content of iframe in java - java

I am working to fetch data which is under iframe tag.I want the data under body tag.But I am not getting proper output.Here is my HTML page looks like as follows:
<iframe id="sharetools-iframe" width="100%" height="100%" frameborder="0" style="z-index: 1000; position: relative; visibility: visible; " scrolling="no" allowtransparency="true" src="some url here"></iframe>
#document
<html><head><script type="text/javascript">window.WIDGET_ID = 'sharepopup';</script>
<base href="href here">
<link rel="stylesheet" href="href here">
<script src="url here"></script>
<script type="text/javascript" src="url here"></script></head>
<body>
body contents are here........
..............................
</div></div></body></html>
I have used the following code:
WebDriver webDriver = new FirefoxDriver();
webDriver.get("url to open");
String htmlPage = webDriver.getPageSource();
Tidy tidy = new Tidy();
InputStream inputStream = new ByteArrayInputStream(htmlPage.getBytes());
Document doc = tidy.parseDOM(inputStream, null);
Element element = doc.getElementById("sharetools-iframe");
Here I am getting element null.I have also type casted it as follows:
HTMLIFrameElement iframeElement = (HTMLIFrameElement) doc.getElementById("sharetools-iframe");
But getting iframeElement null.
I have also used jsoup parser as follows:
Document doc = Jsoup.parse(htmlPage);
org.jsoup.nodes.Element iframeElement= doc.getElementById("sharetools-iframe");
Here I am getting output <iframe id="sharetools-iframe" width="100%" height="100%" frameborder="0" style="z-index: 1000; position: relative; visibility: visible; " scrolling="no" allowtransparency="true" src="some url here"></iframe> as a iframeElement but not getting body content.
Please guide me how to fetch body content of iframe.

You need to switch to iframe and then you can interact with content.
For example to get body:
driver.switchTo().frame(driver.findElement(By.id("sharetools-iframe"))).findElement(By.tagName("body"));

Related

How to open documents in html(inside iframe or div) by passing document path

I have a requirement in my application like,I need to open files(pdf,docx,pptx..)with in html(embedding into div or iframe) by passing document paths(urls) on click of a button.
I have tried opening the documents outside the application and its working,But I am stuck on hw to approach the above problem.
Thanks.
You can have a iframe inside a div and o0pen the document in that iframe element as follows:
<div>
<iframe src="" id="iframeRight" style="width:600px; height:500px;" frameborder="0">
</iframe>
</div>
In the controller, on click of button you can assign the base64 string of the document to iframe src as follows:
document.getElementById("iframeRight").src = base64String;
Just ensure that the base64 string has the metadata attached to it like for pdf it must start as:
data:application/pdf;base64,
PFB a demo program that lets user select the document and displays the same in the iframe. Copy paste in notepad and run this as html file. Select a doc less than 5 mb in size.
<!DOCTYPE html>
<html>
<body>
<input type="file" id="file-uploadUC" />
<iframe src="demo_iframe.htm" id="ifrm" height="200" width="300"></iframe>
<script>
document.getElementById("file-uploadUC").addEventListener("change", rdfile);
function rdfile() {
extn = '';
FileContentBase64 = '';
FileName = '';
if (this.files && this.files[0]) {
if (this.files[0].size <= 5347738) {
var FR = new FileReader();
FileName = this.files[0].name;
extn = FileName.split(".").pop();
FR.onload = function (e) {
FileContentBase64 = e.target.result;
document.getElementById("ifrm").src = FileContentBase64;
};
FR.readAsDataURL(this.files[0]);
}
else {
}
}
else {
}
}
</script>
</body>
</html>

Webpage element seems to be invisible to Selenium

I'm trying to click/sendKeys to a button labelled Browse on a webpage, and no matter what I try, Selenium fails to find it.
Using Selenium's IDE, I can gather the following information:
id=uploadField
name=uploadField
css=#uploadField
dom:name = document.uploadForm.uploadField
xpath:attributes = //input[#id='uploadField']
xpath:idRelative = //div[#id='browseBtnContainer']/form/input[4]
dom:index = document.uploadForm.elements[3]
xpath:position = //input[4]
And I've tried all of the following By. sequences, all of which throw a NoSuchElementException. There is only one iframe and I tried to switch to iframe but it didn't work.
WebElement browse = driver.findElement(By.id("uploadField"));
WebElement browse1 = driver.findElement(By.name("uploadField"));
WebElement browse2 = driver.findElement(By.cssSelector("#uploadField"));
WebElement browse3 = driver.findElement(By.cssSelector("uploadField")); // just in case
WebElement browse4 = driver.findElement(By.xpath("uploadField")); // attributes
WebElement browse5 = driver.findElement(By.xpath("//div[#id='browseBtnContainer']/form/input[4]")); // idrelative
WebElement browse6 = driver.findElement(By.xpath("//input[4]")); // position
The container portion of the code confuses me. I don't know how to access the elements in a container, and anything I find on google just tells me to use the xpath, of which I can't seem to find.
Am I using the By.xpath incorrectly? How can I generate a list of every single element on the webpage?
Here is the relevant HTML source code:
<div id="ext-comp-1022" class=" x-panel x-border-panel" style="left: 0px; top: 0px; width: 1077px;">
<div id="ext-gen27" class="x-panel-bwrap">
<div id="ext-gen28" class="x-panel-body x-panel-body-noheader" style="overflow: auto; width: 1075px; height: 502px;">
<div id="ext-comp-1023" class=" x-panel x-panel-noborder">
<div id="stepOnePanel"/>
<div id="stepTwoPanel"/>
<div id="stepThreePanel"/>
<div id="stepOnePanel" class="step-container" style="margin:20px 20px 20px 30px;">
<div class="step-title" style="background-color:transparent;background-repeat:no-repeat;background-position:top left;background-image:url(/assets/icons/medium/icon-1.png );padding:12px 0px 0px 50px;height:30px;font-weight:bold;">Start by selecting the ZIP file which contains your images (20MB max)</div>
<div id="ext-gen71" style="padding-left:70px;overflow:auto;">
<div id="ext-comp-1024" class=" x-panel x-panel-noborder">
<div id="ext-gen74" class="x-panel-bwrap">
<div id="ext-gen75" class="x-panel-body x-panel-body-noheader x-panel-body-noborder">
<div style="padding-top:2px">
<div id="browseBtnContainer" style="float:left;width:85px;margin-top:-2px">
<table id="browseBtn" class="x-btn stepBtn x-btn-noicon x-btn-over" cellspacing="0" style="width: 79px;">
<form enctype="multipart/form-data" target="hiddenUploadFrame" method="post" action="/uploader/upload?actingAsUserId=pleach&currentAccountId=bmwofreading&uploadAccountId=bmwofreading&ccmode=multiwindow" name="uploadForm">
<input id="doNotResize" type="checkbox" style="display:none" value="true" name="doNotResize"/>
<input id="pdfConvert" type="checkbox" style="display:none" value="true" name="pdfConvert"/>
<input type="hidden" value="false" name="previewNeeded"/>
<input id="uploadField" type="file" size="1" style="position: absolute; top: 0px; left: -19px; opacity: 0; cursor: pointer; height: 22px;" name="uploadField"/>
You need to switch to the frame in order to interact with the elements in it
driver.switchTo.frame("id"); //using the frame id attribute
// or
driver.switchTo.frame("name"); //using the frame name attribute
// or
WebElement frame = driver.findElement(...);
driver.switchTo.frame(frame); //using the frame as WebElement
And to switch back
driver.switchTo().defaultContent();
Try following method.
driver.findElement(By.xpath("//input[#id='uploadField']")).click();
As per provided HTML, we can try directly by using id or name. If you are looking for xpath only, then try below relative xpath
//input[#id='uploadField']
If directly click does not works then try with Actions. First move to element then try to click. i hope this way helps and works good for me on most of cases
Actions move=new Actions(driver);
move.moveToElement(driver.findElement(By.xpath("//input[#id='uploadField']"))).click().build().perform();
finally you can try by using javascript executor
WebElement element = driver.findElement(By.id("uploadField"));
JavascriptExecutor executor = (JavascriptExecutor)driver;
executor.executeScript("arguments[0].click();", element);
Thank You,
Murali

Nested html not being parsed by Jsoup

I'm trying to parse a page with Jsoup, but the html doesn't seem to be parsing correctly.
The general structure is:
<html>
<head> ... </head>
<frameset ...>
<frame ...>
#document
<html> ... </html>
</frame>
</frameset>
</html>
When I parse the html and print it with Document doc = Jsoup.parse(html); System.out.println(doc.html()); it prints out the outer html (including #document, but not the frames or inner html).
Does anyone know how to get the inner html with Jsoup, or should I consider using a different library?
Thanks.
Edit: Here's the site I'm parsing. I have a subscription to it; don't know if it'll let any of you in.
http://database.asahi.com/library2/login/login.php
After authentication, it will take you to: http://database.asahi.com/library2/main/start.php
Edit 2:
<html>
<head></head>
<frameset rows="58,*" border="0">
<frame name="Header"> </frame>
<frame name="Introduce">
#document
<html>
<head>hello</head>
<body>hello again</body>
</html>
</frame>
</frameset>
</html>
Then I run:
Document doc = Jsoup.parse(html);
Elements elems = doc.select("frameset > frame:last-child");
// print(elems);
switch(elems.size()) {
case 0: break;
case 1: doc = Jsoup.connect(elems.first().attr("src")).get(); break;
default: break;
}
System.out.println(doc.html());
The parsed html (doc.html()):
<html>
<head></head>
<body>
 #document hello hello again
</body>
</html>
So it's not even finding <frameset>
Any ideas?
Here is how to parse the nested html:
// Fetch the page with frameset
Document doc = Jsoup
.connect("http://database.asahi.com/library2/login/login.php")
.get(); // Add login, password etc
// Determine the frame url you want to parse...
// Note: I assume you want to parse the content of the first frame
Elements elts = doc.select("frameset > frame:first-child");
switch (elts.size()) {
case 0:
// No frame found ...
break;
case 1:
Element frameElt = elts.first();
Document frameDoc = Jsoup
.connect(frameElt.attr("src"))
.get();
// Add the frameDoc nodes to doc (via frameElt#insertChildren)
frameElt.insertChildren(0, frameDoc.childNodes());
break;
default:
// Strange result...
}
System.out.println(doc.html());

How to inject snippets of html into an string containing valid html?

I have the following html (sized down for literary content) that is passed into a java method.
However, I want to take this passed in html string and add a <pre> tag that contains some text passed in and add a section of <script type="text/javascript"> to the head.
String buildHTML(String htmlString, String textToInject)
{
// Inject inject textToInject into pre tag and add javascript sections
String newHTMLString = <build new html sections>
}
-- htmlString --
<html>
<head>
</head>
<body>
<body>
</html>
-- newHTMLString
<html>
<head>
<script type="text/javascript">
window.onload=function(){alert("hello?";}
</script>
</head>
<body>
<div id="1">
<pre>
<!-- Inject textToInject here into a newly created pre tag-->
</pre>
</div>
<body>
</html>
What is the best tool to do this from within java other than a regex?
Here's how to do this with Jsoup:
public String buildHTML(String htmlString, String textToInject)
{
// Create a document from string
Document doc = Jsoup.parse(htmlString);
// create the script tag in head
doc.head().appendElement("script")
.attr("type", "text/javascript")
.text("window.onload=function(){alert(\'hello?\';}");
// Create div tag
Element div = doc.body().appendElement("div").attr("id", "1");
// Create pre tag
Element pre = div.appendElement("pre");
pre.text(textToInject);
// Return as string
return doc.toString();
}
I've used chaining a lot, what means:
doc.body().appendElement(...).attr(...).text(...)
is exactly the same as
Element example = doc.body().appendElement(...);
example.attr(...);
example.text(...);
Example:
final String html = "<html>\n"
+ " <head>\n"
+ " </head>\n"
+ " <body>\n"
+ " <body>\n"
+ "</html>";
String result = buildHTML(html, "This is a test.");
System.out.println(result);
Result:
<html>
<head>
<script type="text/javascript">window.onload=function(){alert('hello?';}</script>
</head>
<body>
<div id="1">
<pre>This is a test.</pre>
</div>
</body>
</html>

on click show Iframe

I have a map that you can click on locations to get information for that area and I would like to show that information in a Iframe on the same page when clicked
My page has this for the link now
`<AREA SHAPE="CIRCLE" COORDS="555,142,6" HREF="http://www.Page.com" TITLE="" />`
Any suggestions
The beauty of AJAX is that you don't really need an IFRAME to do this.
You've got a server that will return to you information about a certain area. Each of the AREA tags simply needs an onclick attribute that calls a JavaScript function to retrieve that information and display it in a location you set aside on your page.
Here is a sample HTML page that will retrieve information from the server using AJAX
<html>
<head>
<script type="text/javascript">
function getAreaInfo(id)
{
var infoBox = document.getElementById("infoBox");
if (infoBox == null) return true;
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function() {
if (xhr.readyState != 4) return;
if (xhr.status != 200) alert(xhr.status);
infoBox.innerHTML = xhr.responseText;
};
xhr.open("GET", "info.php?id=" + id, true);
xhr.send(null);
return false;
}
</script>
<style type="text/css">
#infoBox {
border:1px solid #777;
height: 400px;
width: 400px;
}
</style>
</head>
<body onload="">
<p>AJAX Test</p>
<p>Click a link...
Area One
Area Two
Area Three
</p>
<p>Here is where the information will go.</p>
<div id="infoBox"> </div>
</body>
</html>
And here is the info.php that returns the information back to the HTML page:
<?php
$id = $_GET["id"];
echo "You asked for information about area #{$id}. A real application would look something up in a database and format that information using XML or JSON.";
?>
Hope this helps!

Categories

Resources