So, I was absolutely baffled as to how to do this in Selenium, and couldn't find the answer anywhere, so I'm sharing my experience.
I was trying to select an iframe and having no luck (or not repeatably anyway). The HTML looked like this:
<iframe id="upload_file_frame" width="100%" height="465px" frameborder="0" framemargin="0" name="upload_file_frame" src="/blah/import/">
<html>
<body>
<div class="import_devices">
<div class="import_type">
<a class="secondary_button" href="/blah/blah/?source=blah">
<div class="import_choice_image">
<img alt="blah" src="/public/images/blah/import/blah.png">
</div>
<div class="import_choice_text">Blah Blah</div>
</a>
</div>
</div>
</body>
</html>
The Python code (using the selenium library) was trying to find this iframe using this:
@timed(650)
def test_pedometer(self):
sel = self.selenium
...
time.sleep(10)
for i in range(5):
try:
if sel.select_frame("css=#upload_file_frame"): break
except: pass
time.sleep(10)
else: self.fail("Cannot find upload_file_frame, the iframe for the device upload image buttons")
Repeated fails with every combination of Selenium commands I could find. The occasional success would not be reproducible, so perhaps it was some sort of race condition or something? Never did find the right way to get it in selenium proper.
What finally worked for me was:
Basically, don't use selenium to find the link in the iframe and click on it; use jQuery. Selenium has the capability to run an arbitrary piece of javascript apparently (this is python-selenium, I am guessing the original selenium command is runScript or something), and once I can use jQuery I can do something like this: Selecting a form which is in an iframe using jQuery
This worked for me with Python (v. 2.7), webdriver & Selenium when testing with iframes and trying to insert data within an iframe:
You don't need to use JavascriptExecutor. All you needed to do was switch into the frame and then switch back out, like so:
As long as you are careful with this, you will never have a problem. The only time I always use a JavascriptExecutor is to get window focus since I think using Javascript is more reliable in that case.
If
iframe
is dynamic node, it's also possible to wait foriframe
appearence explicitly and then switch to it usingExpectedConditions
:If
iframe
doesn't have@id
or@name
it can be found as common WebElement usingdriver.find_element_by_xpath()
,driver.find_element_by_tag_name()
, etc..:To switch back from
iframe
:Selenium's selectFrame command accepts all the standard locators like
css=
, but it also has a an extra set of locators that work specifically with FRAME and IFRAME elements.As the doc says:
In general, you'll have better luck using the specialized locators, especially if you establish the right context first (e.g.,
select_frame("relative=top"); select_frame("id=upload_file_frame");
).