Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I access a dynamically added iframe using Selenium WebDriver?

I have a page that starts off without an iframe, and then via JavaScript gets an iframe added after clicking an anchor.

The problem I'm having is that when switching to the frame with driver.switch_to_frame(x) I still can find any of my content.

I've tried looping through the frames found with driver.find_elements_by_tag_name('iframe') and checking each of them for the class I expect to find, but no such luck.

driver.switch_to_active_element() does not give me the correct iframe either.

I'm not sure if the iframe content is just not accessible due to the JS DOM changes not reflected in what Selenium is seeing from the driver. I've gone through the same process for other iframes with no problems, but this one just won't cooperate. Below is a simplified version of what I'm dealing with.

Before JS:

<html>
    <body>
      <a onclick="jsmagic">load iframe</a>
    </body>
</html>

After JS:

<html>
    <body>
      <iframe><div class='modal'>Message</div></iframe>
      <a onclick="jsmagic">load iframe</a>
    </body>
</html>

Python WebDriver attempt:

driver.switch_to_frame(0)
driver.find_elements_by_class_name('modal')
driver.switch_to_default_content()

I've also tried variations on that like:

frame = driver.find_elements_by_tag_name('iframe')[0]
driver.switch_to_frame(frame)
driver.find_elements_by_class_name('modal')

I've event tried using driver.execute_script to get to the object, but getting at the content is beyond me. The Firefox console commands that work doesn't run via Selenium.

like image 878
Belrog Avatar asked Oct 21 '22 04:10

Belrog


1 Answers

It seems that it is a timing issue, I ended up with something along these lines:

def modal_must_show(self, string):
  for _ in range(12):
    for frame in self.driver.find_elements_by_tag_name('iframe'):
      try:
        if not frame.is_displayed():
          continue
        if frame.parent.page_source.find(string):
          return
      except:
        pass
  assert False, 'Modal missing string'
like image 147
Belrog Avatar answered Oct 31 '22 16:10

Belrog