I am using firebug to inspect the xpath, one block of firebug shows the element your finding is in window or iframe and so on. I am facing similar kind of problem where it shows me 2 options
1: Top window
2: iframe#mainframe
now the problem is,when i inspect the element it shows in iframe#mainFrame, i tried switching the driver control from main window to iframe and detect the element using webdriver but it didn't work for me,I wrote the following set of code:
driver.switchTo().frame("mainFrame");
driver.findElement(By.xpath("//div[#class='div_img']/img[#src='http://ser/themes/20/3/Flor/CF.jpg']")).click();
Note: when i checked the iframe in the html code,it doesn't contain another document inside it, It only contains id and other style and all and src tag.
Kindly suggest if there is some other way through which i can detect the element.
There are various ways to switch to iframe like using frame id, name, index and through webElement.
Might be in your case, there might be no iframe id or name. Best way is to create an xpath that uniquely identifies the iframe, create a webelement using this xpath and pass this webelement to switch frame. This is more reliable.
Suppose you have markup like below:-
<div id='noticeRichText'>
<iframe height="83px" frameborder="0" width="100%" scrolling="NO" '1331808552380'"="" +="" src="initialize.do?init=header&cacheBuster=" marginheight="0" marginwidth="0">
</div>
Create a WebElement for iframe:-
WebElement iframe=
driver.findElement(By.xpath("//*[#id='noticeRichText']/iframe"));
Switch to frame using above webelement:-
driver.switchTo().frame(iframe);
Perform the required actions on frame and then switch back to parent window using:-
driver.switchTo().defaultContent();
for the window handling you can use this...
String baseWindow = driver.getWindowHandle();
driver.switchTo().window(baseWindow);
Related
I am trying to select an element which resides inside an iframe and probably in other iframes.
Is it somehow possible to select an element within some (sub-)iframe in (python)selenium without selecting the iframes before? Is there a way to 'loop' over every iframe somehow and to check where to find my element...?
And how to do that in the case elements and html stuff and iframes might just about being loaded...?
No, it is not possible to interact with any WebElement within an <iframe> through Selenium without switching to the respective iframe.
Reason :
When a page is loaded, Selenium's focus by default remains on the Top Window. The Top Window contains the other <iframes> and the framesets. So when we need to interact with a WebElement which is within an iframe we have to switch to the respective <iframe> through one of the below-mentioned methods :
Frame Switching Methods :
We can switch over to frames by 3 ways.
By Frame Name :
Name attribute of iframe through which we can switch to it.
Example:
driver.switch_to.frame("iframe_name")
By Frame ID :
ID attribute of iframe through which we can switch to it.
Example:
driver.switch_to.frame("iframe_id")
By Frame Index :
Suppose if there are 10 frames in the page, we can switch to the iframe by using the index.
Example:
driver.switch_to.frame(0)
driver.switch_to.frame(1)
Switching back to the Main Frame :
We can switch back to the main frame by using default_content() or parent_frame()
Example:
driver.switch_to.default_content()
driver.switch_to.parent_frame()
A Better Approach to Switch Frames:
A better way to switch frames will be to induce WebDriverWait for the availability of the intended frame with expected_conditions set to frame_to_be_available_and_switch_to_it as follows :
Through Frame ID:
WebDriverWait(driver, 10).until(EC.frame_to_be_available_and_switch_to_it(By.ID,"id_of_iframe"))
Through Frame Name:
WebDriverWait(driver, 10).until(EC.frame_to_be_available_and_switch_to_it((By.NAME,"name_of_iframe")))
Through Frame Xpath:
WebDriverWait(driver, 10).until(EC.frame_to_be_available_and_switch_to_it((By.XPATH,"xpath_of_iframe")))
Through Frame CSS:
WebDriverWait(driver, 10).until(EC.frame_to_be_available_and_switch_to_it((By.CSS_SELECTOR,"css_of_iframe")))
Reference
You can find a relevant detailed discussion in:
Ways to deal with #document under iframe
Writing your own recursive finder should be easy enough. Apologies, don't know python but in Java it would be something like:
public void findInAllFrames(WebElement e, String targetIdStr) {
List<WebElement> l = e.findElements(By.tagName("iframe"));
for(int inx=0; inx<l.size(); inx++) {
List<WebElement> targets = l.get(inx).findElements(By.id(targetIdStr));
if(targets.size()>0) {
// Do something with your targets
}
findInAllFrames(l.get(inx), targetIdStr);
}
}
I'm trying to load a parent page into an object tag, and whilst I can get an alert to show I've got the code, I cannot get it into the <object> Any clues?
var page=parent.document.documentElement.innerHTML;
alert(page);
document.getElementById('close_skin').style.visibility="visible";
document.getElementById('show_skin').style.visibility="visible";
document.getElementById('show_skin').setAttribute("data",page);
Assuming I can get the code to appear, how can I "toggle" to a different set of styles? The parent uses ".xxx_fixed" classes, but the code in the object needs to use the ".xxx_float" classes that are also in the template CSS at top of page. (When I did it in another PERL program, it was easy just to rename the tags in the <body> from "class='xxx_fixed' " to "class='xxx_float' " (Can't do that so easily with global javascript replace as that would also rename the classes at top of code as well!)
I have just tried adding some script to the top of the var page object - which MAY work if I can get the code to appear ...
+'document.getElementById(\'icon_outer\').setAttribute(\'class\', \'icon_outer_float\')'
If you're interested as to the "why", the "fixed" keep menu / top bar fixed in one place when viewed in full screen browser, but the 'float' makes everything move in unison within the <object> "window" allowing viewer to pan around the template page like a static magnifying glass;
.menu_back_float{position:relative;top:0px;background-color:#f5eca4;min-height:520px;height:auto}
.menu_back_fixed{position:relative;top:35px;background-color:#f5eca4;min-height:550px;height:auto}
To load the parent page into an <object> element, you have to specify the URL of the page. To get the code and place it in a alert box, you can use jQuery's $.get() method (as long as you load it via a proxy domain), like this:
HTML:
// I'm just using W3Schools just to save time
<object data="http://www.w3schools.com/" width="1500" height="1200">
<embed src="http://www.w3schools.com/" width="1500" height="1200"></embed>
Your browser does not support the object tag.
</object>
JavaScript:
window.jQuery.get("http://www.yourdomain.com/?url=www.w3schools.com", function(response) {
window.alert(response);
}
For the second part of your question, you can use jQuery to change the name of the class from .xxx_fixed to .xxx_float:
function main() {
$('object').removeClass('xxx_fixed').addClass('xxx_float');
}
$(document).ready(main);
Hopefully I have answered your question correctly and thouroughly, and if I haven't, feel free to let me know so I can edit this.
I am trying to do a Javascript postMessage like you can do to an iframe, but now to an embed. I have to use an embed because it is for an app which is loaded on an IOS device, and since IOS has a bug with iframe width and height I need to use an embed.
This is loaded and from inside the embed I can do a postMessage to the parent, but somehow I am not able to post to the embed. What I tried:
document.getElementById("embed").contentWindow.postMessage(...)
document.getElementById("embed").contentDocument.postMessage(...)
document.getElementById("embed").document.postMessage(...)
document.getElementById("embed").getSVGDocument() // will return null
Current embed setup:
<embed src="URL" id="embed" type="text/html"></embed>
Any solution for this?
If you want to get an element by Id in JS, you have to put an Id in your element so the JS script can find it:
<embed id="embed" src="URL" type="text/html"></embed>
If you don't want to use an Id, you can use the getElementsByTagName function to get your element, like this:
//if you only have one element of that type
document.getElementsByTagName("embed")[0].doSomething();
//if you have several embed elements
var embeds = document.getElementsByTagName("embed");
for(var i=0;i<embeds.lenght;i++)
{
document.getElementsByTagName("embed")[i].doSomething();
}
Concerning the contentWindow property, seems like it's an iFrame property only. So you'll have to use another property or switch back to iFrame. More here:
https://developer.mozilla.org/en-US/docs/Web/HTML/Element/iframe#Scripting
I have an iframe. I want to access a table which present inside iframe.I want to access it from parent window of iframe. I have written JS like
Document.getElementById("table Id");
But the result come null. What is the process to get it?
thanks
x=document.getElementById("iFrameId");
x.contentDocument.getElementById("tableId");
if you can use jQuery i guess it will work across browsers
$("#iFrameId").contents().find("#tableId")
You have to select the element from the iFrame's document. Per Juan's comment, check against both the name, and id of the iFrame
var targetFrame = window.frames["nameOfIFrame"] || window.frames["iFrameId"];
targetFrame.document.getElementById("tableId");
EDIT
I just tested this with the following:
window.frames["fName"].document.getElementById("Adam").innerHTML
in the Chrome console, and it output the html of the Adam div from within my iframe.
Good day to all.
I have this setup:
One page with text/whatever, that also includes an iframe (the page in iframe is created by me so I have access to it, I can modify its content).
What I need to do is that when I access a link from the iframe to open it on the mother page (navigate).
Until now I kind of failed to do that so any help would be appreciated.
For any further info just ask.
In all of the links that you want to affect the parent window do something like this:
GO THERE!
Or with javascript:
<a href="javascript:window.parent.location = 'somthing.html';" >GO SOMEWHERE!</a>
If all you need to do is change the parent window's location from inside the iframe, it is very simple:
window.parent.location = 'newWindow.html';
Or if you are using a link, just use it's "target" attribute.
You should use the target attribute <a href="" target="...">
For all the possible values of target, you can go here.