I have a method that clicks on a button, however, when it is run, selenium returns the outcome as clicked successfully, when, in reality, the button is not actually clicked. If I run the test several times, occasionally, it'll be clicked as expected. I have my test framework set as an implicit wait for about 15 seconds, I have set an explicit wait for this element, and still see the same issue. When I do <element>.isDisplayed(), the element is always found. I placed the .click in a while loop to click it a few times which works most of the time, however, still sometimes the test fails. Is it possible to have an if statement to check if an element is actually displayed before clicking the button?
I've tried:
if(!element.isDisplayed){
element.click
}
Here is the button I am having issues with:
<button class="notkoButton listNew">
<div class="l6e iconAdd">New List</div>
</button>
Here is my method:
public marketing_lists_page navigateToNewListPage() throws Throwable {
try {
int x = 0;
while(x < 5) {
newListBtn.click();
x++;
}
//newListPageHeader.isDisplayed();
} catch (NoSuchElementException e){
logs.errorDetails("Could not navigate to New List Page");
Assert.fail();
}
return this;
}
Seems like the element is not enabled or not clickable initially. And to answer your question, yes there is an explicit wait you can use and wait for the element to be clickable:
WebDriverWait wait = new WebDriverWait(driver, timeOut);
wait.until(ExpectedConditions.elementToBeClickable(locator));
Try this, Click using javascript and feel free to change the locate for the element according to your convenience:-
WebElement element= driver.findElement(By.xpath("YOUR XPATH"));
JavascriptExecutor executor = (JavascriptExecutor) driver;
executor.executeScript("arguments[0].click();", element);
Hope it will help you :)
Try scrolling to the element before clicking on it. This mostly happens when you test on chrome. You can use JavaScriptExecutor to scroll.
Something like this:
JavascriptExecutor jse = (JavascriptExecutor)driver;
jse.executeScript("window.scrollTo(0," + element.getLocation().Y + ")");
You say you have tried an explicit wait, but it sounds like what you are asking for can be best accomplished by a fluentWait (which is type of explicit wait):
public WebElement fluentWait(final By locator) {
Wait<WebDriver> wait = new FluentWait<WebDriver>(driver)
.withTimeout(30, TimeUnit.SECONDS)
.pollingEvery(5, TimeUnit.SECONDS)
.ignoring(NoSuchElementException.class);
WebElement foo = wait.until(new Function<WebDriver, WebElement>() {
public WebElement apply(WebDriver driver) {
return driver.findElement(locator);
}
});
return foo; };;
Here the WebElement would be the button you are trying to click. The cool thing about FluentWait is that the element itself is returned if it is found. From the documentation:
An implementation of the Wait interface that may have its timeout and polling interval configured on the fly. Each FluentWait instance defines the maximum amount of time to wait for a condition, as well as the frequency with which to check the condition. Furthermore, the user may configure the wait to ignore specific types of exceptions whilst waiting, such as NoSuchElementExceptions when searching for an element on the page.
To use it simply do:
WebElement newListBtn = fluentWait(By.id("button"));
Also try:
Driver.SwitchTo().DefaultContent();
before clicking just in case it is a frame issue.
Selenium suffers from lack of GUI "dynamism".
By that i advice you to send a refresh to the page after your click.
Tell me what's up.
I was facing the exact same issue but only after I updated my selenium libraries from 2.45 to 2.48.2. "Click" method call never fails which mean the element is always found by the driver, what I think it fails to do is clicking the right spot may be. My test would run fine on a higher res screen and would sometimes pass (but mostly fail due to click issues) on a lower res screen. I tried many things but in the end what worked for me was ZOOM.
Before running the test I call the following method and the "click" method works as expected on that low res screen now.
public void zoomOut () {
WebElement html = driver.findElement(By.tagName("html"));
html.sendKeys(Keys.chord(Keys.CONTROL, Keys.SUBTRACT));
}
I had what looked like a similar problem on the surface of it while using the JavaScript WebDriver - the click() promise resolved successfully, and yet nothing happened.
In my case, it turned out to be related to an invalid image src attribute on the page (unrelated to the button I was clicking). For whatever reason, fixing the image link solved the problem!
I know the OP was using Java rather than JS, but my own searches brought me here, so others using JavaScript will likely come the same way.
I've noticed clicks being inconsistent with Selenium as well, this seems to be a known issue to a certain extent:
https://github.com/SeleniumHQ/selenium/issues/4075
In my case there is practically no way for the element to not be ready. I had a wait, but more importantly my test case was filling in a very large form, the button that was to be clicked to initiate a drop-down is very simple and I can see it being loaded close to half a minute before my test interacts with it, yet every so often it would still fail. To the point where I wrote a silly while loop to click every 100 millisecond until the expected dropdown showed up.
This is all guessing but from personal observance and some comments from others in that thread - such as one user mentioning they notice more issues like this when running parallel tests, seem to indicate it is possible for what seems to be a missed event, and perhaps this is due to the lag introduced from it's architecture. Specifically I'm comparing this to how Cypress works with native commands given to the browser directly without the intermediary server.
Related
Clicking an element always ended up failure. Just found the reason is that the element is not ready to click because it comes with some shaking animation even if Explicit wait method ExpectedConditions.elementToBeClickable(ele) is implemented.
In debugging mode, I can click. Of course. But in run mode, no difference.
ElementClickInterceptedException This is the exception.
Any idea to tell that animation finished and actually ready to be clicked?
My advice is to "hard-click" on the element via JavaScript:
WebElement element = driver.findElement(By.id("Element's ID Goes Here"));
JavascriptExecutor executor = (JavascriptExecutor)driver;
executor.executeScript("arguments[0].click();", element);
Tell me if this helped you or not.
If Tal Angel's answer doesn't work for you, try using the Actions class to move to the element's position and force a click event.
Actions actions = new Actions(driver);
actions.moveToElement(ele).click().build().perform();
You will need to import org.openqa.selenium.interactions.Actions; to do this.
Runnable example here
Yesterday I ask question how to deal with: "Element is not clickable at point - other element would receive the click" exception in Selenium WebDriver.
I receive several answers with this solution:
WebElement element = wait.until(ExpectedConditions.elementToBeClickable(By.id(...));
Yes, it has sense but in practice it doesn't work.
Below is piece of my code:
JavascriptExecutor js = (JavascriptExecutor) driver;
js.executeScript("arguments[0].scrollIntoView();", categoryItem);
Thread.sleep(1000);
new WebDriverWait(driver, 10).until(ExpectedConditions.elementToBeClickable(categoryItem));
categoryItem.click();
List<WebElement> selects = driver.findElements(By.tagName("select"));
Select ticketsSelect = new Select(selects.get(3));
ticketsSelect.selectByValue("2");
By addToBasket = By.xpath("//div[contains(text(),'Add to Basket')]");
Thread.sleep(1000);
new WebDriverWait(driver, 10).until(ExpectedConditions.elementToBeClickable(addToBasket));
driver.findElement(addToBasket).click();
I had to put 1 second sleep before each wait until element to be clickable because without this it still throw exception that other element would receive the click.
My question is why WebDriver clicks this element if element is not clickable ?
ElementToBeClickable – An expectation for checking an element is visible and enabled such that you can click it.
But it seems that it doesn't imply that this element is not "hidden" under some other element, even if it's a transparent part of another tag. In my experience, this exception is mostly occur when you are trying to interact with a page, which currently loads, and you have typical loading div overlapping the whole page with loading icon, or in other cases when you have an open modal, which also often cover page with overlays transparent overlay, to prevent user from interacting with a page.
In this answer you can see that you basically have two options:
You can send a click event via JavaScript call. It will always work, but it's not something you want to do. If you want to test your page, you should always trigger real click events.
Wait. There is not much you can do. Something you just need to wait till your page fully loads. In a way maybe this will show you the slow parts of your application, which you can improve in a future
I need to wait for a page 'popup overlay' to load before scrolling to the relevant web element.
The following code below is successful when locating and scrolling to a web element but i want to avoid Thread.sleep.
public void scrollToElementByLocator(WebElement element) throws InterruptedException {
Thread.sleep(4000);
((JavascriptExecutor) driver).executeScript("arguments[0].scrollIntoView();", element);
((JavascriptExecutor) driver).executeScript("window.scrollBy(0, -400)");
3. Can anyone advice on another method to wait for a page to load and then scroll to the intended webelement without using thread.sleep?
Many thanks for your help
These are a pain. Ideally you would have access to the devs and they could tell you what elements appear/disappear that you can wait for. In this case, I'm assuming you don't have access to them.
What I try to do is trigger the action, quickly right-click and choose Inspect element, and see what elements are popping up. If you are lucky, the dialog, etc. stays up and it's easy to find. In cases like this, they happen so briefly that it makes it really hard. What I did was to do the actions above to the point where I was triggering it on/off and watching the DOM for elements to appear/disappear. I finally got in the right place and found this using screencap and OCR
<div class="modal in" id="loading-modal" data-backdrop data-keyboard="false" tabindex="-1" role= "dialog" aria-hidden="true" style="z-index: 1100; top: 475px; display: block; padding-right: 17px;" modal-dialog">
<div> id="loading-page-backdrop" class="in"></div>
There are a couple of DIVs there, one of them is very likely the element you are looking for and both have IDs so they should be easy to get ahold of and wait for them to be invisible.
// wait for modal to disappear
new WebDriverWait(driver, 10).until(ExpectedConditions.invisibilityOfElementLocated(By.id("loading-modal")));
// do stuff
Even if these aren't the elements you are looking for, you should be able to use this technique to find the ones you want.
BTW, I write automation in Java and I've never needed to scroll the window... it just does it for me. Have you tried the scenario without the scroll code?
A solution i use for waiting on page load is waiting for the page title to match what i expect. For example:
public Boolean waitForPageIsLoaded(String title) {
return new WebDriverWait(driver, 10).until(ExpectedConditions.titleIs(title));
}
Of course if you know what WebElement you are waiting for there are plenty of ExpectedConditions you can take advantage of eg, visibilityOf()
To verify the page is loaded completely, loop through the below statement until it returns the value "complete"
(String) ((JavascriptExecutor) driver).executeScript("return document.readyState");
For more details refer here
There's a menu item that I want to click.
However just before this click, in my test flow I have a modal open, which prevents clicking on the menu item. Also, when closed, the modal will fade instead of disappearing instantly.
What I do is close the menu item and then place a wait for the menu item to be clickable, before performing the click:
WebDriverWait wait = new WebDriverWait(getDriver(), time);
wait.withMessage(message);
try {
wait.until(ExpectedConditions.elementToBeClickable(locator));
} catch (Exception e) {
Logging.logException(e);
}
clickOn(locator);
However this does not work, as I'm running each time into the following exception:
org.openqa.selenium.WebDriverException: unknown error: Element is not clickable at point (158, 565). Other element would receive the click: <div class="globalpopup with-data slideout">...</div>
I also have Selenium set-up to take a screenshot each time an exception occurs and in the screenshot I can clearly see that the modal is in the process of fading out.
So the close button for it has been clicked, but at this point I'm thinking the wait should come into effect and pause execution until the modal fully disappears and the menu item can be clicked. Which does not happen.
Now I usually fix this by adding a bit of sleep time, as it's quite predictable how long it takes the modal to fade out. However I'd really like to figure out a more elegant solution, which can apply in all situations.
My understanding is that elementToBeClickable does not account for when the element is covered by another element, which I find quite silly. Is there a way to simulate such a wait (notCoveredByOtherElement), as it's exactly what I'd need?
P.S. I'm using Selenium 2.53. Have not tried v3 yet, although I'd happily make the effort to start switching to it if someone can confirm that this case is handled properly in this new version.
I also faced this issue number of time and tried some solution which always worked for me.
1-Updated chrome driver to latest one 2.23
2-Get the coordinate then click on the link or button
3-Try to click using Y coordinates
// Find an element
WebElement elementToClick = driver.findElement(By.xpath("Your xpath"));
// Scroll the browser to the element's Y position
((JavascriptExecutor)driver).executeScript("window.scrollTo(0,"+elementToClick.getLocation().y+")");
// Click the element
elementToClick.click();
// Find an element
WebElement elementToClick = driver.findElement(By.xpath("Your xpath"));
// Scroll the browser to the element's Y position
((JavascriptExecutor)driver).executeScript("window.scrollTo(0,"+elementToClick.getLocation().y+")");
// Click the element
elementToClick.click();
I have documented all in below link kindly check
Solutions for Element is not clickable in Selenium
I want to be able to click a logout button twice very rapidly like a user would?
WebElement logout = driver.findElement(By.id("dijit_form_Button_0_label"));{
if(logout.isDisplayed()){
logout.click();
I want to be able to click on the logout button twice at less than a second like a user would? Is this possible in selenium webdriver?
EDIT:
Make sure the dom is loaded
Like atri said, you could use the double click function according to This thread.
WebElement logout = driver.findElement(By.id("dijit_form_Button_0_label"));{
if(logout.isDisplayed()){
logout.doubleClick();
if you don't want to use the doubleClick function, I would recommend the ExplicitWait from Selemium
Selenium: Implicit and explicit Wait
If you want to do this manually, could add a delay between your click using javascript Thread and selenium wait.
Based on This thread
WebElement logout = driver.findElement(By.id("dijit_form_Button_0_label"));{
if(logout.isDisplayed()){
logout.click();
Thread.sleep(100);
logout.click();
}
Better way is to use ExplicitWaits which you means you will wait
exactly as long as some action happens or some element gets rendered
on the page.
- petr-mensik
An explicit waits is code you define to wait for a certain condition
to occur before proceeding further in the code. The worst case of this
is Thread.sleep(), which sets the condition to an exact time period to
wait. - Selenium