Posted about 3 years ago. Visible to the public. Repeats.

Capybara: Execute asynchronous JavaScript

Capybara provides execute_script and evaluate_script to execute JavaScript code in a Selenium-controlled browser. This however is not a good solution for asynchronous JavaScript.

Enter evaluate_async_script, which allows you to execute some asynchronous code and wait until it finishes. There is a timeout of a couple of seconds, so it will not wait forever.

Use it like this:

Copy
page.evaluate_async_script(<<~JS) let [done] = arguments doSomethingAsynchronous().then(() => { done() // call this to indicate we're done }) JS

You can return results to Ruby by passing them to the done callback:

Copy
result = page.evaluate_async_script(<<~JS) let [done] = arguments doSomethingAsynchronous().then(() => { done("some result") }) JS

Finally, you can pass additional object from Ruby to Javascript:

Copy
result = page.evaluate_async_script(<<~JS, arg1, arg2) let [arg1, arg2, done] = arguments doSomethingAsynchronous().then(() => { done("some result") }) JS

Returning a promise

Warning

The following is not documented anywhere, it may be incorrect.

In newer Capybara versions you may also wrap a promise inside an IIFE and use evaluate_script:

Copy
result = page.evaluate_script(<<~JS) (function() { return doSomethingAsynchronous() })() JS

Of course, you may also add an async-modifier to this function declaration to enable the usage of await. Please check, if this works for you. If not, use evaluate_async_script and chain your calls.

Does your version of Ruby on Rails still receive security updates?
Rails LTS provides security patches for unsupported versions of Ruby on Rails (2.3, 3.2, 4.2 and 5.2).

Owner of this card:

Avatar
Tobias Kraze
Last edit:
8 days ago
by Henning Koch
About this deck:
We are makandra and do test-driven, agile Ruby on Rails software development.
License for source code
Posted by Tobias Kraze to makandra dev
This website uses short-lived cookies to improve usability.
Accept or learn more