Posted over 5 years ago. Visible to the public. Repeats.

Capybara/Selenium: evaluate_script might freeze your browser, use execute_script

In a nutshell: Do not use evaluate_script. Use execute_script instead!


Capybara gives you two different methods for executing Javascript:

Copy
page.evaluate_script("$('input').focus()") page.execute_script("$('input').focus()")

While you can use both, the first line (with evaluate_script) might freeze your Firefox window for 10 seconds.

The reason is that evaluate_script will always return a result. The return value will be converted back to Ruby objects, which in case of complex objects (e.g. a jQuery collection) is very expensive.

Now that you know this, just forget that evaluate_script ever existed and use execute_script.

In cases where you don't care about the return value, it will just run the command. When you do need a return value, simply return it explicitly in your JavaScript snippet, like you would in any normal piece of JavaScript code:

Copy
page.execute_script("return 2 + 3") # => 5

Many Bothan spies have died to bring you this card.

Special case: Poltergeist

The Poltergeist driver for Capybara implements execute_script so that it always returns nil. Therefore you cannot use the previously discussed approach if you need a result value. Luckily there is another workaround. Use evaluate_script, but wrap your JavaScript code in an Immediately Invoked Function Expessions (or IIFEs):

Copy
page.evaluate_script(<<-JAVASCRIPT) (function(){ return 2 + 3 })(); JAVASCRIPT

makandra has been working exclusively with Ruby on Rails since 2007. Our laser focus on a single technology has made us a leader in this space.

Author of this card:

Avatar
Henning Koch
Last edit:
15 days ago
by Daniel Straßner
About this deck:
We are makandra and do test-driven, agile Ruby on Rails software development.
License for source code
Posted by Henning Koch to makandra dev