0

My Selenium code logs into a website, then reaches a page with a button that exists within an iframe. Inspecting the element in chrome and using the console of the browser, I found the iframe:

iframe = document.getElementById("deputy-app-view1045")

Then I found the element and am able to click it:

iframe.contentWindow.document.getElementById("csv_download").click()

In my python code, I inserted:

browser.execute_script('document.getElementById("deputy-app-view1043").contentWindow.document.getElementById("csv_download").click()')

However, the error is "TypeError: document.getElementById(...) is null". :(

[SOLUTION] FIGURED IT OUT! Simply had to add a 'return' inside the js script! Thanks everyone! OLD VERSION:

browser.execute_script('document.getElementsByClassName("app-iframe dg-content-box margin-none Report Builder (BETA) ready")[0].contentWindow.document.getElementById("csv_download").href') 

FIXED VERSION:

browser.execute_script('return document.getElementsByClassName("app-iframe dg-content-box margin-none Report Builder (BETA) ready")[0].contentWindow.document.getElementById("csv_download").href')
Ace Pash
  • 11
  • 4

1 Answers1

0

As the the desired element is within an <iframe> so to invoke click() on the element you have to:

  • Induce WebDriverWait for the desired frame to be available and switch to it.
  • Induce WebDriverWait for the desired element to be clickable.
  • You can use either of the following Locator Strategies::

    • Using CSS_SELECTOR:

      WebDriverWait(driver, 10).until(EC.frame_to_be_available_and_switch_to_it((By.CSS_SELECTOR,"iframe[id^='deputy-app-view']")))
      WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "#csv_download"))).click()
      
    • Using XPATH:

      WebDriverWait(driver, 10).until(EC.frame_to_be_available_and_switch_to_it((By.XPATH,"//iframe[starts-with(@id, 'deputy-app-view')")))
      WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.ID, "csv_download"))).click()
      

Here you can find a relevant discussion on Ways to deal with #document under iframe

DebanjanB
  • 118,661
  • 30
  • 168
  • 217
  • Unfortunately, this leads to this error: selenium.common.exceptions.TimeoutException: Message: (and yes, there is nothing after Message:) – Ace Pash Jan 10 '20 at 17:55
  • @AcePash _TimeoutException_ is the outcome of **failed** _expected-conditions_. Debug your code through `find_element_by_*` in-conjunction with `time.sleep()`. If you are able to locate the element, update the question with the observations. Check the HTML and traverse upwards and observe if the element is within an – DebanjanB Jan 10 '20 at 22:28
  • FIGURED IT OUT! Simply had to add a 'return' inside the js script! Thanks everyone! OLD VERSION: ```browser.execute_script('document.getElementsByClassName("app-iframe dg-content-box margin-none Report Builder (BETA) ready")[0].contentWindow.document.getElementById("csv_download").href') ``` FIXED VERSION: ```browser.execute_script('return document.getElementsByClassName("app-iframe dg-content-box margin-none Report Builder (BETA) ready")[0].contentWindow.document.getElementById("csv_download").href')``` – Ace Pash Jan 11 '20 at 00:45