We are waiting for a button identified by xpath to be clickable with:
ExpectedConditions.elementToBeClickable()
and then execute click on this button in Selenium.
We then get an error that:
another element would receive the click at position (x, y).
It is possible that this button is moving around slightly on the page during page loading as other buttons next to it are loading.
Why would Selenium report that the button is clickable and then not be able to click it? I understand that's what this condition is for. This execution happens in the same line.
How could we solve this problem?
CodePudding user response:
Imagine that you want to interact with a button and that button is in middle of the page.
Case1:
You do not open the browser in full-screen mode through an automation script. Then its position will not be in the middle of the page.
you can solve this issue by just introducing
driver.maximize_window()
Case2:
Maybe in the automation script, some pop up
or ads
shows up and that really hides the button in the background. In this case, you will likely encounter another element would receive the click at position (x, y).
Solution: You should determine what kind of pop up/Alert/ads
they are and handle them separately then only you should interact with the intended button.
Case3:
It could also occur cause you might have open (let's say calendar to select a start/end date) and then because of that web elements that are just under the calendar view won't be accessible to selenium and only the Calendar view will get the click. [This should answer your query]
In General, I use actions class
or JS
to inject js code
in the selenium script.
If you are using Selenium with Python then you can use
Use
ActionChains
:ActionChains(driver).move_to_element(WebDriverWait(driver, 20).until(EC.visibility_of_element_located((By.CSS_SELECTOR, "CSS here")))).click().perform()
Use
execute_script
:wait = WebDriverWait(driver, 20) button= wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR, "CSS here"))) driver.execute_script("arguments[0].click();", button)
In Python you'd need the below imports as well:
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
CodePudding user response:
Using ExpectedConditions.elementToBeClickable()
allows our code to halt program execution, or freeze the thread, until the condition we pass it resolves. The condition is called with a certain frequency until the timeout of the wait is elapsed. This means that for as long as the condition returns a falsy value, it will keep trying and waiting. Thus Explicit waits allows us to wait for a condition to occur which inturn synchronises the state between the browser and its DOM Tree, and the WebDriver script.
Even with ExpectedConditions.elementToBeClickable()
there can be instances while invoking click() on the desired element you may face either of the following errors:
Element <a href="/path1/path2/menu">...</a> is not clickable at point (415, 697). Other element would receive the click: <div >...</div>
or
WebDriverException: Element is not clickable at point (36, 72). Other element would receive the click
Reason and Solution
There can be numerous reasons for this error to occur and a couple of them and their remediation are as follows:
Though the element is within the Viewport but may be hidden behind the cookie banner. In such cases you have to accept the cookie consent before you interact with the desired element as follows:
new WebDriverWait(driver, 20).until(ExpectedConditions.elementToBeClickable(By.xpath("cookieConsentXpath"))).click(); new WebDriverWait(driver, 20).until(ExpectedConditions.elementToBeClickable(By.xpath("elementXpath"))).click();
The element may be clickable but behind a loader. In such cases you have to wait for the loader to disappear before you interact with the desired element as follows:
new WebDriverWait(driver, 20).until(ExpectedConditions.invisibilityOfElementLocated(By.cssSelector("loader_cssSelector"))); new WebDriverWait(driver, 20).until(ExpectedConditions.elementToBeClickable(By.cssSelector("element_cssSelector"))).click();