I'm having difficulty testing a piece of code using NightwatchJS with Selenium and SafariDriver.
I have an open issue for this on nightwatch repo, although am not sure if it is an issue with nightwatch or something deeper.
The HTML content to be tested looks something like:
<body>
<iframe id="top-iframe" src="about:blank">
#document
<html>
<body>
<container>
<!-- access this iframe to test -->
<iframe id="nested-iframe" src="news.google.com"></iframe>
</container>
</body>
</html>
</iframe>
</body>
Where #nested-frame
will need to be accessed from the top level document for inspection of content.
The test code is using NightwatchJS, more details about config, setup and code are in the GitHub issue.
The Gist of the issue:
The problem is that to access the nested iFrame, it needs to first find #top-frame
web element, use the returned web element and pass it to frame
which makes the WebDriver call to change context of test session to that frame. This is all good with Chrome, FF, and Safari as they can all find this frame web element and make the switch into the frame context. My test that Safari was changing iFrame context, although not sure how good it is, was to try and find another DOM element other than the nested frame, which it could find. The problem comes when with Safari, after switching into #top-frame
, it cannot find the #nested-frame
web element, and Nightwatch returns a 404
no such element
from the HTTP call. Strange, right?
It is very puzzling, my latest thinking was maybe it was a cross origin issue. But then I read on WebDriver switch to frame:
NOTE WebDriver is not bound by the same origin policy, so it is always possible to switch into child browsing contexts, even if they are different origin to the current browsing context.
And I also tried checking Disable Cross Origin Restrictions
from Safari Developer menu.
As mentioned before, I can find another DOM element in the #top-frame
. I tried things like 10-15s timeouts thinking maybe it needed to load. I can inspect the browser with debugger and see that #nested-frame
is there and the content loads as expected. There are not console errors indicating any content failed to load.
It's very puzzling to me and I'm not sure how to further debug. Maybe someone else with a fresh perspective could have a suggestion or if someone has run into a similar situation as this. Throwing this out into the universe as information is limited on the topic too, so maybe this could help someone else. TIA!
CodePudding user response:
iframes
As per the documentation iframe
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.
This usecase
As the top-level <iframe>
is having src="about:blank"
it is highly unlikely there can be any child <iframe>
. Hence, in absence of any child <iframe>
your attempt to access any nested <iframe>
will fail.
Reference
You can find a relevant detailed discussion in:
CodePudding user response:
After discussion with Selenium team, this appears to be a bug with Apple.
I have filed a ticket with Apple here.