Explicit wait not working for a checkbox selenium - python

I'm trying to implement an explicit wait before giving a click on a checkbox:
WebDriverWait(self.driver, 10).until(EC.element_to_be_clickable((By.XPATH, "pay_type_list_item_id_salary"]")))
self.driver.find_element_by_xpath('//input[#id="pay_type_list_item_id_salary"]').click()
My problem is that my explicit wait keeps sending the error:
not clickable at point (663, 478). Other element would receive the click.
I'm trying to use different kind of explicit waits like visibility_of_element_located or invisibility_of_element_located (using an element from the previous step on my script), but no luck with those options.
If I add a time.sleep(1) between the 2 lines my scripts works but I know it's not the most efficient thing to use time.sleep.
The previous step before this one opens a calendar and I'm not sure if it tries to give the click when the calendar is closing and that's the reason to receive this error.

The error you are getting is indicating that another element is covering the element you are trying to click. If you look at the error message (you really should post the full error message in your question), it will tell you the HTML of the element that is in the way. That will give you a good idea of what element is blocking the click so you can find it and figure out what part of the page it is. Then you can wait for it to get out of the way. From your description, it sounds like you need to add a wait for the calendar to close.

Related

Selenium: Can't find element by class name in any way

I have this problem where I can't access a button trough it's class name in any way I could think of.
This is the HTML:
<button class="expand-button">
<faceplate-number pretty="" number="18591"><!---->18.591</faceplate-number> weitere Kommentare anzeigen
</button>
I tried to access it using:
driver.find_element(By.CLASS_NAME, "expand-button")
But the error tells me that there was no such element.
I also tried X-Path and Css-Selector which both didn't appear to work.
I would be glad for any help!
Kind Regards and Thanks in advance
Eirik
Possible issue 1
It could be because you check before the element is created in the DOM.
One way to solve this problem is by using the waites option like below
driver.implicitly_wait(10)
driver.get("http://somedomain/url_that_delays_loading")
my_dynamic_element = driver.find_element(By.ID, "myDynamicElement")
You can read more about it here: https://www.selenium.dev/documentation/webdriver/waits/#implicit-wait
Another way is by using the Fluent Wait whhich marks the maximum amount of time for Selenium WebDriver to wait for a certain condition (web element) becomes visible. It also defines how frequently WebDriver will check if the condition appears before throwing the “ElementNotVisibleException”.
#Declare and initialise a fluent wait
FluentWait wait = new FluentWait(driver);
#Specify the timout of the wait
wait.withTimeout(5000, TimeUnit.MILLISECONDS);
#Sepcify polling time
wait.pollingEvery(250, TimeUnit.MILLISECONDS);
#Specify what exceptions to ignore
wait.ignoring(NoSuchElementException.class)
#specify the condition to wait on.
wait.until(ExpectedConditions.element_to_be_selected(your_element_here));
you can also read more about that from the official documentation
https://www.selenium.dev/documentation/webdriver/waits/#fluentwait
Possible issue 2
it is also possible that the element might be partially or completely blocked by an element overlaying it. If that is the case, then you will have to dismiss the overlaying element before you will be able to perform any action on your target

Finding XPath without using inspecting element?

I am making an automation for download data from a weather institution.
The issue is that in my effort to make it more independent I am trying to make Selenium to Tab keys to a certain spot, so the Browser focus can "Walk" to the download button. When I call the click() function it doesn't do anything. So I tried to Extract the XPath with the function get_attribute("xpath") but it returns None. How I can extract the XPath?
I am going to paste the issue down here:
Bandera=driver.find_element_by_xpath('/html/body/div[2]/div[2]/div/div[3]/div/div/div/div[1]/div/div/div[2]/div/table/tbody/tr[1]/td[1]/div/input')
Bandera.click()
Bandera.click()
## So Here i just select and dis-select a checkbox just to be near the Download button.
actions = ActionChains(driver)
actions.send_keys(Keys.TAB * 1 )
actions.perform()
#Here i just tabed to the button
Accion=driver.switch_to.active_element
#Maybe, here is when i lost the focus of the button?
Descarga_Actual=Accion.get_attribute("xpath")
Thank you and sorry to borrow your time.
To make a click on hover I would use the following sequence:
your_dropdown_locator.click()
dropdown_option = driver.find_element_by_xpath("dropdown option locator")
actions = ActionChains(driver)
actions.move_to_element(dropdown_option)
actions.click().perform()
But, this is the approach that is usually used for dropdowns.
You use: driver.find_element_by_xpath('/html/body/div[2]/div[2]/div/div[3]/div/div/div/div[1]/div/div/div[2]/div/table/tbody/tr[1]/td[1]/div/input') This is the main problem of your code.
If you pasted html code of this dropdown (or button you need to click), people would help you to find a better locator. XPath/CSS must be unique. In your case the locator is very bad.
Also, I see no sense making Bandera.click() two times.
In your case, as I understand, you just need to click the button. So the locator is your main problem.
You need to find the correct locator, to wait till the button is clickable and then to click it.
Another problem in what you are trying to do:
get_attribute("xpath") looks like incorrect expectation of how get_attribute function works. Check at least here what this function means Python Selenium: Find object attributes using xpath

How to click the Continue button on website using selenium in python?

I am trying to write a code that is able to auto apply on job openings on indeed.com. I have managed to reach the last stage, however, the final click on the application form is giving me a lot of trouble. Please refer the page as below
Once logged in to my profile, I go to the relevant search page, click on the listing I am interested in and then on the final page (shown above) I am trying to click on the continue button using xpath as follows:
driver.get("https://in.indeed.com/jobs?q=data%20analyst&l=Delhi&vjk=5c0bd416675cf4e5")
driver.find_element_by_xpath('//*[#id="apply-button-container"]/div[1]/span[1]').click()
driver.find_element_by_xpath('//*[#id="form-action-continue"]')
However, this gives me an error:
Message: no such element: Unable to locate element: {"method":"xpath","selector":"//*[#id="form-action-continue"]"}
Having gone through some suggestions on the net I have even tried the following:
driver.get("https://in.indeed.com/jobs?q=data%20analyst&l=Delhi&vjk=5c0bd416675cf4e5")
driver.find_element_by_xpath('//*[#id="apply-button-container"]/div[1]/span[1]').click()
WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.XPATH, '//*[#id="form-action-continue"]')))
But then this gives me a timeout error
TimeoutException: Message:
Will appreciate some help on this.
From it seems, on that form there are multiple iframes, therefore the reason for your errors.
You need to get the first iframe, switch to it, get the second iframe inside the first one, switch to it and only afterwards you'll be able to get the continue button.
Something like this should do the trick:
frame_1 = driver.find_element_by_css_selector('iframe[title="Job application form container"')
driver.switch_to.frame(frame_1)
frame_2 = driver.find_element_by_css_selector('iframe[title="Job application form"]')
driver.switch_to.frame(frame_2)
continue_btn = driver.find_element_by_css_selector('#form-action-continue')
continue_btn.click()
Once I had a similar issue and standard time.sleep() until the form (or continue button) appears helped me. Try it instead of WebDriverWait, maybe it will work.

Click an element after a particular time

I have a website having youtube iframe. I want to click the replay button after the video gets over. I switched to youtube iframe and found the play button. But how can I click it after a particular time period(like after the video gets over) using selenium(python). Here the element to be clicked is always available but i need to click it only after a particular time.
driver.switch_to.frame(driver.find_element_by_xpath("//iframe[#id='YTPlayer']"))
driver.implicitly_wait(10000)
driver.find_element_by_css_selector(".ytp-play-button.ytp-button").click()
Tried Explicit wait as well but the conditions dont match.
An implicit wait tells WebDriver to poll the DOM for a certain amount of time when trying to find any element (or elements) not immediately available. The default setting is 0. Once set, the implicit wait is set for the life of the WebDriver object.
This is probably not what you want as your element is available all the time.
Instead you can just run time.sleep() within your code.
Like this:
driver.switch_to.frame(driver.find_element_by_xpath("//iframe[#id='YTPlayer']"))
time.sleep(1)
driver.find_element_by_css_selector(".ytp-play-button.ytp-button").click()
However instead you should try to find a condition that needs to be satisfied and then click the button instead.
Example:
driver.switch_to.frame(driver.find_element_by_xpath("//iframe[#id='YTPlayer']"))
while True:
if your-condition:
driver.find_element_by_css_selector(".ytp-play-button.ytp-button").click()
break
time.sleep(1)
You could also use Explicit Waits as described here: http://selenium-python.readthedocs.io/waits.html

Rewrite click() method in Selenium 2 (python)

I'm using Seleniun 2 webdriver (python) to run auto tests on IE browser.
One of major bugs in IE webdriver is that click() method does not work in 100% of cases. It happens sometimes when IE browser cannot set/looses focus on element. So, there's a workaround i googled to solve the problem- first the parent element must be clicked/selected. After that click() on the current element always works.
I would like to add my own method, named for ex. ieclick() that would do something like:
element = driver.find_element_by_id('id')
parentElement = element.find_element_by_xpath('..')
parentElement.click()
element.click()
Instead of writing all this code i would like to make:
driver.find_element_by_id('id').ieclick()
But i don't know how to implement this. I'm lost in Selenium modules code. I know that selenium class has click() method but i can't understand how can i rewrite it/add my own and make it useble for all this find_element_by_id, find_element_by_xpath etc.
Can someone help me to understand this implementation or maybe paste a link to some sort of explanation/example/lesson ?
The only reason that an element would not receive a click is because :
The element is disabled.
The element is invisible (therefore, cannot interact with it)
The element is not listening for any clicks (not binded)
My guess is that your "inconsistency issue" is coming form the third reason.
Consider the following:
<a href="dosomething">
<span id="spanclick">Click me</span>
</a>
Doing driver.find_element_by_id("spanclick").click() would not work, because it's the <a> element that is receiving the click, not the <span>.
It's your responsibility as the test writer to determine which element is receiving the click. My suggestion would be use debugging anytime you are in doubt. I've actually had a scenario where an <li> was receiving the actions of the mouse, not the <a>. By using Watch Expressions you are able to find what element is receiving the actions.
Seems i was exaggerating the difficulty.
selenium\webdriver\remote\webelement.py
Added code right after native click() method:
def ieclick(self):
"""2013-12-27. Surely clicks the element in IE."""
parent = self.find_element(by=By.XPATH, value='..')
parent._execute(Command.CLICK_ELEMENT)
try:
self._execute(Command.CLICK_ELEMENT)
except:
pass

Categories