diff --git a/README.md b/README.md index 056ac632..cc96efbd 100644 --- a/README.md +++ b/README.md @@ -611,13 +611,23 @@ In drivers which support it, you can easily execute JavaScript: page.execute_script("$('body').empty()") ``` -For simple expressions, you can return the result of the script. Note -that this may break with more complicated expressions: +For simple expressions, you can return the result of the script. ```ruby result = page.evaluate_script('4 + 4'); ``` +For more complicated scripts you'll need to write them as one expression. + +```ruby +result = page.evaluate_script(<<~JS, 3, element) + (function(n, el){ + var val = parseInt(el.value, 10); + return n+val; + })(arguments[0], arguments[1]) +JS +``` + ### Modals In drivers which support it, you can accept, dismiss and respond to alerts, confirms and prompts. diff --git a/lib/capybara/spec/session/evaluate_script_spec.rb b/lib/capybara/spec/session/evaluate_script_spec.rb index b6a2db53..3f43e710 100644 --- a/lib/capybara/spec/session/evaluate_script_spec.rb +++ b/lib/capybara/spec/session/evaluate_script_spec.rb @@ -34,4 +34,16 @@ Capybara::SpecHelper.spec '#evaluate_script', requires: [:js] do expect(el).to be_instance_of(Capybara::Node::Element) expect(el).to eq(@session.find(:css, '#change')) end + + it 'should support multi statement via IIFE' do + @session.visit('/with_js') + @session.find(:css, '#change') + el = @session.evaluate_script(<<~JS) + (function(){ + var el = document.getElementById('change'); + return el; + })() + JS + expect(el).to eq(@session.find(:css, '#change')) + end end diff --git a/lib/capybara/spec/session/node_spec.rb b/lib/capybara/spec/session/node_spec.rb index 4054a3c5..96b41edf 100644 --- a/lib/capybara/spec/session/node_spec.rb +++ b/lib/capybara/spec/session/node_spec.rb @@ -774,6 +774,18 @@ Capybara::SpecHelper.spec 'node' do expect(el).to be_instance_of(Capybara::Node::Element) expect(el).to eq(change) end + + it 'should support multiple statements via IIFE' do + @session.visit('/with_js') + change = @session.find(:css, '#change') # ensure page has loaded and element is available + res = change.evaluate_script(<<~JS, 3) + (function(n){ + var el = this; + return [el, n]; + }).apply(this, arguments) + JS + expect(res).to eq [change, 3] + end end describe '#evaluate_async_script', requires: %i[js es_args] do