Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Selenium Click functionality does not work consistently #4075

Closed
vinaybond opened this issue May 25, 2017 · 50 comments
Closed

Selenium Click functionality does not work consistently #4075

vinaybond opened this issue May 25, 2017 · 50 comments

Comments

@vinaybond
Copy link

vinaybond commented May 25, 2017

Meta -

OS:
Windows/Linux (Cent OS & Ubuntu)
Selenium Version:
Any WebDriver version
Browser:
Chrome/Firefox and IE (Any version)

Expected Behavior -

Click operation should always work when no exception is thrown

Actual Behavior -

Click action works something and sometime it does not. It shows the element is actually being clicked, as for link and buttons we can see dotted border around the object. However the action on that click is not triggered. I tried .Click() / Actions Class/ Click using JS/ Press Enter button on element but none is working all the time.

Steps to reproduce -

I wish I could have provided the steps but this is happening on multiple webpages on click action. Many people around world is facing this issue. Save can be checked on stackoverflow or other forums. Element is present on the page and page is completely loaded when I took screenshot. I have seen this issue with Java and Python web drivers.

Suggestions & Observations -

I think selenium is sending the click but browser (IE/FF/chrome) are not ready to process it. May be its binding to JS is not done or something like that. If that is the case then is there a way selenium can find if the browsers are ready to perform click. I guess selenium already check for DOM status. Please see if anything else which can solve the problem

@AutomatedTester
Copy link
Member

This is a case of waiting for the relevant cues to know when to carry on. We have the WebDriver Wait classes that simplify this for you.

@vinaybond
Copy link
Author

vinaybond commented May 29, 2017

Waits are already present. Wait passes and click does not work randomly with no exception. Page is not changing during this process. If this was the case if Wait class then I'd have got some exception. In this case I am not getting any exception. I request to reopen the bug. I have seen many people across the world are facing this issue are left with no solution.

@AutomatedTester
Copy link
Member

We will gladly reopen this when you have a test case that shows this issue consistently. Unfortunately until then there is nothing that we can do.

Events not added to a DOM element by the time you click wouldnt throw an error, especially since the web is asynchronous, and the test would try carry on but then not hit the relevant issue.

@vinaybond
Copy link
Author

vinaybond commented May 30, 2017

Hi @AutomatedTester
I totally understand the situation you must be facing here. This is one of those scenarios where issue is not reproducible every time making it hard for both of us to move ahead. In such case if someone can help me with where and what to look for, I can gather data as much a possible. I want to understand how and what to look for.
I also want to share my observations. Here is an image which has a link "Assign checklist" which takes user to some page. Which works most of the time but sometime. When it does not work it does not have throw any error (coz it has done it job by clicking on it). We can see in the screenshot that, link turns blue when user clicks on it. So click has happened but it did not work. I am clueless why it did not work. was browser not ready to process the request or is it something else? I tried using multiple waits (present/visible/clickable etc) .

image

@luke-hill
Copy link
Contributor

It is a known issue that IE clicks can sometimes be flaky. Here is ruby code (You'll need to adapt, that possible could help)

wait_for do
  element.click
  has_next_page?
end

This will then re-click everytime the next page isn't open, until it is. Not brilliant code, but it gets the job done.

As for FF / Chrome, you're on your own there

@vinaybond
Copy link
Author

Thanks for the suggestion @luke-hill . That was just one of the case. Sometime user moves to different page after click on some element sometime user will remain on same page. Beside, I have some validation added after many click which fails when click does not work. This failure is not due to application error but click did not work so next page did not load. This is kind of false failure.

@0019
Copy link

0019 commented Jun 12, 2017

Exactly the same situation here. I'm running a Firefox on windows 10. It sometimes work and sometimes doesn't, which is driving me crazy.

@0019
Copy link

0019 commented Jun 12, 2017

A workaround: Thread.sleep() for some time before the click, and even before starting to look for the element. This is for the situation where you want to click on something right after refreshing/redirecting the page. Looks like the click might be thrown away, if you try to click while the page is still loading. In my case, it needs to sleep for 6000 ms. Not a good solution, but can get things moving, hope it helps.

@vinaybond
Copy link
Author

@0019 , putting hard coded sleep is not a good solution. I tried 3 seconds of sleep and it did not solve the problem. However, it reduced failures a bit. But, if the DOM status is "completed", then why do we even need hard coded sleep? Is something browser does after DOM is ready? i.e. binding events with Objects? If yes, can we know the status of such thing is completed or not?

@0019
Copy link

0019 commented Jun 14, 2017

@vinaybond , I've upgraded my method to abandon the sleeping. I'm now using the driver as JavascriptExecutor to execute js command to click it. It works fine for me. To make it 100% hit, you may need to use ExpectedConditions to wait for the element to be visible first.

@vinaybond
Copy link
Author

Hi @0019,
I tried that as well, but, with that issue of "click not working" increased. I already have checks of element present and visible before I use click using JS.

Here is how I am using JS to click on element. It is written in python:

    def myclick(self, locator):
        element = self._element_find(locator, True, True)
        return self._current_browser().execute_script("arguments[0].click();", element)

I also tried adding hard coded sleep of 2s before clicking. Any suggestion is welcome.

@dtronche
Copy link

I had a problem similar to vinaybond one and I realise that the reason for the click operation not working was that the element was not completely visible in the windows.
I understand this behaviour can be logical but I suggest an exception should be raised for such case. This would have saved me a lot of time to help me understand what was wrong

@vinaybond
Copy link
Author

vinaybond commented Aug 31, 2017

Here is the workaround:
Say I want to click on Link1 and after doing that it will take me to the page which has Button1 on it. Here is the psudo code:

MyClick(Link1, nextloc=Button1, nextAction=Present){
	driver.click    Link1
	if (nextloc is present)
	timeout=1 (seconds)
	while(timeout<30){
		try{  
		      if (nextAction=='present')
			  driver.wait for element present(Button1,  2second)   //if it will fail, it will throw exception
			  break       //exit loop if next element found
		} catch{
		   timeout = timeout+2
		   driver.click    Link1   //Click Again
		}
	}
}


myClick     link1    nextloc=button1

In above example, my action is "element present" (Button1). It can be sometime else. In that case, you have to write a different login.

This has worked well for me

@Edzarius
Copy link

In Chrome I changed from a zoom of 90% to 100% and that solved the problem.

@mamohanc
Copy link

@Edzarius you gotta be kidding me!.
The solution was working normally, and i messed with zoom (zooming out). And suddenly everything stopped behaving abnormally.

BTW, how did you find the issue that zoom is the problem. Why is it so.
In my code I am using only classnames, not anything remotely related to X,Y Coordinates

@lmtierney
Copy link
Member

@mamohanc this is a long standing issue with chromedriver https://bugs.chromium.org/p/chromedriver/issues/detail?id=628

@Vijayasok89
Copy link

facing similar issue . Tests fails intermittently due to this. Logs show click operation is passed but button is not clicked, I even tried wait and EC.element_to_be_clickable before performing click , still am facing this inconsistent failure for button click. can someone please share some workaround for this ?

@ViharJam
Copy link

Hi one work around which can be done in this is every time when you want to click any element.
1.Use wait for checking element presence.
2.Before clicking first get page Source and once you get the page source you just search for the element you want to click.
3. Give the check if the element is present in the DOM once you find then click the element .
hope this might help to solve the problem.

@sheejan
Copy link

sheejan commented Feb 14, 2018

Hi ,
I am also faced the same issue, I used try and catch like Vinaybond . Please see the code.
In the application the second item get available only when user click the first item successfully.

int timeout=0;
while(timeout<30)
{

try

{
driver.findElement(By.xpath("Xpath of second item")).click();
timeout=30;

}catch(Exception e){

	driver.findElement(By.xpath("Xpath of first item")).click();
	
	 timeout=timeout+2;
}
}

@ViharJam
Copy link

Ideally writing any logic inside a catch block is not recommended . You should use finally block to get your work done.

@sheilatapia
Copy link

@abutremutante have you found a solution? having the same problem :(

@sheejan
Copy link

sheejan commented Apr 25, 2018

This will solve the problem.

int timeout=0;
while(timeout<30)
{

try

{
driver.findElement(By.xpath("Xpath of second item")).click();
timeout=30;

}catch(Exception e){

driver.findElement(By.xpath("Xpath of first item")).click();

 timeout=timeout+2;

}
}

@indsoftselenium
Copy link

indsoftselenium commented May 10, 2018

Good day,

I have encountered the same issue while automating some tests for documents downloading
with Selenium 3.5.3 and Chrome 65.
I have noticed that WebElement click() method randomly terminate without exception but no click is performed (so my files are never downloaded...)
My solution was to implement a retry mechanism (loop until download is done or number of retries is reached)
Any help ?
May be sending alternate keys as Keys.ENTER or Keys.SPACE to the web element and the click will always perform correcty ?
Thanks

Note:

  1. The clicked element is a basic HTML anchor element with
    target="_blank" and href ="/Filed?Download?file=test.pdf"
    so no other Java script or jQuery actions are involved.
  2. The method use to click is:
    e.click();

@ViharJam
Copy link

ViharJam commented May 11, 2018 via email

@indsoftselenium
Copy link

indsoftselenium commented May 11, 2018

// 1 - the code (extract)
....
final String downloadedFileHRef = result_link.getAttribute("href");
FileDownloadUtility downloader = new FileDownloadUtility(result_link);
downloader.download();
.....

// 2 - the class FileDownloadUtility (extract with download method)
public class FileDownloadUtility extends Utilities {
final ReloadableHtmlElement link;

public FileDownloadUtility(ReloadableHtmlElement link) {
    super();
    this.link = link;
}

/**
 * download download a document
 * 
 * @throws Throwable
 */
public void download() throws Throwable {
    // clean
    clean();
    // click download link
    clickOnceAndWait(link);
    waitUntilDownloadIsComplete();
}

/**
 * wait until download complete
 * @throws Throwable
 */
void waitUntilDownloadIsComplete() throws Throwable {
    // wait result
    withWaitForPageLoad().untilWithUnhandledAlert(new ExpectedCondition<Boolean>() {
        public Boolean apply(WebDriver w) {
            try {
                return downloadedFile.exists();
            } catch (Throwable x) {
                return null;
            }
        }

        public String toString() {
            return "FileDownloadUtility.waitUntilDownloadIsComplete : wait presence of file: ("
                    + getDownloadedFileFullPath(downloadFileName) + ")";
        }
    });
    // finalize operation
    terminate();        
}

} /* FileDownloadUtility */

// 3 - extract ReloadableHtmlElement
public class ReloadableHtmlElement extends RemoteWebElement {
public WebElement element = null;
...
public WebElement getWebElement() throws Throwable {
reload();
return element;
}
...
} /* ReloadableHtmlElement */

// 4 - clickOnceAndWait
public void clickOnceAndWait(final ReloadableHtmlElement e) throws Throwable {
{
...
// getWebElement() return link internal WebElement
link.getWebElement().click();
logger.info("clicked on elenment:"+link.getWebElement().getText());
// no exception is thrown BUT THE CLICK IS NOT PERFORMED so the file is not downloaded
// the log indicate that the click was performed successfully
...
} /* clickOnceAndWait */

@indsoftselenium
Copy link

indsoftselenium commented May 11, 2018 via email

@henning-roos
Copy link

We had the same problem with click sometimes doing nothing.
In our case the button link was managed by javascript (not a normal button link) thus we got the same behavior as previously mentioned in this issue. So the real problem was that javascript wasn't ready. We used the following code to solve it:

public void waitForJQueryToLoad() {
    WebDriverWait webDriverWait = new WebDriverWait(driver, 30);
    webDriverWait.until((ExpectedCondition<Boolean>) wd ->
        ((JavascriptExecutor) wd).executeScript("return document.readyState").equals("complete"));

    webDriverWait.until((ExpectedCondition<Boolean>) wd ->
        ((JavascriptExecutor) wd).executeScript("return jQuery.active==0").equals(true));
}

@indsoftselenium
Copy link

why not 1) wait for ajax queries to complete and 2) wait for java script readyState

readyState should not be checked last ?

@aaravgotra
Copy link

def wait_until_page_load(self):
attempt_page_load=0
page_state = 'not complete'
while(page_state!='complete' and attempt_page_load<=20):
page_state = self.driver.execute_script(
'return document.readyState;'
)
time.sleep(1)
attempt_page_load=attempt_page_load+1

@musanas
Copy link

musanas commented Aug 27, 2018

Hi @vinaybond

Regarding the below workaround that you provided, I have couple of points to ask you

MyClick(Link1, nextloc=Button1, nextAction=Present){ driver.click Link1 if (nextloc is present) timeout=1 (seconds) while(timeout<30){ try{ if (nextAction=='present') driver.wait for element present(Button1, 2second) //if it will fail, it will throw exception break //exit loop if next element found } catch{ timeout = timeout+2 driver.click Link1 //Click Again } } }

  1. Is it some thing you add as part of your framework, and is it only the click method in framework?
    If yes, this would be unneccessarily increasing your overall execution time I guess , coz for every click, you are checking the next action/element etc is present/satisfied, which may not be required everywhere. Also some time you may not really have a next action/step in your application to satisy this.
    (If you use it only at places where you have expereinced this issue, and in lot other places in automation script if you do not have this , I guess the above inconvenience is not there)

Also if the first click is not working due to a real application issue say a bug in the app, wouldn't this be re-trying it multiple times and by chance if the re-attempt was successful, you would miss out on capturing that application bug ?

Thanks,

@vinaybond
Copy link
Author

Hi @musanas
What I put here is psudo code. next action and nextloc are needed in 5% case. I code in robotframework where nextloc and nextaction are kept optional. And yes, every time it checks if nextloc is given or null. If given, it performs wait, else it does not.
Also, if the first click does not work due to the issue, it won't work in next attempts, You can keep the interval between two clicks bit high so it won't keep clicking on the element frequently.
In case you have any better suggestion, please feel free to share.

@Susirya
Copy link

Susirya commented Sep 4, 2018

Hi All!
We also face this issue in our tests.
Just wanted to mention that I noticed that clicking starts to fail A LOT more frequent if i run tests in several Chrome instances on 1 machine in parallel. Running in 1 thread causes issues very rarely.
Maybe it will help to understand root cause.

@emanuelsantan4
Copy link

emanuelsantan4 commented Oct 25, 2018

Hi All,
I'm having the same issue. There are other points that I've noticed as well. When I debug the test, it pass through all with no errors, but if I run the scrip, then the click does not return anything (I've tried sending keys as well). I basically did all the suggested things in this post. I've tried different ways of waiting, I've tried to focus on the button before, assertion, none of that works.
One interesting thing that I've noticed is that when I set my breaking point for debugging in the test page, it pass through the test, but if I set the breaking point in the page object (just before the click) then it won't return the click, the same way as if I was running the script.
Through Selenium, I got directly in the page that the button was not working, and then I was trying to interact with it. When I changed to drive to the previews page and then clicking in a button there, to redirect me to the page that I wanted, then the whole workflow just worked.
I'm using C# and page objects.

@mspilsbury
Copy link

I am also seeing the same issue. Fresh chrome instances seem to be fine but when reusing the same instance the click action seems to be very hit and miss.

There are no errors and as far as selenium is aware it has performed the click but when you screenshot the result you can see nothing has happened (sometimes you see a highlight around the button or form element which suggests something has been attempted).

For now the best workaround I have found is using javascript to click the button instead. Replacing click() with: (python)

driver.execute_script("element = document.querySelector("SELECTOR"); element.click()");

As proven a lot more reliable and consistent in my cases.

@twalpole
Copy link
Contributor

twalpole commented Nov 7, 2018

@mspilsbury Of course the downside to that approach is that it basically makes your tests meaningless since you're now potentially clicking on elements a user never could.

@mspilsbury
Copy link

@mspilsbury Of course the downside to that approach is that it basically makes your tests meaningless since you're now potentially clicking on elements a user never could.

Sorry I didn't provide a full detail of the solution just an example.

The script call can still be used in conjunction with an element_to_be_clickable wait. This function still behaves correctly it is the actual click() function that does not seem to work all the time.

I understand its not 100% ideal but as a solution right now, using the wait and the forcing the click via javascript works every time for me.

@geopetoa
Copy link

geopetoa commented Nov 12, 2018

Super noob here.
just to give another data point, I also try to use button.click() but downloaded files are random.

Here is my code until thus far.

driver = webdriver.Chrome()
with open("welllist.csv", 'r') as file:
welllist = csv.reader(file)
next(welllist)
for line in welllist:
driver.get('https://secure.conservation.ca.gov/WellSearch/Details?api='+str(line[1]))
button = driver.find_element_by_id('ButtonExportProdToExcel')
button.click()
time.sleep(3)

line[1]:
08322171
08322851
08322850
08322849

@geopetoa
Copy link

OK, just found a solution from another resource. it clicks %100. (And also skips when the button is not active on the page)

here is the code:

    button = driver.find_element_by_id('ButtonExportProdToExcel')
    driver.execute_script("arguments[0].click();", button)

@vinaybond
Copy link
Author

hi @opheno ,
Whether you use click using JS or click using the native method. This problem will be there when there are multiple instances of browsers are running or your VM is too slow. The only solution I have seen working so far os checking nextcondition and re-click after few seconds say 20 seconds or so (but not so soon like 1-2 seconds). My best guess is when there is a resource crunch, the browser does not complete event binding with the object even when DOM status is completed.

@donggangcj
Copy link

Yea! The only solution is use time.sleep() currently!

@Souldat

This comment has been minimized.

@DanielFreemanTester
Copy link

DanielFreemanTester commented Jan 21, 2019

Thanks for everyone's comments on this - very helpful. I've found element.click() is unreliable when testing Chrome desktop browser running in mobile emulation mode. I've written a JS helper function to workaround this issue where I'm replacing each instance of
element.click()
with
clickElement(element)

This is only supposed to be a temporary solution (it seems to work reliably for the latest version of Protractor) - hopefully a Selenium fix will turn up at some point :)

Here's the function (hopefully others will find it useful)

this.clickElement = (el) => {
	const deferred = protractor.promise.defer();

	switch (global.deviceType) {
	  case commonConstants.ov3DeviceTypeEnum.desktop:
		el.click();
		break;
	  case commonConstants.ov3DeviceTypeEnum.mobile:
		if (!global.ov3TestIsRunUsingChromeMobileEmulation) {
		  el.click();
		} else {
		  /*
			This is required because there is a known issue with el.click() for Chrome mobile emulation
			https://github.com/SeleniumHQ/selenium/issues/4075
		   */
		  browser.wait(until.elementToBeClickable(el), commonConstants.shortBrowserWaitDelay)
			.then((elClickable) => {
			  if (elClickable) {
				// use direct JS command
				try {
				  browser.executeScript(
					'arguments[0].click();',
					el);
				} catch (exception) {
				  throw exception;
				}
			  } else {
				fail('Element cannot be clicked');
			  }
			});
		}

		break;
	  default:
		throw new Error(
		  `The deviceType '${global.deviceType}' is not supported.`
		  + ' Please ensure no tests are switched off using xdescribe.');
	}

	deferred.fulfill(true);
	return deferred.promise;
  };

@twalpole
Copy link
Contributor

@DanielFreemanTester No fix for that can come from Selenium - it's a bug in chromedriver/chrome - there have been a few reports of it to the chromedriver team and it has been open for quite a few months. It does not seem to be a priority to them. One example is - https://bugs.chromium.org/p/chromedriver/issues/detail?id=2452&q=emulation&sort=-id&colspec=ID%20Status%20Pri%20Owner%20Summary

@DanielFreemanTester
Copy link

@DanielFreemanTester No fix for that can come from Selenium - it's a bug in chromedriver/chrome - there have been a few reports of it to the chromedriver team and it has been open for quite a few months. It does not seem to be a priority to them. One example is - https://bugs.chromium.org/p/chromedriver/issues/detail?id=2452&q=emulation&sort=-id&colspec=ID%20Status%20Pri%20Owner%20Summary

Many thanks @twalpole , looks like the Chromium bug is receiving some attention as last updated just 4 days ago so hopefully this issue will get fixed soon :).

@dmitrygusev
Copy link

It's stupid, but I thought I'd share this maybe it helps somebody.

In my case it didn't work consistently because of an XPath element selector //*[contains(@class, 'js-modal-confirm')] randomly returning button "Cancel" (CSS class js-modal-confirm-cancel) instead of "OK" (CSS class js-modal-confirm).

We were migrating from Selenium RC where old selectors were using XPath. Everything returned back to normal after replacing them with proper CSS selectors.

@jinliangwii
Copy link

Hi All!
We also face this issue in our tests.
Just wanted to mention that I noticed that clicking starts to fail A LOT more frequent if i run tests in several Chrome instances on 1 machine in parallel. Running in 1 thread causes issues very rarely.
Maybe it will help to understand root cause.

Same issue, have you solved this problem right now?

@vinaybond
Copy link
Author

@jinliangwii , Yes this problem is solved with the solution mentioned by me.

@UlianaSaviak
Copy link

UlianaSaviak commented May 6, 2019

Hi
I'm facing same issue in Chrome Version 73.0
In Firefox everything works fine, looks like it's chromedriver bug, additional code writing is only temporary workaround, root cause should be fixed

@cgoldberg
Copy link
Contributor

root cause should be fixed

the issue has already been submitted to ChromeDriver. Please use the Chromium tracker for followup. There is nothing selenium developers can do to fix this.

@chavira
Copy link

chavira commented Jul 3, 2019

OMFG! I was having the same problem... until I read the comment from @Edzarius, I'm using Safari with maximize_window setting, and the click event was really inconsistent.

At the moment that I removed the maximize_window, all the clicks were working!!!

@lock lock bot locked and limited conversation to collaborators Aug 14, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests