38

I have a problem with my tests in Selenium WebDriver. The Click event not always works when a program tries to click on button. In one test everything is ok, in others it is not.

Every test starts from one page. First the user has to choose an option from a select component and after that the user clicks on a button.

I want to know why one time everything is ok, and when I run tests a second time it is not?

Here is the source code of finding and clicking the button:

public void clickContinueBtn() {    
    webElement = driver.findElement(By.xpath("//div[@class='btn magenta_s']/a/span"));
    webElement.click(); 
}
Jeroen
  • 60,696
  • 40
  • 206
  • 339
user1494328
  • 681
  • 3
  • 14
  • 20
  • related post - http://stackoverflow.com/questions/43011751/how-do-find-out-why-an-element-is-disabled-briefly – MasterJoe Mar 25 '17 at 02:26

10 Answers10

29

I ran into a similar issue. The click method worked on other pages, then didn't work at all on a particular page.

A race condition caused the issue:

  1. HTML content is rendered with the button disabled.
  2. The selenium web driver script was executed before the javascript onload event was triggered (Or finished executing). So the button.click would occur on a disabled element. And nothing would happen.
  3. Then the javascript onload event would trigger (or finish executing) and the javascript would enable the button.
  4. I looked at the page and couldn't figure out why my code wasn't working because the button appeared to be enabled upon inspection, and if I manually clicked the button, it worked.

Once I figured out that it was a timing issue, I found the solution here: How can I get Selenium Web Driver to wait for an element to be accessible, not just present?

To paraphrase the solution in Ruby:

//This will not return the button until it is enabled.
button = driver.find_element(:xpath,  "//button[@id='myButtonId' and not(@disabled)]")
button.click
Community
  • 1
  • 1
Walker D
  • 429
  • 4
  • 7
  • 1
    This really helped me, the script worked perfect in other browsers but not in Safari 6 and Android Browsers, they wasn't fast enough. Thanks for sharing this answer! :) – Jonatan Lundqvist Medén May 14 '16 at 07:45
  • How do I switch do iframe and wait for onload="javascript:pageload(); functionalPageLoad();" to reload the page in Ruby? I find myself opening the iframe inside a page, I have access to it, then the page reloads, and I cannot access the frame anymore. I have read many answers regarding wait, sleep, time, switch to frame then to parent, however I cannot reach my goal. – Amanda Cavallaro Oct 06 '16 at 13:10
  • How do you find out that your element is disabled if stays disabled only for a few milliseconds ? In my case the click works 1-2 seconds after the first attempt by selenium. – MasterJoe Mar 30 '17 at 23:11
  • 1
    @testerjoe2 - http://stackoverflow.com/questions/6727370/using-chrome-javascript-debugger-how-to-break-on-page-loading-events Use a breakpoint on the element or the javascript that alters the state of the element to set it to "enabled". Use that to verify that the element loads as disabled. – Walker D Apr 03 '17 at 02:57
  • @AmandaC.Cavallaro I apologize for the extreme delay and poor answer. This might help. http://stackoverflow.com/questions/9942928/how-to-handle-iframe-in-webdriver – Walker D Apr 03 '17 at 03:00
25

You can also try using the Javascript based alternative method for clicking. The code for this can be as follows:

WebElement element = driver.findElement(By.id("something"));
JavascriptExecutor executor = (JavascriptExecutor)driver;
executor.executeScript("arguments[0].click();", element);
Arek
  • 1,941
  • 4
  • 22
  • 27
  • 1
    It don't work. When one option of select component is choosed browser window is closing. – user1494328 Aug 28 '12 at 13:42
  • Worked for me after trying almost every other option, Thanks! – B.W. Nov 02 '20 at 15:29
  • Not a good advice. Javascript click is performed directly via DOM and does **not** resemble what a human would do in a browser. Unless your customers open the browser's developer tools console and call `click` using Javascript, instead of clicking with the mouse. Javascript click defeats the purpose of end-to-end UI tests, which is reproduce human interaction with automation. – C2H5OH Nov 16 '22 at 16:39
5

Many times it happens because of Browser compatibility (Mostly on firefox). So try to use "WebElement.sendKeys(Keys.ENTER);" code instead of "webElement.click(); "

3

Have you made sure, there is no timing issue? Make a break point before finding the element and look if your code runs fine. If there is a timing issue, use a an explicit Wait before clicking your button. Note also, that the button should be clickable (element must be visible AND enabled) before actually clicking it.

a solution with explicit wait could look like this:

By by = By.xpath("//div[@class='btn magenta_s']/a/span");
WebDriverWait w = new WebDriverWait(driver, timeout);
WebElement element = w.waitUntil(ExpectedConditions.elementToBeClickable(by);
element.click();
loother
  • 199
  • 1
  • 8
  • Seems the w.waitUntil has been replaced with w.until, i.e. WebElement element = wait.until(ExpectedConditions.elementToBeClickable(selector)); – theINtoy Dec 04 '18 at 12:16
3

Try Out below code sometimes you have deliberately move your focus towards your elements

WebElement element = driver.findElement("yourElement");
        Actions builder = new Actions(driver);
        builder.moveToElement(element).click(element);
        builder.perform();
Jitesh Lakhwani
  • 305
  • 1
  • 2
  • 8
2

I experienced a similar problem a couple of days ago and I found the solution in my particular case. ===Using Selenium Webdriver, I wanted to click to the link of "First Link" and that would load content on the page.

Below a portion of code with structure alike my case:

<li class="first-link">
    <a class="common-style" href="javascript:;" style="padding-left: 15px; padding-right: 15px;">First Link</a>
</li>

===The result is that the Webelement is supposed to be found and clicked but switching to the UI, nothing happened, no error was thrown either (element not found, element not ready for click, element disabled, etc).

After trying a couple of different ways to find the link through (xpath and css, didnt try by id because in my case there is no unique id), I was able to access and click the element with Selenium webdriver by css with the following value: li.first-link a. However, when I tried to access by xpath with the following value, this was 'found' in Firefox but click didnt work: .//li[a/text()='First Link'].

The problem was a slight xpath syntax issue, that firebug from Firefox didnt report at all, in fact it found the link.

I changed the braces order like this: .//li/a[text()='First Link'] Now it works as expected, First Link is found and clicked and the javascript code that loads the page is fired.

My findings are: * It is not a timing issue, so this does not happen because you try to click an element that is not ready. Otherwise we had solved this with an explicit Selenium wait...

  • The problem is not that element is found and the javascript is not fired. You can try to execute directly javascript code and fire manually the events and see this does not work.
  • This issue happens on Firefox 22,probably works for older versions from this browser. I cant provide information if this works on IE or Chrome. The issue itself is that even that there is a syntax conflict on xpath firefox does not throw an exception, that makes you think there is nothing wrong with your code, but there is.
  • This is an unexpected unhandled behavior for Firefox. I have found a bug reported for this: http://code.google.com/p/selenium/issues/detail?id=4757

SOLUTION SUGGESTED: verify your html structure, your xpath, try to find issues in the syntax, find different ways to access to the element.

Tom
  • 1,387
  • 3
  • 19
  • 30
Romita Dinda
  • 81
  • 1
  • 4
0

Looking at your xpath you have not identified the button, instead you are pointing to the span tag inside which button is present. Selenium clicks on span instead of the button. That is why click() is not working. Please use an Id or name if available or change the xpath to include the button tag as well. If you can post the html it will be easy to create the xpath. click() has been working perfectly for me and I have been using this method for over an year in a project and every time it works fine...

Vinay
  • 648
  • 4
  • 12
0

you can try with JavaScriptExecutor or Action class.

//JSExecutor
WebElement element = driver.findElement(By.xpath("xpathofyourelement"));
JavascriptExecutor jsExecutor = (JavascriptExecutor)driver;
jsExecutor.executeScript("arguments[0].scrollIntoView();", element);
jsExecutor.executeScript("arguments[0].click();", element);

//Action Class
WebElement element = driver.findElement(By.xpath("xpathofyourelement"));
Actions builder = new Actions(driver);
builder.moveToElement(element).click(element);
builder.perform();

Cheers..!!

0

When you are facing with javascript and you have to scroll down then this might help:

// Try to use JavascriptExecutor to bring the element within Viewport (for scrolling)
WebElement myelement = driver.findElement(By.xpath(xpathSelect));
JavascriptExecutor jse2 = (JavascriptExecutor) driver;
jse2.executeScript("arguments[0].scrollIntoView()", myelement);
WebElement showMore = driver.findElement(By.xpath(xpathSelect));
showMore.click();

good luck!

Gerrit-Jan
  • 59
  • 1
  • 9
  • Thanks for providing this code. Out of interest, why have you performed findElement after the scroll again? – Dave Jan 04 '23 at 22:38
  • because this findelement is needed to check if the element after the scrolling is found, you need to find something after you scrolled right? – Gerrit-Jan Jan 15 '23 at 10:18
-2

One possible reason for this could be click() method is not able to dispatch click event on every element.

Hence, you could explicitly fire click event on the element you are trying to click.

Vaman Kulkarni
  • 3,411
  • 2
  • 21
  • 22