Reputation: 55
I've been trying to enter to an iframe and write text in a search bar ( tag) in Safari:
I can't post the html because it's huge and it isn't mine but this is the iframe code:
<iframe frameborder="0" id="contentIFrame0" name="contentIFrame0" title="Área de contenido" style="border: 0px none; overflow: hidden; position: absolute; left: 0px; right: 0px; height: 100%; width: 100%; visibility: visible; display: block;"> (...Content of the iframe...) </iframe>
Here is python code:
wait.until(ec.frame_to_be_available_and_switch_to_it((By.XPATH, '//*[@id="contentIFrame0"]')))
chk_elem = wait.until(ec.visibility_of_element_located((By.XPATH, '//*[@id="2crmGrid_findCriteria"]')))
act = ActionChains(driver)
act.move_to_element(chk_elem)
act.send_keys('Search input', Keys.ENTER).perform()
but I always get this Exception: "selenium.common.exceptions.NoSuchFrameException: Message:".
I've been watching some tutorials and even reading the official documentation and I guess my code is Ok. Why it isn't working?
PD: There aren't another iframe before the iframe that I posted and XPATHs are well written. I don't know if it is relevant but we are talking about a web site of dynamics services from microsoft, just in case.
Upvotes: 1
Views: 2335
Reputation: 193088
This error message...
selenium.common.exceptions.NoSuchFrameException
...implies that Selenium driven WebDriver instance was unable to locate the <iframe>
element.
You have adapted the right approach. Ideally, to locate an iframe you have to induce WebDriverWait inconjunction with expected_conditions set as frame_to_be_available_and_switch_to_it().
However, there can be numerous reasons behind seeing this error and some of the reasons and solutions are as follows:
The desired iframe may be a nested iframe within it's parent iframe. In those cases you have to induce WebDriverWait first to switch to the parent iframe and then to the child iframe as follows:
WebDriverWait(driver, 10).until(EC.frame_to_be_available_and_switch_to_it((By.XPATH,"parent_iframe_xpath")))
WebDriverWait(driver, 10).until(EC.frame_to_be_available_and_switch_to_it((By.XPATH,"child_iframe_xpath")))
If you are switching between two sibling iframes then you first need to switch back to the default_content
first and then switch to the sibling iframe as follows:
WebDriverWait(driver, 10).until(EC.frame_to_be_available_and_switch_to_it((By.XPATH,"sibling_iframe_A")))
driver.switch_to.default_content()
WebDriverWait(driver, 10).until(EC.frame_to_be_available_and_switch_to_it((By.XPATH,"sibling_iframe_B")))
You can find a detailed discussion in How to address “WebDriverException: Message: TypeError: can't access dead object” and wait for a frame to be available using Selenium and Python
At times multiple iframes can have similar values for same attributes. In those cases, you may need to construct Locator Strategies which identifies the <iframe>
element uniquely using the src
attribute as follows:
WebDriverWait(driver, 10).until(EC.frame_to_be_available_and_switch_to_it((By.XPATH,"//iframe[@id="iframe_id and @src='iframe_src'"]")))
You can find a detailed discussion in Ways to deal with #document under iframe
Finally, you need to ensure that the binary versions are compatible and you can find a couple of relevant discussions in:
The timeout configured for WebDriverWait may be too less and in that case you need to increase the timeout as follows;:
WebDriverWait(driver, 30).until(EC.frame_to_be_available_and_switch_to_it((By.XPATH,"parent_iframe_xpath")))
You can find a couple of reference discussions in:
Upvotes: 1