Selenium and iframe in html - python

Unable to use send_keys() for an iframe. How to select this iframe and which element inside this should be use for send_key()?
and iframe html code
<iframe class="textarea" src="/framework/html/blank.html" style="width: 99%; border-width: 1px; height: 332px;">
#document
<html webdriver="true">
<head>
</head>
<body> … </body>
</html>
</iframe>
How to send the value to description?
One more thing i want to know that this code of frame is not coming when i go for "view page source " in browser?

driver.switch_to.frame(driver.find_element_by_tag_name("iframe")) assuming that driver is a healthy instance of webdriver. To continue with the default content do driver.switch_to.default_content()
EDIT: When you have switched to needed frame, locate your webelement as you always do. I guess (but not sure) in your case this will be a html/body, so
el = driver.find_element_by_xpath('html/body')
should be fine. And perform
el.send_keys('keys_to_send')
EDIT2: Before sending keys you may have to focus on the element (click should do the thing, a child element should appear). Or you can just place the needed text via JS.
driver.execute_script('document.body.innerHTML = "%s"' % text_var)

The Accepted answer works very well for the given question. However I have two reasons for adding one more answer and hope this answer might help someone landing this question with different ask.
Reason 1:
Accepted answer has one way of handling iframes inside a web page. However there are different ways to handle iframes.
By using index position of the frame
By using name of the frame
By using id of the frame
Reason 2:
It uses driver.find_element_by_tag_name("iframe") statement to find iframe element which may not work or return expected iframe web element when there are multiple iframe elements in the same page.
There are many articles out there to explain handling iframes in detail.
http://allselenium.info/handling-iframes-using-selenium-webdriver/

You can switch to the iframe using multiple approaches as per the prevailing condition of the HTML DOM.
If the <iframe> is the only iframe within the DOM Tree you can use the following line of code:
Using TAG_NAME:
driver.switch_to.frame(driver.find_element(By.TAG_NAME, "iframe"))
Locating the <iframe> element with a unique Locator Strategy:
Using css_selector:
driver.switch_to.frame(driver.find_element(By.CSS_SELECTOR, "iframe.textarea[src='/framework/html/blank.html']"))
Using xpath:
driver.switch_to.frame(driver.find_element(By.XPATH, "//iframe[#class='textarea' and #src='/framework/html/blank.html']"))
Ideally to switch to 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 TAG_NAME (only iframe present):
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.TAG_NAME, "iframe"))).click()
Using CSS_SELECTOR:
WebDriverWait(driver, 20).until(EC.frame_to_be_available_and_switch_to_it((By.CSS_SELECTOR,"iframe.textarea[src='/framework/html/blank.html']")))
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "element_css_selecor"))).send_keys("character_sequence")
Using XPATH:
WebDriverWait(driver, 20).until(EC.frame_to_be_available_and_switch_to_it((By.XPATH,"//iframe[#class='textarea' and #src='/framework/html/blank.html']")))
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//a[#class='TlogBtn']/span[#class='mailicn']/img"))).send_keys("character_sequence")
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:
Switch to an iframe through Selenium and python
selenium.common.exceptions.NoSuchElementException: Message: no such element: Unable to locate element while trying to click Next button with selenium
selenium in python : NoSuchElementException: Message: no such element: Unable to locate element

In order to handle iframes on a web page you need to switch to the iframes first that are present on the page using this command:
driver.switch_to.frame(frame_id)
This tutorial has a working example of handling iframe using selenium with python which will made you able to get through this issue.

Related

Selenium NoSuchFrameException when waiting for combobox input

I have an element that is placed in 2 frames. So I wait for the parent frame to load, switch to it, wait for the child frame to load, switch to it, then i try to access my element. The frame switching throws no error but when I try to access the element within the child frame, it is throwing an selenium.common.exceptions.NoSuchFrameException with no message.
parentF = WebDriverWait(driver, 60).until(EC.visibility_of_element_located((By.ID, "parent")))
driver.switch_to.frame(parentF)
childF = WebDriverWait(driver, 60).until(EC.visibility_of_element_located((By.ID, "child")))
driver.switch_to.frame(childF)
program_select = WebDriverWait(driver, 60).until(EC.visibility_of_element_located((By.ID, "xyz")))
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 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'"]")))

How can I switch to the iframe using Selenium and python?

I've used Selenium for a number projects without problems. This one, however, no dice.
I'm trying to automate a check out process, and sometimes there is a prompt to re-input information. The window has a javascript popup (I think), and, while I can select the <div id="app"> portion without any problems, I CANNOT get find the iframe and focus on it.
So, this works:
driver.find_elements_by_id('app')
But, nothing works to recognize the frame and switch to it. For example, none these work:
driver.find_element_by_id()
driver.find_element_by_name()
driver.find_element_by_xpath()
And, I assume that because I can't find and switch to the iframe.
Help?
The element with the text as E-Mail Login 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.zoid-visible[title='ec_payment'][name^='__zoid__ec__payment']")))
Using XPATH:
WebDriverWait(driver, 20).until(EC.frame_to_be_available_and_switch_to_it((By.XPATH,"//iframe[#class='zoid-visible' and #title='ec_payment'][starts-with(#name, '__zoid__ec__payment')]")))
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:
Ways to deal with #document under iframe
Switch to an iframe through Selenium and python
selenium.common.exceptions.NoSuchElementException: Message: no such element: Unable to locate element while trying to click Next button with selenium
selenium in python : NoSuchElementException: Message: no such element: Unable to locate element
driver.switch_to.frame(iframe_elem)
or
driver.switch_to_frame(iframe_id)
in your case you can use :
driver.switch_to.frame(driver.find_element_by_tag_name("iframe"));
to switch back to main use:
driver.switch_to_default_content()
Try this code to switch to frame
frame = driver.find_element_by_xpath('//div[starts-with(#id, "zoid-ec-payment")]/iframe')
driver.switch_to.frame(frame)

selenium.common.exceptions.ElementNotInteractableException: Message: element not interactable while sending text to contenteditable div element

I am having trouble with a selenium send keys on discord. I am attempting to send a message to a user.
The error I get is:
selenium.common.exceptions.ElementNotInteractableException: Message: element not interactable
The HTML is as follows:
The Object im trying to send_keys that is highlighted by the xpath is as follows:
My code is as follows
inputMessage = wait.until(EC.visibility_of_element_located((By.XPATH,"//div[contains(text(),'Message #')]/..")))
#inputMessage = driver.find_element_by_xpath("//div[contains(text(),'Message #')]/..")
inputMessage.send_keys(msg,Keys.ENTER)
I have attempted several ways to try to solve the error but have not succeeded. Any help would be appreciated. Thank you.
The ElementNotInteractableException error tells you that you can't use the send_keys() method on this webElement. I can't really tell you what could work, considering the lack of information considering the problem, but here are some clues :
Using the ActionsChains to try to input what you want in the field:
from selenium.webdriver.common.action_chains import ActionChains
actions = ActionChains(self.driver)
actions.send_keys('your_data')
actions.perform()
Try inputMessage.click() before you try to send keys
Otherwise, it happened to me too, and the thing was that i tried to send keys to the div, and not to the element which was inside it.
Hopes it help !
HTML contenteditable Attribute
By using some JavaScript event handlers you can transform your web page into a full and fast rich text editor only by setting the contenteditable attribute on nearly any HTML element to make it editable. As an example, to create a <div> element whose contents an user can edit would be:
<div contenteditable="true">
This text can be edited by the user.
</div>
When an HTML element has contenteditable set to true, the document.execCommand() method is made available. This lets you run commands to manipulate the contents of the editable region. However, there seem to be some difference in usage of contenteditable across different browsers. As an example, when you press Enter or Return to create a new line of text inside an editable element:
Firefox inserted <br> elements
IE/Opera used <p> elements
Chrome/Safari used <div> elements
Firefox 60 wraps the separate lines in <div> elements, matching the behavior of Chrome, modern Opera, Edge, and Safari.
This usecase
As per the HTML it seems the next <div> with attribute aria-label="Message #Ticketing" has the property contenteditable="true". So ideally you should be able to invoke send_keys() on this element.
Solution
Finally, to interact with an element you need to to induce WebDriverWait for the element_to_be_clickable() and you can use either of the following Locator Strategies:
Using CSS_SELECTOR:
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "div[aria-label='Message #Ticketing'][data-slate-editor='true'][role='textbox']"))).send_keys(msg)
Using XPATH:
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//div[#aria-label='Message #Ticketing' and #data-slate-editor='true'][#role='textbox']"))).send_keys(msg)
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

How to Find Element Text within <span> using Selenium?

I am pretty new to Python and Selenium, and I have got my script to do what I want so far, but I have this current coding from the website:
<a onclick="realPostBack('ctl00$ctl00$mainContent$ContentPlaceHolder1$ucHub$ucSearchExplorer$dgContents$ctl00$ctl04$lnkContent', ''); return false;" id="ctl00_ctl00_mainContent_ContentPlaceHolder1_ucHub_ucSearchExplorer_dgContents_ctl00_ctl04_lnkContent" class="hub-content-item" actiontype="Secondary" href="javascript:__doPostBack('ctl00$ctl00$mainContent$ContentPlaceHolder1$ucHub$ucSearchExplorer$dgContents$ctl00$ctl04$lnkContent','')"><span>How to Project Wirelessly in Philly</span></a>
and I can't get it to click the link.
I've tried:
driver.find_element_by_text("How to Project Wirelessly in Philly")
and partial text
driver.find_element_by_id("ctl00_ctl00_mainContent_ContentPlaceHolder1_ucHub_ucSearchExplorer_dgContents_ctl00_ctl04_lnkContent")
I've tried by tag but all returning errors. Looking up on here, I've seen stuff with Xpath but I have no clue how to do that, but if someone here does, then a little help with that, or any other simple code that hopefully allows me to click that link. (I know i will have to do .click() to eventually click it, but i cant even find the element yet)
The desired element is a dynamic element, so invoke click() on it you have to induce WebDriverWait for the element to be clickable and you can use either of the following solutions:
Using CSS_SELECTOR:
element = WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "a.hub-content-item[id*='SearchExplorer'][actiontype='Secondary']>span")))
Using XPATH:
element = WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//a[#class='hub-content-item' and contains(#id,'SearchExplorer')][#actiontype='Secondary']/span[text()='How to Project Wirelessly in Philly']")))
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

Problem clicking an href=javascript using selenium web drive python

I am having an problem with clicking an menu item that has an link with an href with selenium web drive.
<a class="a-link-normal" href="javascript:;">Fiction</a>
Here is my code:
driver.find_element_by_xpath('//*[#id="div-fiction"]/span/a').click()
This only seem to hover over the linked name and highlight it but does not trigger the javascript. I tried reading all the other solutions but it all lead to just using the click() method. Does anyone know what is wrong or a different approach to this.
The desired element seems to be a JavaScript enabled element so you need to induce WebDriverWait for the desired element to be clickable and you can use either of the following solutions:
LINK_TEXT:
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.LINK_TEXT, "Fiction"))).click()
XPATH:
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//a[#class='a-link-normal' and contains(.,'Fiction')]"))).click()
You may try this:
driver.execute_script("arguments[0].click();", webelement to click)

Categories

Resources