I'm coding a selenium automated bot, and I want to send keys to a input that I got from iFrame, check the code line:
username = bot.find_element_by_xpath("//iframe[#title='Registration form' and #class='top']")
Can you guys help me? I can click on the input, but, on send the keys, it doesn't work and deselect the input field.
You don't send character sequence to the <iframe> element rather you would send character sequence to the <input> element within the <iframe>. As the the desired element is within a <iframe> so you have to:
Induce WebDriverWait for the desired frameToBeAvailableAndSwitchToIt.
Induce WebDriverWait for the desired elementToBeClickable.
You can use either of the following Locator Strategies:
Using XPATH:
WebDriverWait(driver, 20).until(EC.frame_to_be_available_and_switch_to_it((By.XPATH,"//iframe[#title='Registration form' and #class='top']")))
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//input[#attribure_name='attribute_value']"))).send_keys("Igor Duca")
Using CSS_SELECTOR:
driver.get('https://www.t-online.de/themen/e-mail')
WebDriverWait(driver, 20).until(EC.frame_to_be_available_and_switch_to_it((By.CSS_SELECTOR,"iframe.top[title='Registration form']")))
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "input[attribure_name='attribute_value']"))).send_keys("Igor Duca")
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
You can find a relevant detailed discussion in How to extract all href from a class in Python Selenium?
References
You can find a couple of relevant discussions in:
Ways to deal with #document under iframe
Is it possible to switch to an element in a frame without using driver.switchTo().frame(“frameName”) in Selenium Webdriver Java?
Related
I'm trying to accept cookies with Selenium, but the accept button is not found. I am not familiar with Selenium and I don't know how to debug. For instance, if I try to accept cookies from stackoverflow.com.
This is my code:
driver = webdriver.Chrome("chromedriver")
driver.get("https://stackoverflow.com")
WebDriverWait(driver,10).until(EC.element_to_be_clickable((By.XPATH, "//button[contains(#class, 'flex--item')]/div[text()='Accept all cookies']"))).click()
WebDriverWait(driver,10).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "flex--item s-btn s-btn__filled js-cookie-settings"))).click()
Whatever the selected option (Xpath or CSS), the button is not found. How can I debug my Xpath or CSS selector ? What is the solution ?
To click() on the element Accept all cookies' you need to induce WebDriverWait for the element_to_be_clickable() and you can use either of the following locator strategies:
Using XPATH and normalize-space():
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//button[normalize-space()='Accept all cookies']"))).click()
Using XPATH and contains():
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//button[contains(., 'Accept all cookies')]"))).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
I have bar graph in a website and need to click on it. Using developer tools, I am getting below xpath:
/html/body/root/main/portal/div[2]/div/div/div/my-portal/div[3]/td-tyr/td-tyr/div[1]/filter-bar/div/div[3]/div[1]/div[1]/bar-chart/div/div[1]/div/svg/g[4]/g[1]/rect[1]
When using the above in xpath, it's giving invalid expression. Any help will be appreciated.
To click on the Bar Graph as the element have a parent <svg> element you can use either of the following Locator Strategies:
Using css_selector:
driver.find_element(By.CSS_SELECTOR, "bar-chart svg g rect.highcharts-point.highcharts-color-0.highcharts-point-hover[x='31.5'][y='40.5']").click()
Using xpath:
driver.find_element(By.XPATH, "//bar-chart//*[name()='svg']//*[name()='g']//*[name()='rect'][#x='31.5' and #y='40.5']").click()
Ideally to click on a clickable element you need 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, "bar-chart svg g rect.highcharts-point.highcharts-color-0.highcharts-point-hover[x='31.5'][y='40.5']"))).click()
Using XPATH:
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//bar-chart//*[name()='svg']//*[name()='g']//*[name()='rect'][#x='31.5' and #y='40.5']"))).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
References
You can find a couple of relevant discussions on interacting with SVG element in:
How to access to 'rect' type element through Selenium-Python
Clicking on svg using selenium python
There are basically 4 ways to click in Selenium.
I will use this xpath
//rect[#class='highcharts-point highcharts-color-0 highcharts-point-hover'][#stroke='#ffffff']
Code trial 1:
time.sleep(5)
driver.find_element_by_xpath("//rect[#class='highcharts-point highcharts-color-0 highcharts-point-hover'][#stroke='#ffffff']").click()
Code trial 2:
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//rect[#class='highcharts-point highcharts-color-0 highcharts-point-hover'][#stroke='#ffffff']"))).click()
Code trial 3:
time.sleep(5)
button = driver.find_element_by_xpath("//rect[#class='highcharts-point highcharts-color-0 highcharts-point-hover'][#stroke='#ffffff']")
driver.execute_script("arguments[0].click();", button)
Code trial 4:
time.sleep(5)
button = driver.find_element_by_xpath("//rect[#class='highcharts-point highcharts-color-0 highcharts-point-hover'][#stroke='#ffffff']")
ActionChains(driver).move_to_element(button).click().perform()
Imports:
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.action_chains import ActionChains
PS : Please check in the dev tools (Google chrome) if we have unique entry in HTML DOM or not.
Steps to check:
Press F12 in Chrome -> go to element section -> do a CTRL + F -> then paste the xpath and see, if your desired element is getting highlighted with 1/1 matching node.
I have webpage where I am trying to login to it. When I use find element by name method to find the elements I get element not interactable error but when i use find element by xpath it works fine and no error. Can anyone explain me why it is not able to interact with element when found by name method?
Same issue is observed for User ID, Password and Login elements.
I am sure even when using by name method website is loaded and is ready for use.
Below is the screenshot of the Webpage login
My HTML code is as below
Below is the code am using
import xlrd
import openpyxl
import requests
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
import time
from selenium.webdriver.support.ui import Select
from selenium.webdriver.chrome.options import Options
from selenium.webdriver import ChromeOptions, Chrome
opts = webdriver.ChromeOptions()
opts.add_experimental_option("detach", True)
def login_to_Portal(mBrowser):
mBrowser.find_element_by_id("userNameTrucks")
mBrowser.find_element_by_id("userNameTrucks").clear()
mBrowser.find_element_by_id("userNameTrucks").send_keys("xxxxx")
mBrowser.find_element_by_xpath("/html/body/div/router-view/section/div[2]/ul/li[4]/input")
#mBrowser.find_element_by_name("password").clear()
mBrowser.find_element_by_xpath("/html/body/div/router-view/section/div[2]/ul/li[4]/input").send_keys("xxxxx")
mBrowser.find_element_by_xpath("/html/body/div/router-view/section/div[2]/ul/li[5]/button").click()
#mBrowser.find_element_by_class_name("au-target").click()
#mBrowser.find_element_by_name("target")
#mBrowser.find_element_by_name("target").click()
mBrowser = webdriver.Chrome(executable_path = r'C:\chromedriver_win32\chromedriver.exe', options = opts )
mBrowser.get("https://grouptrucksportal.volvo.com/gpp/index.html")
time.sleep(10)
mBrowser.find_element_by_xpath("/html/body/div/compose[1]/section/div[1]/map/area[1]")
mBrowser.find_element_by_xpath("/html/body/div/compose[1]/section/div[1]/map/area[1]").click()
time.sleep(3)
mBrowser.find_element_by_xpath("/html/body/div/compose[3]/section/div[2]/div/ul/li[4]/a")
mBrowser.find_element_by_xpath("/html/body/div/compose[3]/section/div[2]/div/ul/li[4]/a").click()
time.sleep(5)
login_to_Portal(mBrowser)
Now am using xpatha and everything works fine.
When i use find element by name it fails with not interactable error
This error message...
ElementNotInteractableException: Message: element not interactable
...implies that the WebElement with whom you are trying to interact isn't interactable (isn't in interactable state) at that moment.
The two(2) main reasons for this error are:
Either you are trying to interact with a wrong/mistaken element.
Or you are invoking click() too early even before the element turns clickable / interactable.
Analysis and Solution
There are a couple of things you need to take care. In case of websites like Truck Dealer Online once you navigate to the Login page instead of find_element_by_id() or find_element_by_name() you have to induce WebDriverWait for the element_to_be_clickable().
As an example, to send a character sequence to the user name field you can use either of the following Locator Strategies:
Using ID:
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.ID, "userNameTrucks"))).send_keys("SrinivasVenkataram")
Using CSS_SELECTOR:
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "input#userNameTrucks"))).send_keys("SrinivasVenkataram")
Using XPATH:
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//input[#id='userNameTrucks']"))).send_keys("SrinivasVenkataram")
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 detailed discussion on ElementNotInteractableException in:
ElementNotInteractableException: Message: element not interactable error sending text in search field using Selenium Python
I want to click on an element as follows:
//select[#name='instructionSelection']
But its not clicking with Selenium on IE 11.
HTML:
You have to switch to iframe using name=InvoiceDeatils before interacting with the element.
Not sure which language you are using. Providing the snippet in python below.
driver.switch_to.frame(driver.find_element_by_name('InvoiceDeatils'))
# now click on the element
driver.find_element_by_xpath("//select[#name='instructionSelection']").click()
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 the following Locator Strategies::
Using CSS_SELECTOR:
WebDriverWait(driver, 10).until(EC.frame_to_be_available_and_switch_to_it((By.CSS_SELECTOR,"iframe[name='invoiceDeatils'][src*='invoiceDeatils']")))
WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "select[name='instructionSelection']"))).click()
Using XPATH:
WebDriverWait(driver, 10).until(EC.frame_to_be_available_and_switch_to_it((By.XPATH,"//iframe[#name='invoiceDeatils' and contains(#src, 'invoiceDeatils')]")))
WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.XPATH, "//select[#name='instructionSelection']"))).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 relevant discussion in:
Ways to deal with #document under iframe
I can't find the correct xpath to use for retweet and like on this page: https://twitter.com/snowfulls/status/1198269659465818115
Also, I need help finding the xpath for the second retweet button that comes up to confirm the retweet.
Is there a way to find xpaths automatically?
To answer your first question -- no, there is not a way to find XPaths automatically unless you use some kind of scanner tool. These XPaths are not always accurate though. The best approach is to use an XPath browser extension helper that will allow you to test out XPath expressions on a page in real-time. That is what I have used to help develop my solution.
To click the "Like" button on a tweet, you can use the following code:
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
# ensure the above references are added to use WebDriverWait correctly
# wait for the element to exist
like_button = WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.XPATH, "//div[#aria-label='Like']")))
# click the like button
like_button.click()
To click the retweet button, similarly:
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
# ensure the above references are added to use WebDriverWait correctly
# wait for the element to exist
retweet_button = WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.XPATH, "//div[#aria-label='Retweet']")))
# click the retweet button
retweet_button.click()
# now, confirm the retweet:
retweet_confirm = WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.XPATH, "//div[#data-testid='retweetConfirm']")))
# click the retweet confirm button
retweet_confirm.click()
The above solution uses a few simple extensions of Selenium library -- mainly, WebDriverWait and ExpectedConditions class. WebDriverWait allows us to wait up to a specified time for a condition to occur. This goes hand-in-hand with ExpectedConditions class, which measures the status of elements on the page to confirm whether or not a WebElement meets a certain condition.
So, WebDriverWait(driver, 10).until(EC.presence_of_element_located means "Wait up to 10 seconds for the presence of a WebElement" -- this WebElement then gets specified in the locator strategy, By.XPath, "....".
Hope this explanation helps a bit.