Ways to deal with #document under iframe - javascript

For the portal I am testing now, I came with the problem that I could not create any xpath locators, after some time I figured out that it was because of an '#document', this cuts the path and makes the simple "copy xpath" to direct the path to a completely different element.
<iframe id="FRAMENAME" src="/webclient/workspace/launch-task/REMbl?ds=BP" width="100%" height="100%" frameborder="0" data-navitemname="navitemname" style="" xpath="1">
#document
<html>
CODE....
</html>
I found the solution for this is it is simply add a switchTo like this:
driver.switchTo().frame("FRAMENAME");
This works and makes the rest of the code to work properly but, takes some extra time processing this command till the code moves to the next line.
So I would like to ask, is there is a better solution for this? something smarter/faster?
I am concerned that when the point where I have lots of scripts comes, the execution time will take too long.
I don't use id locators for example because they are all dynamic so sometimes a xpath is required.
Thank you!

To work with elements inside iframe you must switch to this specific iframe.
Your solution .switchTo().frame("FRAMENAME"); is correct. Selenium does not have any other ways to work with iframe wrappers.

inline frames
As per the documentation in Using inline frames, an inline frame is a construct which embeds a document into an HTML document so that embedded data is displayed inside a subwindow of the browser's window. This does not mean full inclusion and the two documents are independent, and both them are treated as complete documents, instead of treating one as part of the other.
iframe structure and details
Generally, an iframe element is in the form of:
<iframe src="URL" more attributes>
alternative content for browsers which do not
support iframe
</iframe>
Browsers which support iframe display the document referred to by the URL in a subwindow, typically with vertical and/or horizontal scroll bars. Such browsers ignore the content of the iframe element (i.e. everything between the start tag <iframe...> and the end tag </iframe>). Browsers which do not support iframe (or have such support disabled) does the opposite, i.e. process the content as if the <iframe...> and </iframe> tags were not there. Thus, the content matters, despite being ignored by some browsers.
So to summarize, inline frames do not mean an include feature, although it might sometimes serve similar purposes.
Note that, when inline frames are used, the browser (if it supports them) sends a request to the server referred to by the URL in the iframe element, and after getting the requested document displays it inside an inline frame. In this sense inline frames are a joint browser-server issue, but only the browser needs to be specifically iframe-aware; from the server's point of view, there's just a normal HTTP request for a document, and it sends the document without having (or needing) any idea on what the browser is going to do with it.
Something Smarter
As per the best practices while switching to an iframe you need to induce WebDriverWait as follows:
Switch through Frame Name (Java Sample Code):
new WebDriverWait(driver, 20).until(ExpectedConditions.frameToBeAvailableAndSwitchToIt(By.name("frame_name")));
Switch through iframe XPath (Python Sample Code):
WebDriverWait(driver, 10).until(EC.frame_to_be_available_and_switch_to_it((By.XPATH,"//iframe[#id='ptifrmtgtframe' and #name='TargetContent']")))
Switch through iframe CssSelector (C# Sample Code):
new WebDriverWait(driver, TimeSpan.FromSeconds(20)).Until(ExpectedConditions.FrameToBeAvailableAndSwitchToIt(By.CssSelector("iframe#twitter-widget-0")));
Reference
You can find a couple of relevant discussions in:
Python: How can I select a html element no matter what frame it is in in selenium?
Java: Is it possible to switch to an element in a frame without using driver.switchTo().frame(“frameName”) in Selenium Webdriver Java?
C#: How to wait for a frame to load before locating an element?
tl; dr
Inline frames vs. normal frames

Related

How to run a Javascript function on an iframe before the source (src) is loaded?

I've asked this question before this one, trying to figure out why I was seeing scrollbars on the a-ads iframes, on this website, while some swear they didn't see them!
Hence, I have discovered that the appearance of the iFrame scrollbars is by execution order. And with faster or slower computers, results may vary.
I realize that I have to replace scrolling="no", a strong (but unsupported in HTML5), attribute that forces no scrollbars on iframes, with a JavaScript, or CSS alternative. However, the CSS overflow:hidden; is too weak to override whatever style the iframe's source may contain (e.g. overflow:scroll, overflow:auto, etc.). So the solution must be with JavaScript.
The caveat however, is that the javascript must activate after the iframe itself is loaded, but before the source (src="") is loaded. Because if scrolling="no" is replaced after the source is loaded it has no effect on the outcome of the iframe display. Though, if it is place before the <iframe> tag markup is reached, how does the JavaScript know what to modify? It is as good as not present at that point.
One More Problem: The source can't be stripped from the <iframe> tag, and replaced in JavaScript. We've tried that, and while it worked....sort of... we lost ad impressions and clicks into a black hole, because the spider (i.e. bot) at a-ads couldn't, or had problems with, detecting the proper a-ads code on the webpage. But if we left it in the iframe and just reloaded the source after scrolling="no" was set, then that would result in double ad-loads (i.e. invalid impressions).
This is a real pickle!
All the Einsteins of the world - You're Needed!
Also, this S.O. question doesn't apply.
Screenshots
Chrome Proof
IE Proof
Opera Proof
Firefox was best-behaved
This issue has now been solved, for now, I think. Here is the solution:
<head>
<script type="text/javascript">
function noScrollBarsOnAAdUnit( ElementID )
{
document.getElementById( ElementID ).setAttribute("scrolling", "no");
return true;
};
</script>
</head>
<body>
<script type="text/javascript">noScrollBarsOnAAdUnit( 'aa-unit-top-center' );</script>
<iframe id='aa-unit-top-center' style='width:468px;height:60px;' class='a-ads-frame' data-aa='[ad-id]' src='https://ad.a-ads.com/[ad-id]?size=468x60'>
<!-- iframe fallback message here -->
</iframe>
<script type="text/javascript">noScrollBarsOnAAdUnit( 'aa-unit-top-center' );</script>
</body>
Fellow S.O. members, please, check this page, to assure this fix is consistent, and really works at least 99.99%, if not 100%, of the time.
Thanks!
-James A.

IE9 throws exceptions when loading scripts in iframe. Why?

Precondition:
I have an aspx-page with iframe inside. This iframe points to the url handled by MVC on the same site (it's hybrid site, both standard ASP.NET and ASP.NET MVC). The resulting page rendered by MVC contains a lot of scripts references.
Problem:
IE9 throws an exception on every single script it load in iframe. These exceptions are similar to this one:
Error: 'Function' is undefined
That is, it says that the most basic things every window has is somehow absent. Once you clicked through all of these popups, the page just works as designed!
If I load a URL from <iframe /> src attribute in the browser directly, everything works as expected.
If I open the page in another browser (I tried Opera, Firefox), everything works as expected -- no errors.
So, what IE9 wants?
There is this msdn page about this bug (or feature).
You get these kinds of errors when you move the iframe element around in DOM. In such cases, IE 9 garbage collects the iframe (causing your undefined bug) and reloads it at another position.
In general, you should create the element, set its src attribute only once and then put it somewhere in the DOM tree once. It has nothing to do with the code which runs in the iframe itself.
I have encountered this same situation in the wild. Basic symptoms:
You load script code in an iframe
The script code runs early (from the head section or top of body)
IE complains about some missing native object
I found that it can often be prevented by delaying the execution of the script code until onload or DOMContentLoaded... Not much help I know but this is one of the most difficult IE scripting bugs I have ever encountered. I upped the score of your question, hope it will be found by others as well and we can get a more detailed answer.
Also see this question:
Error in Internet Explorer 9 (not earlier versions or other browsers) when including jQuery in an iframe
Placing the following script block at the very top of the iFrame html <head> seems to resolve the issue in my case. Basically, it forces the iframe to reload, which as some have pointed out, solves the issue. It seems relatively safe, because, without things like 'Object' and 'Date', javascript is essentially useless.
<script type="text/javascript">
if(typeof(Object)==="undefined"){
window.location.reload();
}
</script>
Try loading the javascript at the end after complete web page is loaded. I feel the script is executing even before the iframe is completely loaded.
for some suggestion of scripting in IE9 view the given link below
http://blogs.msdn.com/b/ie/archive/2010/06/25/enhanced-scripting-in-ie9-ecmascript-5-support-and-more.aspx
Further investigation revealed that the solution is to add the offending iframe to it's dom location BEFORE setting the 'src' attribute.
Once the 'src' has been set, changing location of the iframe within the DOM stack forces IE9 to garbage collect it.
Once 'src' has been set, iframe can be resized and changed via css positioning, but cannot change the relative location in the DOM stack.
Often times, plugins like dialogs and lightboxes will stuff an iframe with src already set into the dom, then append / prepend or whatever, triggering the GC to take place.
function waitForjQuery(){
if(typeof jQuery!='undefined'){
//Do yor stuff!
}
else{
setTimeout(function(){
waitForjQuery();
},500);
}
}
waitForjQuery();

manipulating location.href of frame with PDF plugin in IE9

I'm experiencing rather strange behaviour in IE9 when loading a PDF in a frame with Javascript. The document will load once, but any subsequent invocation will result in SCRIPT65535: Invalid calling object.
I'm constructing my URL from Javascript and loading through top.framename.location.href='file1.pdf'. If you start with a PDF in the frame, it will fire the error upon the first invocation of the script.
So, it appears you are no longer allowed to modify the location.href property of a frame in which the Adobe Reader plugin (version 10) is loaded. The same code with HTML documents works fine.
Does anybody know why this behaviour was changed, and if there is a workaround other than using IE8 emulation with <meta http-equiv="X-UA-Compatible" content="IE=EmulateIE8">?
I'm also not looking for workarounds that completely avoid the Javascript. There are numerous options, like constructing the link elsewhere and loading it with a target attribute, but I'd really like to do this with Javascript.
If you want to test/reproduce, you can use:
<frameset cols="150,*">
<frame src="toc.html"/>
<frame src="about:blank" name="otherframe"/>
</frameset>
and in toc.html:
<a onclick="javascript:top.otherframe.location.href='1.pdf'">pdf1</a><br/>
<a onclick="javascript:top.otherframe.location.href='2.pdf'">pdf2</a>
Take a look here:
http://forum.jquery.com/topic/internet-explorer-9-jquery-and-divx
When I go to IE9 developer tools (F12) and under Script tab, click on
Start debugging button, I get details about the error: SCRIPT65535:
Invalid calling object script block (2), line 72 character 4
When you look at the script line 72, this line is highlighted:
appendChildOriginal(element);
Then I go to IE9, Manage add-ons, under Toolbars and Extensions, look
for Divx, LLC and disable Divx Plus Web Player HTML5 and DivX HiQ and
restart IE9 Browser.
The error is gone and my web application work perfectly.
Had the same problem.
In IE9, the frame object is replaced by some PDF object that doesn't contain the location property. So the second time you cannot update the frame url with location.
You can solve this by using window.open()
window.open('1.pdf', 'otherframe');

Can I load a page with an HTML 5 Doctype into a frame on a page with a Frameset Doctype?

I have a main frameset page, which uses the FRAMESET doctype..Now this has 3 frames inside it..
Now for the 2nd frame, I want to use some HTML5 code ()...So guess I'll have to use the doctype
Now my question is; can both these doctypes co-exist, which means can I declare FRAMESET doctype for the main frameset page and HTML5 Doctype for one of the frame page..
Can it cause any cross-browser issues?
Also before you say, I know this is a strange question as I am using old/outdated frameset with the latest HTML5...But I have limited options (In fact, can't edit the main frameset page to use iframes)...So want to know how can I combine the 2?
Doctypes are specific to documents and each document has its own independent doctype. Having a different doctype in each frame is perfectly valid, and having the doctype of the frameset be different from the doctype of the frames is not only valid, it's impossible for it to be otherwise. Whether it's HTML 5 doesn't really enter into it.
Now my question is; can both these doctypes co-exist, which means can I declare FRAMESET doctype for the main frameset page and HTML5 Doctype for one of the frame page..
They are separate, independent documents, so: yes.
Apparently the answer is no because as usual, Internet Explorer. This link: http://css-tricks.com/ie-iframe-quirksmode/ is validating my findings that my html5 document loaded inside of a frame loaded inside of a much older parent document with frameset doctype is rendering in quirksmode because "In IE, iFrames on Pages in Quirks Mode Also in Quirks Mode". It sounds like this is the case with Frames as well as IFrames even in IE11.

iframe without an src attribute

I would like to create an <iframe> on the page, but then add the src later. If I make an iframe without an src attribute, then it loads the current page in some browsers. What is the correct value to set for the src so that it just loads a blank iframe?
The answers I've seen are:
about:blank
javascript:false
javascript:void(0)
javascript:"";
url to a blank page
Is there a clear winner? If not, what are the tradeoffs?
I'd like to not have mixed content warnings for HTTPS urls, nor any back-button, history, or reload weirdness in all browsers from IE6 onward.
Not sure if all browsers support "about:blank", so I'd just go with your own blank page then.
Another idea: Why not add the whole iframe using javascript instead of just the src?
Standard approach when creating an "empty" iframe (as an iframe shim, for example), is to set the src as javascript:false;. This is the method used by most of the JavaScript libraries that create iframe shims for you (e.g. YUI's Overlay).
What about
about:blank
Re your comment clarifying that you're planning to use the iframe as the target for a form submission:
I would use an empty document on the server that sends back a 204 no content.
It avoids
"mixed content" warnings in IE and HTTPS mode
Unnecessary errors because a client doesn't understand the javascript: protocol
and other exotic shenanigans.
It's also valid HTML.
So what if it generates an extra request? Set the caching headers right, and there will be only one request for each client.
javascript:false:
IE10 and FF (checked in v23 in Linux) will show 'false' as content.
javascript:void(0) && javascript:;:
IE will show 'cannot display the webpage' error in the iframe. Also, when setting the src from a valid url to javascript:void(0), the page will not get blank.
about:blank:
Works in all browsers but IE 9 sends an request to the server with path "null". Still the best bet IMO
Checkout http://jsfiddle.net/eybDj/1
Checkout http://jsfiddle.net/sv_in/gRU3V/ to see how iframe src changes on dynamic updation with JS
javascript:false works in modern browsers.
What I've seen is that this only "fails" when dumb spiders try to load javascript:false as a page.
Solution: Block the dumb spiders.
As I posted in this question: Is an empty iframe src valid?, it looks acceptable to just leave out the src= attribute completely.
IMO: if you don't put the src, your page won't validate. But's about it.
If you put a src="", your server will log many 404 errors.
Nothing is really wrong as in "damaging". But then, is it actually not wrong to use an iframe in itself?
°-
Yes, I know I'm reviving an old thread. Sue me. I'm interested in the answer.
I don't understand why having the trigger being a form submit precludes dynamically creating the IFrame. Does this not do exactly what you want?
<html>
<head>
<script type="text/javascript">
function setIFrame(elemName, target, width, height) {
document.getElementById(elemName).innerHTML="<iframe width="+width+" height="+height+" src='"+target+"'></iframe>";
}
</script>
</head>
<body>
<div id="iframe" style="width:400px; height:200px"></div>
<form onSubmit="setIFrame('iframe', 'http://www.google.com', 400, 200); return false;">
<input type="submit" value="Set IFrame"/>
</form>
</body>
</html>
I run into this line of code:
iframe.setAttribute("src", "javascript:false");
as well. I wanted to remove javascript:URL.
Found this note from the Web Hypertext Application Technology Working Group [Updated 2 October 2019]
[https://html.spec.whatwg.org/multipage/iframe-embed-object.html#the-iframe-element][4.8.5_The_iframe_element]
The otherwise steps for iframe or frame elements are as follows:
If the element has no src attribute specified, or its value is the
empty string, let url be the URL "about:blank".

Categories