5

I read somewhere in the docs that WebDriver API's are non blocking (except for a few like driver.get). So performing a WebElement click() or isDisplayed() should generally be asynchronous (assuming native events are enabled, of course).

I have a simple HTML page that performs a long operation (basically a long loop). While the JS executes, the browser is unresponsive which is expected. But I also noticed that WebDriver API's like click()/isDisplayed()/executeScript() block as long as the browser is busy executing the script.

Since WebDriver is issuing a native event for the click and not a synthesized JS event, I am puzzled why the API blocks. Although at present this behavior is not bothering me, I want to know if this blocking nature can be relied upon when running tests against unresponsive pages? I do use conditional waits in my tests, but would like to understand what happens under the hoods and if this is Browser/OS specific?

I am seeing this behavior in Selenium 2.20.0 with InternetExplorerDriver (IE9) and ChromeDriver (Chrome 19) on Windows 7.

Shama
  • 178
  • 2
  • 9

1 Answers1

6

Actually, the use of a blocking vs. non-blocking API is a point of contention for many users of the Selenium library. There are a lot of places where the library does a "best guess" attempt at blocking, even on element clicks, but it's not guaranteed. This tension between blocking and non-blocking has been discussed at length among the developer community and is reflected in one of the FAQs in the project wiki. In the case of IE, the driver does attempt to block on element clicks, and it's a race condition whether it succeeds in blocking or not. In the case of your specific page, the IE driver (and Chrome apparently) are "winning" that race, blocking until the operation is complete. However, the driver could just as easily lose that race in other cases, so it's best to use explicit waits for other page changes before proceeding to the next step in your code.

If it becomes a problem in the future, you might be able to mitigate this by setting a page load timeout to move on to the next statement earlier. One small challenge with this approach is that not all browsers may implement the timeout currently (IE does, I don't know about Chrome).

JimEvans
  • 27,201
  • 7
  • 83
  • 108
  • 1
    Selenium WebDriver blocks on synchronous code execution so you only need to worry about Asynchronous code. There is an article [here](https://spin.atomicobject.com/2015/05/12/testing-asynchronous-behavior-javascript-selenium/) that talks about a way to handle asynchronous code. I have been using the following (along with a wait for ajaxIsComplete to be true) var ajaxIsComplete = (bool)(driver as IJavaScriptExecutor).ExecuteScript("return jQuery.active == 0"); for a while. I plan to try the other two instances of asynchronous execution mentioned in the above link out. – MikeJRamsey56 Mar 16 '16 at 14:39
  • @floem Sorry about the community wiki edit. I clearly misunderstood the purpose. Can you enlighten me about the kind of community wiki change that would be appropriate here? I was just trying to help. I added my rejected change above as a comment. – MikeJRamsey56 Mar 16 '16 at 14:47