Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can JavaScript talk to Selenium 2?

I know I can get Selenium 2's webdriver to run JavaScript and get return values but so much asynchronous stuff is happening I would like JavaScript to talk to Selenium instead of the other way around. I have done some searching and haven't found anything like this. Do people just generally use implicitly_wait? That seems likely to fail since it's not possible to time everything? Perfect example would be to let Selenium know when an XHR completed or an asynchronous animation with undetermined execution time.

Is this possible? We're using Selenium 2 with Python on Saucelabs.

like image 921
Bjorn Avatar asked Apr 08 '11 19:04

Bjorn


1 Answers

You should look into the execute_async_script() method (JavascriptExecutor.executeAsyncScript in Java, IJavaScriptExecutor.ExecuteAsyncScript() in .NET), which allows you to wait for a callback function. The callback function is automatically appended to the arguments array in your JavaScript function. So, assuming you have a JavaScript function already on the page that waits until the condition you want, you could do something like the following (Java code below, C# and Python code should be similar):

String script = "var callback = arguments[arguments.length - 1];"
    + "callback(myJavaScriptFunctionThatWaitsUntilReady());";

driver.manage().timeouts().setScriptTimeout(15, TimeUnit.SECONDS);
((JavascriptExecutor)driver).executeAsyncScript(script);

It might be possible to be even more clever and pass the callback function directly to an event that returns the proper data. You can find more information on the executeAsyncScript() function in the project JavaDocs, and can find sample code for this in the project source tree. There's a great example of waiting for an XHR to complete in the tests in this file.

If this isn't yet available in the version of the Python bindings available for use with SauceLabs, I would expect it to be available before long. Admittedly, in a sense, this is pushing the "poll for desired state" from your test case into JavaScript, but it would make your test more readable.

like image 151
JimEvans Avatar answered Oct 16 '22 18:10

JimEvans