How to Select a HTML Element No Matter What Frame It Is in in Selenium

How can I select a html element no matter what frame it is in in selenium?

No, it is not possible to interact with any WebElement within an <iframe> through Selenium without switching to the respective iframe.

Reason :

When a page is loaded, Selenium's focus by default remains on the Top Window. The Top Window contains the other <iframes> and the framesets. So when we need to interact with a WebElement which is within an iframe we have to switch to the respective <iframe> through one of the below-mentioned methods :



Frame Switching Methods :

We can switch over to frames by 3 ways.

By Frame Name :

Name attribute of iframe through which we can switch to it.

Example:

driver.switch_to.frame("iframe_name")

By Frame ID :

ID attribute of iframe through which we can switch to it.

Example:

driver.switch_to.frame("iframe_id")

By Frame Index :

Suppose if there are 10 frames in the page, we can switch to the iframe by using the index.

Example:

driver.switch_to.frame(0)
driver.switch_to.frame(1)

Switching back to the Main Frame :

We can switch back to the main frame by using default_content() or parent_frame()

Example:

driver.switch_to.default_content()
driver.switch_to.parent_frame()


A Better Approach to Switch Frames:

A better way to switch frames will be to induce WebDriverWait for the availability of the intended frame with expected_conditions set to frame_to_be_available_and_switch_to_it as follows :

  • Through Frame ID:

     WebDriverWait(driver, 10).until(EC.frame_to_be_available_and_switch_to_it(By.ID,"id_of_iframe"))
  • Through Frame Name:

     WebDriverWait(driver, 10).until(EC.frame_to_be_available_and_switch_to_it((By.NAME,"name_of_iframe")))
  • Through Frame Xpath:

     WebDriverWait(driver, 10).until(EC.frame_to_be_available_and_switch_to_it((By.XPATH,"xpath_of_iframe")))
  • Through Frame CSS:

     WebDriverWait(driver, 10).until(EC.frame_to_be_available_and_switch_to_it((By.CSS_SELECTOR,"css_of_iframe")))


Reference

You can find a relevant detailed discussion in:

  • Ways to deal with #document under iframe

How to locate an element inside this iframe with selenium?

As the element is within an <iframe> so you have to:

  • Induce WebDriverWait for the desired frame to be available and switch to it.

  • 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.CSS_SELECTOR,"iframe[title='To Do Assignments in Connect'][src='https://connect.mheducation.com/paamweb/index.html#/access/home']")))
    • Using XPATH:

      WebDriverWait(driver, 20).until(EC.frame_to_be_available_and_switch_to_it((By.XPATH,"//iframe[@title='To Do Assignments in Connect' and @src='https://connect.mheducation.com/paamweb/index.html#/access/home']")))
  • 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


References

You can find a couple of relevant detailed discussions in:

  • How can I select a html element no matter what frame it is in in selenium?

Identifying element from nested HTML code under frame using Selenium (confirmed no iframe)

The <input> tag with id as testFormNumForLastAttempt seems to be nested within 3 layers of <frame>.

So to click() within the element you have to:

  • Ignore (safely) the presence of parent or child <frameset> tags.
  • Induce WebDriverWait for the first layer of frame_to_be_available_and_switch_to_it().
  • Induce WebDriverWait for the second layer of _frame_to_be_available_and_switch_to_it().
  • Induce WebDriverWait for the third layer of frame_to_be_available_and_switch_to_it().
  • Induce WebDriverWait for the desired element_to_be_clickable().
  • You can use the following solution:

    • Code Block:

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

      WebDriverWait(driver, 10).until(EC.frame_to_be_available_and_switch_to_it((By.NAME,"applet_container")))
      WebDriverWait(driver, 10).until(EC.frame_to_be_available_and_switch_to_it((By.CSS_SELECTOR,"frame[name='javascript_container'][src$='__AUTHENTICATION_REQUEST_PARAMETER_MECHANISM__=applet']")))
      WebDriverWait(driver, 10).until(EC.frame_to_be_available_and_switch_to_it((By.XPATH,"//frame[@name='main' and contains(@src, 'Loading')]")))
      WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "input#testFormNumForLastAttempt[name='testFormNumForLastAttempt']"))).click()

You can find a relevant discussion in How to locate and click on an element which is nested within multiple frame and frameset through Selenium using Webdriver and C#


Outro

  • How can I select a html element no matter what frame it is in in selenium?
  • Ways to deal with #document under iframe

How do I Switch to Iframe and enter text in field with Selenium

The iframe has a class-name - webAuthContainer__iframe. Can make use of the same to switch to the iframe.

please = driver.find_element_by_css_selector('button.frontHero__loginButton')
please.click()

# Switch to iframe using class-name
wait.until(EC.frame_to_be_available_and_switch_to_it((By.CLASS_NAME,"webAuthContainer__iframe")))

attempt = wait.until(EC.element_to_be_clickable((By.ID,"sign_in_up_email")))
attempt.send_keys("example@email.com")

# Switch to default content to interact with elements outside the iframe
driver.switch_to.default_content()

Selenium unable to locate my elements(buttons)

When you have clicked on the iframe and you need to come back to the prev frame or the default frame, you should use driver.switch_to.default_content() and then you can click on the button on the default content.

This would switch the context to the default frame and you would be able to again operate on it.

Python Selenium: how to switch frames after navigation?

selenium.common.exceptions.NoSuchFrameException: Message: contents

this is because you are staying in child level of iframe which is 'menu' so inside that it can't able to find the iframe 'contents'.

First Switch back to the parent frame which is "contents", by using

DRIVER.switch_to.default_content()

and then try to go to the 'contents' iframe and perform actions, Now it should work.



Related Topics



Leave a reply



Submit