I am trying to list the names of all the iframe
s in a page, so I can access them through Selenium.
The problem is that the name of the iframe
changes each time, so I need to loop through all of them.
I am getting:
Uncaught DOMException: Blocked a frame with origin "http://localhost:8080" from accessing a cross-origin frame.
error when I try to loop over them using:
for (var f = 0; f < window.frames.length; f++) {
console.log(window.frames[f].name)
}
Is there a way to get the name of the iframe
in a different way?
This error message...
Uncaught DOMException: Blocked a frame with origin "http://localhost:8080" from accessing a cross-origin frame.
...implies that the WebDriver instance blocked from accessing a cross-origin frame.
Same-origin policy
Same-origin policy : Same-origin policy restricts how a document or script loaded from one origin can interact with a resource from another origin. It is a critical security mechanism for isolating potentially malicious documents.
Cross-Origin Resource Sharing (CORS)
Cross-Origin Resource Sharing (CORS) : Cross-Origin Resource Sharing (CORS) is a mechanism that uses additional HTTP headers to tell a Browser Client to let the AUT (Application under Test) running at one origin (domain) have permission to access selected resources from a server at a different origin. A web application makes a cross-origin HTTP request when it requests a resource that has a different origin (domain
, protocol
, and port
) than its own origin.
Example of an origin
Here is an example of origin comparisons to the URL http://store.company.com/dir/page.html
URL Outcome Reason
http://store.company.com/dir2/other.html Success
http://store.company.com/dir/inner/another.html Success
https://store.company.com/secure.html Failure Different protocol
http://store.company.com:81/dir/etc.html Failure Different port
http://news.company.com/dir/other.html Failure Different host
What went wrong
When you tried to loop through frames
your script/program tried to access an <iframe>
with different origin using JavaScript which would been a huge security flaw if you would have achieved it. As mentioned above the same-origin policy browsers block scripts trying to access a <iframe>
with a different origin.
Two pages have the same origin if the protocol, port (if one is specified), and host are the same for both the webpages. You'll see this referred to as the "scheme/host/port tuple"
at times (where a "tuple" is a set of three components that together comprise a whole). Perhaps the protocol, domain, hostname and port must be the same of your same domain when you want to access the desired frame.
Solution
The AUT may contain numerous frames / iframes and some of them may be loaded only after certain JavaScript / Ajax have completed where as some of them may be having style attribute set as display:none; or visiblity as hidden. Of-course won't require to interact with all of them. So it will be a better approach to identify the attributes of the <iframe>
and switch accordingly. You can switch to an <iframe>
through:
Frame Name
Frame ID
Frame Index
WebElement
As per best practices when you intent to switch to a frame induce WebDriverWait for frameToBeAvailableAndSwitchToIt as per the references below.
Here you can find a relevant discussion on Uncaught DOMException
References
Some references:
In this discussion you will find a detailed analysis on SecurityError: Blocked a frame with origin from accessing a cross-origin frame
In this discussion you will find the different approaches on Is it possible to switch to an element in a frame without using driver.switchTo().frame(“frameName”) in Selenium Webdriver Java?
In the A Better Approach to Switch Frames
section of this discussion you will find the different approaches on How can I select a html element no matter what frame it is in in selenium?
Dirty solution:
for windows:
chrome.exe --user-data-dir="" --disable-web-security
for mac:
open -a Google\ Chrome --args --disable-web-security --user-data-dir=""
In this way you open the chrome and let it ignore the web security.
You can use selenium
to get iframe tags like this:
var iframeElems = driver.findElements(webdriver.By.xpath("//iframe"));
Then loop on those elements and get the name attribute:
iframe.getAttribute('name')
You can try something like this : (Not sure about JavaScript)
var iframeElems = driver.findElements(webdriver.By.tagName("iframe"));
iterate this list to get the attribute.
for (var f = 0; f < iframeElems.length; f++) {
console.log(iframeElems.getAttribute("attribute name"))
}