Add execute/evaluate_script as Element methods
This commit is contained in:
parent
a16defe121
commit
a5b757d6d9
|
@ -1,9 +1,14 @@
|
|||
# Version 3.2.0
|
||||
Release date: unreleased
|
||||
|
||||
### Changed
|
||||
|
||||
* Ruby 2.3.0+ is now required
|
||||
|
||||
### Added
|
||||
|
||||
* New global configuration `default_set_options` used in `Capybara::Node::Element#set` as default `options` hash [Champier Cyril]
|
||||
* `execute_javascript' and `evaluate_javascript` can now be called on elements to run the JS in the context of the element [Thomas Walpole]
|
||||
|
||||
# Version 3.1.0
|
||||
Release date: 2018-05-10
|
||||
|
|
|
@ -347,6 +347,40 @@ module Capybara
|
|||
self
|
||||
end
|
||||
|
||||
##
|
||||
#
|
||||
# Execute the given JS in the context of the element not returning a result. This is useful for scripts that return
|
||||
# complex objects, such as jQuery statements. +execute_script+ should be used over
|
||||
# +evaluate_script+ whenever possible. `this` in the script will refer to the element this is called on.
|
||||
#
|
||||
# @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, *args)
|
||||
session.execute_script(<<~JS, self, *args)
|
||||
(function (){
|
||||
#{script}
|
||||
}).apply(arguments[0], Array.prototype.slice.call(arguments,1));
|
||||
JS
|
||||
end
|
||||
|
||||
##
|
||||
#
|
||||
# Evaluate the given JS in the context of the element and return the result. Be careful when using this with
|
||||
# scripts that return complex objects, such as jQuery statements. +execute_script+ might
|
||||
# be a better alternative. `this` in the script will refer to the element this is called on.
|
||||
#
|
||||
# @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, *args)
|
||||
session.evaluate_script(<<~JS, self, *args)
|
||||
(function(){
|
||||
return #{script}
|
||||
}).apply(arguments[0], Array.prototype.slice.call(arguments,1));
|
||||
JS
|
||||
end
|
||||
|
||||
def reload
|
||||
if @allow_reload
|
||||
begin
|
||||
|
|
|
@ -455,6 +455,48 @@ Capybara::SpecHelper.spec "node" do
|
|||
end
|
||||
end
|
||||
|
||||
describe "#execute_script", requires: %i[js es_args] do
|
||||
it "should execute the given script in the context of the element and return nothing" do
|
||||
@session.visit('/with_js')
|
||||
expect(@session.find(:css, '#change').execute_script("this.textContent = 'Funky Doodle'")).to be_nil
|
||||
expect(@session).to have_css('#change', text: 'Funky Doodle')
|
||||
end
|
||||
|
||||
it "should pass arguments to the script" do
|
||||
@session.visit('/with_js')
|
||||
@session.find(:css, '#change').execute_script("this.textContent = arguments[0]", "Doodle Funk")
|
||||
expect(@session).to have_css('#change', text: 'Doodle Funk')
|
||||
end
|
||||
end
|
||||
|
||||
describe "#evaluate_script", requires: %i[js es_args] do
|
||||
it "should evaluate the given script in the context of the element and return whatever it produces" do
|
||||
@session.visit('/with_js')
|
||||
el = @session.find(:css, '#with_change_event')
|
||||
expect(el.evaluate_script("this.value")).to eq('default value')
|
||||
end
|
||||
|
||||
it "should pass arguments to the script" do
|
||||
@session.visit('/with_js')
|
||||
@session.find(:css, '#change').evaluate_script("this.textContent = arguments[0]", "Doodle Funk")
|
||||
expect(@session).to have_css('#change', text: 'Doodle Funk')
|
||||
end
|
||||
|
||||
it "should pass multiple arguments" do
|
||||
@session.visit('/with_js')
|
||||
change = @session.find(:css, '#change')
|
||||
expect(change.evaluate_script("arguments[0] + arguments[1]", 2, 3)).to eq 5
|
||||
end
|
||||
|
||||
it "should support returning elements" do
|
||||
@session.visit('/with_js')
|
||||
change = @session.find(:css, '#change') # ensure page has loaded and element is available
|
||||
el = change.evaluate_script("this")
|
||||
expect(el).to be_instance_of(Capybara::Node::Element)
|
||||
expect(el).to eq(change)
|
||||
end
|
||||
end
|
||||
|
||||
describe '#reload', requires: [:js] do
|
||||
context "without automatic reload" do
|
||||
before { Capybara.automatic_reload = false }
|
||||
|
|
Loading…
Reference in New Issue