Selenium: How to click a label - python

I'm trying to click this object with selenium (pyhton) using the code:
driver.find_element_by_('publicForm_customFields').click()
But I'm receiving this error:
id="publicForm_customFields" tabindex="0" type="radio" value="value"> is not clickable at point (480, 98). Other element would receive the click: value

"Other element would receive the click" means that you have another element over your element. There are a couple of options to get around this:
Try to find another element above in the DOM tree and click on it.
Use js click, you need to write a function like this:
def js_click(self, element):
element = driver.find_element_by_id("myid")
driver.execute_script("arguments[0].click();", element)
js script will click on the element even if it is intersected by another

There might be two possibilities:
1- Your locator to find element might be wrong or not unique.
2- You need to apply explicit wait till element is ready [load successfully] to be clickable.
Hope above possibilities might help you out, Or you share the link of the sight so I might debug correctly.

You are not passing any find method to the driver. Try refactoring the code to:
driver.find_element_by_id('publicForm_customFields').click()
Also, try using some sort of wait so the driver does not click before the page/element is loaded.
from selenium.webdriver.support import expected_conditions as EC
wait = WebDriverWait(driver, 10)
wait.until(EC.element_to_be_clickable((By.ID, 'publicForm_customFields'))).click()

Related

Error: Stale element is not attached to the page, after try statement

I have the following try statement, that basically finds a button that resets the current page I am in. In summary the page reloads,
try:
reset_button = D.find_element(By.XPATH,"//button[starts-with(#class,'resetBtn rightActionBarBtn ng-star-inserted')]")
reset_button.click()
D.implicitly_wait(5)
ok_reset_botton = D.find_element(By.ID,'okButton')
D.implicitly_wait(5)
print(ok_reset_botton)
ok_reset_botton.click()
D.implicitly_wait(5)
# Trying to reset current worksheet
except:
pass
print(D.current_url)
grupao_ab = D.find_element(By.XPATH,'//descendant::div[#class="slicer-restatement"][1]')
D.implicitly_wait(5)
grupao_ab.click()
The weird thing is every time that try statement get executed, I get the following log of error
selenium.common.exceptions.StaleElementReferenceException: Message: stale element reference: element is not attached to the page document
Which happens in the a following line of code according to the log
grupao_ab.click()
When I took a look at the reason given by selenium it say it is because the element is no longer on the given DOM, but the element grupao_ab, is not even being defined in that page so why it is giving me that error? If any extra information is needed just comment.
First of all, StaleElementReferenceException means that the web element reference you trying to access is no more valid. This normally happens after the page was reloaded. This is exactly what happens here.
What happened is as following: you clicked on reset button and immediately after that you collecting the grupao_ab element and shortly after that trying to click it. But between the moment you located the grupao_ab element with grupao_ab = D.find_element(By.XPATH,'//descendant::div[#class="slicer-restatement"][1]') and the line where you trying to click it, reloading started. So that previously collected web element, that actually is a reference to a physical element on the DOM, no more pointing to that web element.
What you can to do here is: after clicking on the refresh button set a short delay so that refreshing will start and after that wait for grupao_ab element to become clickable. WebDriverWait expected_conditions explicit waits should be used for that.
Also, you should understand that D.implicitly_wait(5) is not a pause command. It sets the timeout for find_element and find_elements methods to wait for presence of the searching element. Normally we never set this timeout at all since it's better to use WebDriverWait expected_conditions explicit waits, not implicitly_wait implicitly waits. And you should never mix these two types of waits.
And even if you want to set implicitly_wait to some value normally no need to set it again, this setting is applied to the entire driver session.
Please try changing your code as following:
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
wait = WebDriverWait(driver, 20)
try:
wait.until(EC.element_to_be_clickable((By.XPATH, "//button[starts-with(#class,'resetBtn rightActionBarBtn ng-star-inserted')]"))).click()
wait.until(EC.element_to_be_clickable((By.ID, "okButton"))).click()
print(ok_reset_botton)
time.sleep(0.5) # a short pause to make reloading started
except:
pass
print(D.current_url)
#wait for the element on refreshed page to become clickable
wait.until(EC.element_to_be_clickable((By.XPATH, '//descendant::div[#class="slicer-restatement"][1]'))).click()

What is the correct way to correctly identify an object via Python and Selenium?

I am currently dabbling in Python in combination with Selenium. I can't get any further at one point.
Enclosed you can see three screenshots. At https://www.easycredit.de I already click on the button (1). After that I get to the next page. I would like to click this button (2) now. In Screenshot 3 you can see the location in the source code.
# link to Chromedriver
browser = webdriver.Chrome('/usr/local/bin/chromedriver')
button = browser.find_element(By.CLASS_NAME, 'econ-button btn btn-primary')
button.click()
The error:
NoSuchElementException: no such element: Unable to locate element: {"method":"css selector","selector":".econ-button btn btn-primary"}
(Session info: chrome=104.0.5112.79)
Here are my questions:
hy does it not work with this code?
How do you find out with which procedure it works best in a case like this?
How do you choose whether to identify an element by XPATH, ID etc.?
Thanks
econ-button btn btn-primary are actually 3 class names.
By.CLASS_NAME gets only single class name parameter.
To work with locators containing multiple class names you can use By.XPATH or By.CSS_SELECTOR.
As for me both the above methods are good, each of them having several cons and pros.
So, here you can use
browser.find_element(By.CSS_SELECTOR, 'button.econ-button.btn.btn-primary')
Or
browser.find_element(By.XPATH, "//button[#class='econ-button btn btn-primary']")
Generally, you can use By.CSS_SELECTOR or By.XPATH. No need to utilize By.ID or By.CLASS_NAME since they are actually internally immediately translated to By.CSS_SELECTOR or By.XPATH :)
Some people preferring to use By.CSS_SELECTOR while others prefer By.XPATH.
As I mentioned previously, each of the above 2 methods having cons and pros.
For example you can locate elements by their texts with XPath only. XPath supports locating parent element based on their child nodes.
On the other hand XPath will not work so good on Firefox driver while it works perfectly on Chrome driver etc.
UPD
The locator for the second nein radio button can be:
"//label[.//input[#data-econ-property='kreditdaten-beduerfnisfragen-flexibilitaetGewuenscht'][#value='radio3']]"
So, Selenium click can be done with
browser.find_element(By.XPATH, "//label[.//input[#data-econ-property='kreditdaten-beduerfnisfragen-flexibilitaetGewuenscht'][#value='radio3']]").click()
And so on with other buttons
The element Zu den finanziellen Angaben is a dynamic element. So to click 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(browser, 20).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "button.econ-button.btn.btn-primary[value='Zu den finanziellen Angaben']"))).click()
Using XPATH:
WebDriverWait(browser, 20).until(EC.element_to_be_clickable((By.XPATH, "//button[#class='econ-button btn btn-primary' and #value='Zu den finanziellen Angaben']"))).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

.click() and .send_keys() methods not being recognized Python Selenium

I'm using Selenium in Python to click a text entry field and write some text into it. Neither the .click() nor .send_keys() methods are being recognized. Can someone help with this?
Also, is there a way to stop Selenium from printing to the console automatically? My program is console-based and Selenium is writing things to an input() that I gave because it prints to the console.
Here is a code snippet:
url = "https://weather.com/weather/today/l/69ef4b6e85ca2de422bea7adf090b06c1516c53e3c4302a01b00ba763d49be65"
browser = webdriver.Edge("Web Scrapers\msedgedriver.exe")
browser.get(url)
textbox = browser.find_element_by_id("LocationSearch_input")
textbox.click()
textbox.send_keys(zipcode)
textbox.send_keys(Keys.ENTER)
you could try the explicitWait hope this will work for you
WebDriverWait(browser,10).until(EC.element_to_be_clickable((By.XPATH,"//input[#type='text']"))).send_keys("20874",Keys.RETURN)
I would suggest you to do it with explicit wait.
I am giving this answer, cause none of the answer's are really using Explicit waits with ID attribute :
driver.maximize_window()
driver.implicitly_wait(30)
driver.get("https://weather.com/weather/today/l/69ef4b6e85ca2de422bea7adf090b06c1516c53e3c4302a01b00ba763d49be65")
wait = WebDriverWait(driver, 10)
wait.until(EC.element_to_be_clickable((By.ID, "LocationSearch_input"))).send_keys('60007' + Keys.RETURN)
wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR, "div[class^='CurrentConditions--dataWrapperInner']"))).click()
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 what I can tell, everything is working fine here, however you are pointing your textbox variable to the wrong HTML element.
LocationSearch_input is a hidden label that isn't directly attached to the searchbox. I would try pointing it to
SearchInput--SearchInput--M7lKl SearchInput--enableSearchIcon--1Ugsx, one of the parent elements.
At least testing in firefox, it's a timing thing. The click works. The error of element not interactable (not reachable by keyboard) comes off of the send_keys line. If we wait after the click(), the element becomes reachable by keyboard.
The following could probably be refined (really don't like sleep, but sometimes it works), but works for me:
url = "https://weather.com/weather/today/l/69ef4b6e85ca2de422bea7adf090b06c1516c53e3c4302a01b00ba763d49be65"
browser.get(url)
browser.find_element_by_id('LocationSearch_input').click()
time.sleep(5)
browser.find_element_by_id('LocationSearch_input').send_keys('Boston')
At that point you need to click on whichever of the 10 options is what you really want.

Selenium can't find radio button

I'm automating the testing process we have in servicenow, but I can't select a radio button in a form. I've used multiple selectors to fix this but nothing has worked.
ServiceNow HTML:
these are the selectors I have used:
driver.find_element_by_css_selector('input[value="Add"]').click()
driver.find_element_by_xpath('//input[#value="Add"]').click()
None of these have worked and there's not iframe tag in the body to swicth to. Thank you!
The following are a few reasons why I couldn't find an element.
Currently on the wrong window/frame.
Synchronization issues - script is looking before the element has loaded. Solved with explicit waits. (see #cruisepandey's answer)
The element was different due to mobile vs desktop. Should be noticable if you disable headless. I advise dumping the HTML from selenium just to be sure.
When I'm unsure I'll start trying to find it's parent element, walking up the scope until I'm able to get a proper element. That's usually where I figure out what the problem was.
Can I find the parent label element?
Can I find the grandparent div element?
Can I find the greatgrandparent fieldset?
And so on...
You can try with expicit wait :
wait = WebDriverWait(driver, 10)
element = wait.until(EC.element_to_be_clickable((By.XPATH, "//input[#value='Add']")))
element.click()
Imports :
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
Update 1 :
wait = WebDriverWait(driver, 10)
radioBtn = wait.until(EC.element_to_be_clickable((By.XPATH, "//input[#value='Add']")))
driver.execute_script("arguments[0].checked = true;", radioBtn)

Problems with clicking a button

I wanted the program to click the 'PLAY' Button on spotify to play a song, but sadly I get this error
selenium.common.exceptions.JavascriptException: Message: javascript error: arguments[0].click is not a function
The code I tried is
WebDriverWait(driver, 3).until(EC.presence_of_element_located((By.XPATH,"//*[text()='PLAY']")))
time.sleep(1)
driver.execute_script("arguments[0].click();", driver.find_element_by_xpath("//*[text()='PLAY']"))
Can someone help me to find the button and click it, I tried also the
driver.find_element_by_xpath("//*[text()='PLAY']").click()
But I get the error element is not interactable
WebDriverWait wait = new WebDriverWait(driver, 10);
wait.until(ExpectedConditions.visibilityOf(driver.find_element_by_xpath("//div[#class='TrackListHeader__button
TrackListHeader__button--top']//button")));
Thread.sleep(1000);
driver.find_element_by_xpath("//div[#class='TrackListHeader__button
TrackListHeader__button--top']//button").click();
also try this one
EC has a good method for verifying element is clickable before making an action element_to_be_clickable.
Also, I found over 20 elements on Spotify using your XPath, so I modified it to look for button instead of *.
Try this:
WebDriverWait(driver, 3).until(EC.element_to_be_clickable((By.XPATH,"//button[text()='PLAY']")))
driver.find_element_by_xpath("//button[text()='PLAY']").click()
I hope this helps. Good luck!

Categories

Resources