Support optional passing of arguments to execute/evaluate_script

This commit is contained in:
Thomas Walpole 2016-12-22 16:22:46 -08:00
parent 9afdc74346
commit 2875482574
5 changed files with 48 additions and 10 deletions

View File

@ -28,11 +28,11 @@ class Capybara::Driver::Base
raise Capybara::NotSupportedByDriverError, 'Capybara::Driver::Base#go_forward'
end
def execute_script(script)
def execute_script(script, *args)
raise Capybara::NotSupportedByDriverError, 'Capybara::Driver::Base#execute_script'
end
def evaluate_script(script)
def evaluate_script(script, *args)
raise Capybara::NotSupportedByDriverError, 'Capybara::Driver::Base#evaluate_script'
end

View File

@ -86,12 +86,12 @@ class Capybara::Selenium::Driver < Capybara::Driver::Base
def wait?; true; end
def needs_server?; true; end
def execute_script(script)
browser.execute_script script
def execute_script(script, *args)
browser.execute_script script, *args
end
def evaluate_script(script)
browser.execute_script "return #{script}"
def evaluate_script(script, *args)
browser.execute_script "return #{script}", *args
end
def save_screenshot(path, _options={})

View File

@ -602,10 +602,16 @@ module Capybara
# +evaluate_script+ whenever possible.
#
# @param [String] script A string of JavaScript to execute
# @param args Optional arguments that will be passed to the script. Driver support for this is optional and types of objects supported may differ between drivers
#
def execute_script(script)
def execute_script(script, *args)
@touched = true
driver.execute_script(script)
if driver.method(:execute_script).arity == 1
raise Capybara::NotSupportedByDriverError, "The current driver does not support arguments being passed with execute_script" unless args.empty?
driver.execute_script(script)
else
driver.execute_script(script, *args.map { |arg| arg.is_a?(Capybara::Node::Element) ? arg.native : arg} )
end
end
##
@ -617,9 +623,14 @@ module Capybara
# @param [String] script A string of JavaScript to evaluate
# @return [Object] The result of the evaluated JavaScript (may be driver specific)
#
def evaluate_script(script)
def evaluate_script(script, *args)
@touched = true
driver.evaluate_script(script)
if driver.method(:evaluate_script).arity == 1
raise Capybara::NotSupportedByDriverError, "The current driver does not support arguments being passed with execute_script" unless args.empty?
driver.evaluate_script(script)
else
driver.evaluate_script(script, *args.map { |arg| arg.is_a?(Capybara::Node::Element) ? arg.native : arg} )
end
end
##

View File

@ -4,4 +4,18 @@ Capybara::SpecHelper.spec "#evaluate_script", requires: [:js] do
@session.visit('/with_js')
expect(@session.evaluate_script("1+3")).to eq(4)
end
it "should pass arguments to the script" do
@session.visit('/with_js')
@session.evaluate_script("document.getElementById('change').textContent = arguments[0]", "Doodle Funk")
expect(@session).to have_css('#change', text: 'Doodle Funk')
end
it "should support passing elements as arguments to the script" do
@session.visit('/with_js')
el = @session.find(:css, '#change')
@session.evaluate_script("arguments[0].textContent = arguments[1]", el, "Doodle Funk")
expect(@session).to have_css('#change', text: 'Doodle Funk')
end
end

View File

@ -10,4 +10,17 @@ Capybara::SpecHelper.spec "#execute_script", requires: [:js] do
@session.visit('/with_js')
expect{ @session.execute_script("$('#change').text('Funky Doodle')") }.not_to raise_error
end
it "should pass arguments to the script" do
@session.visit('/with_js')
@session.execute_script("document.getElementById('change').textContent = arguments[0]", "Doodle Funk")
expect(@session).to have_css('#change', text: 'Doodle Funk')
end
it "should support passing elements as arguments to the script" do
@session.visit('/with_js')
el = @session.find(:css, '#change')
@session.execute_script("arguments[1].textContent = arguments[0]", "Doodle Funk", el)
expect(@session).to have_css('#change', text: 'Doodle Funk')
end
end