Selenium clickable element clicked at wrong position? - selenium

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?

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

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 ... is not clickable at point (415, 697). Other element would receive the click: <div class="cc-content">...</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();

Related

Element not interacable

I have this error "element not interactable" When I try to click a drop down list with selenium. However in debug mode, when I inspect ( press F12 ) before the break points and I continue to run then the test is passed. So my question is Why the elements can be clicked and what should I do to prevent the situation again. Many thanks!
You have to add wait / delay before accessing the elements to let the elements be fully loaded on the page before accessing them.
The simplest way is to add hardcoded sleep, like
time.sleep(5)
The better way is to use explicit way implemented by expected conditions.
Few things to note down,
Always launch browser in full screen mode.
driver.maximize_window()
this code should be written before driver.get()
Whenever you get element not interactable, try to use action chains to click or send_keys :
something like this :-
from selenium.webdriver.common.action_chains import ActionChains
action = ActionChains(driver)
action.move_to_element('your web element here').click().perform()
Make sure that using Selenium, the desired web element should be in Selenium view port.
in order to resolve this, you may have to scroll down to let Selenium know where exactly the element is.

Selenium is not able to find the element even though it exist

It is the line of code that i am using to find the element using chrome web driver and python
This the error that is thrown everytime when i try to run the code
These are the buttons on the header bar and I am trying that my code should click the html button
This is the html code for the efforts button which i am trying to target using selenium so that it can click here but it always says no such element found
I have even created a seperate function to again and again find the element and sleep for 5 sec after every successful attempt until it has clicked on the element but still no luck it runs on forever without ever finding the element
This is where i am calling the function explained in the 5th picture. Here driver is chromedriver and it keeps on repeating for 10 times with 5 sec intervals but still no luck and i am continuously watching the chrome window where driver do all the work and the page has loaded but even after it is loaded it is still not working.
It is the beginning of entire html code from inspect element in case needed by someone
This is the remaining HTML code with EFFORTS area selected in case needed
I have even tried using shadow root but that is also not working and i am also not sure that this is a case of shadow root as i have not seen shadow root specified in html when i checked the html code.
The element you are trying to locate is under iframe with class iframeStyle. First switch to that iframe to access the Efforts link.
try below xpath using xpath contains to resolve your issue:
WebDriverWait(driver, 30).until(
EC.element_to_be_clickable((By.XPATH, "//a[contains(text(), 'EFFORTS')]")))
or
WebDriverWait(driver, 30).until(
EC.element_to_be_clickable((By.ID, "tmsMobileId")))
Note : please add below imports to your solution
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
If you still facing no such element exception then please check if your element is present under iframe. If so then you need to switch iframe before handling EFFORTS anchor tag

Finding xpath of an element that appears for a very short amount of time

Is there a good method to find the xpath of an element that only appears very briefly (e.g. for a second or two, like a loading screen).
If I click within an application and a short loading screen appears I would like to find the xpath of the loading element so I can have selenium wait until the element is no longer on the page before continuing.
Sometimes the loading screen appears over the element I want to click and catches the click instead.
Thanks!
Assuming that you are struggling to find XPath of the element that quickly disappears from the page before you could inspect and find the xpath.
You can try opening the console in the webpage by using Ctrl+Shift+I.
Then navigate to the Network tab next to console tab
Below Network tab you will find Online dropdown.
Click on the arrow beside the online dropdown, you will find multiple options click on the one which says Slowest This will reduce the speed of your website loading and gain you more time to find the xpath.
or
You can also customize the throttle by clicking on add option and providing Download, Upload and Latency. or you can directly choose Offline option once your loading icon is enabled.
Attached screenshot for your reference.
Hope this helps.
You can try something like below using web driver wait, not sure which programing language you are using butyou refer same concept with other languages too:
wait = WebDriverWait(driver, 10)
wait.until(EC.element_to_be_clickable((By.XPATH, "//span[contains(text(),'your text1')]")))
Note : please add below imports to your solution
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait

Selenium WebDriver Explicit Wait intermittently not working

Good day everyone,
I need your help in this method. I have a web page that will have a loading screen UI when the page loads, and I'm waiting for it to finish before clicking a button.
Here is my code:
#Step("Go to Audit Inquiry Screen")
public void launchAuditInquiry(){
WebDriver webDriver = Driver.webDriver;
WebDriverWait wait = new WebDriverWait(webDriver, 10);
wait.until(ExpectedConditions.invisibilityOfElementLocated(By.className("loading-container")));
WebElement auditInquiryBtn = webDriver.findElement(By.linkText("Audit Inquiry"));
auditInquiryBtn.click();
}
My issue is sometimes, this code works fine. It will wait for the loading ui div to be invisible before clicking the button. But sometimes it will produce this error:
Error Message: org.openqa.selenium.WebDriverException: unknown error: Element <a class="module-item" href="/audit/inquiry">...</a> is not clickable at point (822, 436). Other element would receive the click: <div class="loading-container" style="display: flex; opacity: 0.899842;">...</div>
I tried adding another explicit wait before clicking the button to be sure, like this:
wait.until(ExpectedConditions.invisibilityOfElementLocated(By.className("loading-container")));
WebElement auditInquiryBtn = webDriver.findElement(By.linkText("Audit Inquiry"));
wait.until(ExpectedConditions.elementToBeClickable(By.linkText("Audit Inquiry")));
auditInquiryBtn.click();
But it will sometime produce the same error above, and sometimes it will work fine.
I'm just confused on how to remediate the issue.
Thank you guys for the comments, especially this: Selenium Web Driver & Java. Element is not clickable at point (36, 72). Other element would receive the click
It was helpful, but some items there, I have already tried, but did not work as well. The part that I did check was one item there and also a comment here also which is to force a click:
new Actions(driver).moveToElement(auditInquiryBtn).click().perform();
But I'm having second thoughts on this because, a scenario may happen that when the loading container div is still overlaying the page, then I forced clicked the submit button, it will also produce another loading container div, and I'm not sure what will happen if there are two loading container div present.
Now, my solution on this is to adjust the sleep timer of the wait function:
WebDriverWait wait = new WebDriverWait(webDriver, 10, 2500L);
It now works because it gives the loader div time to generate before the first check of wait. 500 ms was a bit fast for the loader to render. I'm still testing this but if it didn't work, I might do the solution above.
Thanks again.
First thing to try is remove the invisibilityOfElementLocated wait and just use elementToBeClickable. I've never really trusted what Selenium considered "visible" and "invisible".
I've had issues in the past where the element to click on was completely off screen, so Selenium automatically scrolled until it was considered in the viewport. But because of a floating footer, it didn't scroll enough and was still behind the footer so could not be clicked on. It was still considered "visible" because it was in the viewport.
But, if you're sure, you can try forcing a click at a coordinate instead of an element.
new Actions(driver).moveToElement(auditInquiryBtn).click().perform();

How many times submit button would get clicked with impicit wait of 30 seconds

I'm having a situation and don't have the answer , I have a login page where i am trying to click on Submit button but somehow when it clicks on submit button it doesnt navigate to homepage.
So my question is considering i have a implicit wait of 30 seconds how many times it would click the submit button?Will it keep on clicking until 30 sec and then throw an exception ?
The Implicit Wait would not click the element multiple times - in other words, it is not applied to the actions, it works for the "find" functionality only:
An implicit wait is to tell WebDriver to poll the DOM for a certain amount of time when trying to find an element or elements if they are not immediately available.
What you are probably looking for is the Explicit Wait - for instance, waiting for a button to become clickable. Example in Python:
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
driver = webdriver.Firefox()
driver.get("http://somedomain/url_that_delays_loading")
wait = WebDriverWait(driver, 10)
button = wait.until(
EC.element_to_be_clickable((By.ID, "myDynamicElement"))
)
button.click()
The implicit wait functionality is different from what you are expecting. It only checks for the element at regular intervals of time, this is called polling. If the element is found on the first time itself, then it will stop polling automatically. This means that it checks for the element until it is found with a time span of what you have given, in this case it is 30 second, through polling.
If you want to hit the element multiple times you can use an explicit wait like fluent wait.
If you want to wait for navigating to home page after clicking on submit, then use web driver wait, and your code will run smoothly.
WebDriverWait wait = new WebDriverWait(big,120);
wait.until(ExpectedConditions.elementToBeClickable(By.xpath("your xpath here"));