0

I am not able to locate the element inside the frame after switching to the correct frame. Here is my code, error and HTML sorce. If I right click on the frame and select This Frame -> Show Only This Frame then I am able to find the element in the default_content, but I need to find it without Show Only This Frame

browser.switch_to.default_content()  

browser.switch_to.frame(browser.find_element_by_id('DialogFrame'))

browser.find_element_by_css_selector('#_ctl12_btnExportCSV')

Error stacktrace:

NoSuchElementException Traceback (most recent call last) in ----> 1 browser.find_element_by_css_selector('#_ctl12_btnExportCSV')

~\anaconda3\lib\site-packages\selenium\webdriver\remote\webdriver.py in find_element_by_css_selector(self, css_selector) 596 element = driver.find_element_by_css_selector('#foo') 597 """ --> 598 return self.find_element(by=By.CSS_SELECTOR, value=css_selector) 599 600 def find_elements_by_css_selector(self, css_selector):

~\anaconda3\lib\site-packages\selenium\webdriver\remote\webdriver.py in find_element(self, by, value) 974 by = By.CSS_SELECTOR 975 value = '[name="%s"]' % value --> 976 return self.execute(Command.FIND_ELEMENT, { 977 'using': by, 978 'value': value})['value']

~\anaconda3\lib\site-packages\selenium\webdriver\remote\webdriver.py in execute(self, driver_command, params) 319 response = self.command_executor.execute(driver_command, params) 320 if response: --> 321 self.error_handler.check_response(response) 322 response['value'] = self._unwrap_value( 323 response.get('value', None))

~\anaconda3\lib\site-packages\selenium\webdriver\remote\errorhandler.py in check_response(self, response) 240 alert_text = value['alert'].get('text') 241 raise exception_class(message, screen, stacktrace, alert_text) --> 242 raise exception_class(message, screen, stacktrace) 243 244 def _value_or_default(self, obj, key, default):

NoSuchElementException: Message: Unable to locate element: #_ctl12_btnExportCSV

HTML:

HTML nested

IFrame

DebanjanB
  • 118,661
  • 30
  • 168
  • 217

2 Answers2

1

Induce WebDriverWait() and wait for frame_to_be_available_and_switch_to_it()

Induce WebDriverWait() and wait for element_to_be_clickable()

WebDriverWait(browser, 10).until(EC.frame_to_be_available_and_switch_to_it((By.ID, 'DialogFrame')))
inptelement=WebDriverWait(browser, 10).until(EC.element_to_be_clickable((By.CSS_SELECTOR, '#_ctl12_btnExportCSV')))

You need to import below libraries.

from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
KunduK
  • 26,790
  • 2
  • 10
  • 32
0

The element #_ctl12_btnExportCSV is a __doPostBack enabled element.

As the element is within an <iframe> so 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, 20).until(EC.frame_to_be_available_and_switch_to_it((By.ID,"DialogFrame")))
      WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "input[id$='btnExportCSV'][name$='btnExportCSV'][value='Scaricamento']"))).click()
      
    • Using XPATH:

      WebDriverWait(driver, 20).until(EC.frame_to_be_available_and_switch_to_it((By.ID,"DialogFrame")))
      WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//input[contains(@id, 'btnExportCSV') and contains(@name, 'btnExportCSV')][@value='Scaricamento']"))).click()
      
  • Note : You have to add the following imports :

     from selenium.webdriver.support.ui import WebDriverWait
     from selenium.webdriver.common.by import By
     from selenium.webdriver.support import expected_conditions as EC
    

Reference

You can find a couple of relevant discussions in:

DebanjanB
  • 118,661
  • 30
  • 168
  • 217
  • Thank you both but unfortunately the solutions are not working. There is a timeout error when locating the element: – Marco Venè Dec 21 '20 at 19:22