lib/capybara/node/actions.rb in capybara-2.18.0 vs lib/capybara/node/actions.rb in capybara-3.0.0.rc1
- old
+ new
@@ -1,10 +1,10 @@
# frozen_string_literal: true
+
module Capybara
module Node
module Actions
-
##
#
# Finds a button or link and clicks it. See {Capybara::Node::Actions#click_button} and
# {Capybara::Node::Actions#click_link} for what locator will match against for each type of element
# @!macro waiting_behavior
@@ -18,12 +18,11 @@
#
# @param [String] locator See {Capybara::Node::Actions#click_button} and {Capybara::Node::Actions#click_link}
#
# @return [Capybara::Node::Element] The element clicked
#
- def click_link_or_button(locator=nil, options={})
- locator, options = nil, locator if locator.is_a? Hash
+ def click_link_or_button(locator = nil, **options)
find(:link_or_button, locator, options).click
end
alias_method :click_on, :click_link_or_button
##
@@ -36,12 +35,11 @@
# @overload click_link([locator], options)
# @param [String] locator text, id, title or nested image's alt attribute
# @param options See {Capybara::Node::Finders#find_link}
#
# @return [Capybara::Node::Element] The element clicked
- def click_link(locator=nil, options={})
- locator, options = nil, locator if locator.is_a? Hash
+ def click_link(locator = nil, **options)
find(:link, locator, options).click
end
##
#
@@ -54,12 +52,11 @@
#
# @overload click_button([locator], options)
# @param [String] locator Which button to find
# @param options See {Capybara::Node::Finders#find_button}
# @return [Capybara::Node::Element] The element clicked
- def click_button(locator=nil, options={})
- locator, options = nil, locator if locator.is_a? Hash
+ def click_button(locator = nil, **options)
find(:button, locator, options).click
end
##
#
@@ -81,16 +78,12 @@
# @option options [String] :name Match fields that match the name attribute
# @option options [String] :placeholder Match fields that match the placeholder attribute
# @option options [String, Array<String>] :class Match fields that match the class(es) provided
#
# @return [Capybara::Node::Element] The element filled_in
- def fill_in(locator, options={})
- locator, options = nil, locator if locator.is_a? Hash
- raise "Must pass a hash containing 'with'" if not options.is_a?(Hash) or not options.has_key?(:with)
- with = options.delete(:with)
- fill_options = options.delete(:fill_options)
- options[:with] = options.delete(:currently_with) if options.has_key?(:currently_with)
+ def fill_in(locator = nil, with:, fill_options: {}, **options)
+ options[:with] = options.delete(:currently_with) if options.key?(:currently_with)
find(:fillable_field, locator, options).set(with, fill_options)
end
# @!macro label_click
# @option options [Boolean] :allow_label_click (Capybara.automatic_label_click) Attempt to click the label to toggle state if element is non-visible.
@@ -111,12 +104,12 @@
# @option options [String, Array<String>] :class Match fields that match the class(es) provided
# @macro waiting_behavior
# @macro label_click
#
# @return [Capybara::Node::Element] The element chosen or the label clicked
- def choose(locator, options={})
- _check_with_label(:radio_button, true, locator, options)
+ def choose(locator = nil, **options)
+ _check_with_label(:radio_button, true, locator, **options)
end
##
#
# Find a check box and mark it as checked. The check box can be found
@@ -134,12 +127,12 @@
# @option options [String, Array<String>] :class Match fields that match the class(es) provided
# @macro label_click
# @macro waiting_behavior
#
# @return [Capybara::Node::Element] The element checked or the label clicked
- def check(locator, options={})
- _check_with_label(:checkbox, true, locator, options)
+ def check(locator, **options)
+ _check_with_label(:checkbox, true, locator, **options)
end
##
#
# Find a check box and mark uncheck it. The check box can be found
@@ -157,12 +150,12 @@
# @option options [String, Array<String>] :class Match fields that match the class(es) provided
# @macro label_click
# @macro waiting_behavior
#
# @return [Capybara::Node::Element] The element unchecked or the label clicked
- def uncheck(locator, options={})
- _check_with_label(:checkbox, false, locator, options)
+ def uncheck(locator = nil, **options)
+ _check_with_label(:checkbox, false, locator, **options)
end
##
#
# If `:from` option is present, `select` finds a select box on the page
@@ -178,17 +171,13 @@
#
# @param [String] value Which option to select
# @option options [String] :from The id, name or label of the select box
#
# @return [Capybara::Node::Element] The option element selected
- def select(value, options={})
- if options.has_key?(:from)
- from = options.delete(:from)
- find(:select, from, options).find(:option, value, options).select_option
- else
- find(:option, value, options).select_option
- end
+ def select(value = nil, from: nil, **options)
+ scope = from ? find(:select, from, options) : self
+ scope.find(:option, value, options).select_option
end
##
#
# Find a select box on the page and unselect a particular option from it. If the select
@@ -201,17 +190,13 @@
#
# @param [String] value Which option to unselect
# @param [Hash{:from => String}] options The id, name or label of the select box
#
# @return [Capybara::Node::Element] The option element unselected
- def unselect(value, options={})
- if options.has_key?(:from)
- from = options.delete(:from)
- find(:select, from, options).find(:option, value, options).unselect_option
- else
- find(:option, value, options).unselect_option
- end
+ def unselect(value = nil, from: nil, **options)
+ scope = from ? find(:select, from, options) : self
+ scope.find(:option, value, options).unselect_option
end
##
#
# Find a file field on the page and attach a file given its path. The file field can
@@ -231,87 +216,80 @@
# @option options [String] name Match fields that match the name attribute
# @option options [String, Array<String>] :class Match fields that match the class(es) provided
# @option options [true, Hash] make_visible A Hash of CSS styles to change before attempting to attach the file, if `true` { opacity: 1, display: 'block', visibility: 'visible' } is used (may not be supported by all drivers)
#
# @return [Capybara::Node::Element] The file field element
- def attach_file(locator, path, options={})
- locator, path, options = nil, locator, path if path.is_a? Hash
+ def attach_file(locator = nil, path, make_visible: nil, **options) # rubocop:disable Style/OptionalArguments
Array(path).each do |p|
raise Capybara::FileNotFound, "cannot attach file, #{p} does not exist" unless File.exist?(p.to_s)
end
# Allow user to update the CSS style of the file input since they are so often hidden on a page
- if style = options.delete(:make_visible)
- style = { opacity: 1, display: 'block', visibility: 'visible' } if style == true
- ff = find(:file_field, locator, options.merge({visible: :all}))
- _update_style(ff, style)
- if ff.visible?
- begin
- ff.set(path)
- ensure
- _reset_style(ff)
- end
- else
- raise ExpectationNotMet, "The style changes in :make_visible did not make the file input visible"
- end
+ if make_visible
+ ff = find(:file_field, locator, options.merge(visible: :all))
+ while_visible(ff, make_visible) { |el| el.set(path) }
else
find(:file_field, locator, options).set(path)
end
end
private
- def _update_style(element, style)
- script = <<-JS
- var el = arguments[0];
- el.capybara_style_cache = el.style.cssText;
- var css = arguments[1];
- for (var prop in css){
- if (css.hasOwnProperty(prop)) {
- el.style[prop] = css[prop]
- }
- }
- JS
+
+ def while_visible(element, visible_css)
+ visible_css = { opacity: 1, display: 'block', visibility: 'visible' } if visible_css == true
+ _update_style(element, visible_css)
+ raise ExpectationNotMet, "The style changes in :make_visible did not make the file input visible" unless element.visible?
begin
- session.execute_script(script, element, style)
- rescue Capybara::NotSupportedByDriverError
- warn "The :make_visible option is not supported by the current driver - ignoring"
+ yield element
+ ensure
+ _reset_style(element)
end
end
+ def _update_style(element, style)
+ session.execute_script(UPDATE_STYLE_SCRIPT, element, style)
+ rescue Capybara::NotSupportedByDriverError
+ warn "The :make_visible option is not supported by the current driver - ignoring"
+ end
+
def _reset_style(element)
- script = <<-JS
- var el = arguments[0];
- if (el.hasOwnProperty('capybara_style_cache')) {
- el.style.cssText = el.capybara_style_cache;
- delete el.capybara_style_cache;
- }
- JS
- begin
- session.execute_script(script, element)
- rescue
- end
+ session.execute_script(RESET_STYLE_SCRIPT, element)
+ rescue # swallow extra errors
end
-
- def _check_with_label(selector, checked, locator, options)
- locator, options = nil, locator if locator.is_a? Hash
- allow_label_click = options.delete(:allow_label_click) { session_options.automatic_label_click }
-
+ def _check_with_label(selector, checked, locator, allow_label_click: session_options.automatic_label_click, **options)
synchronize(Capybara::Queries::BaseQuery.wait(options, session_options.default_max_wait_time)) do
begin
el = find(selector, locator, options)
el.set(checked)
rescue => e
raise unless allow_label_click && catch_error?(e)
begin
el ||= find(selector, locator, options.merge(visible: :all))
- label = find(:label, for: el, visible: true)
- label.click unless (el.checked? == checked)
- rescue
+ find(:label, for: el, visible: true).click unless el.checked? == checked
+ rescue # swallow extra errors - raise original
raise e
end
end
end
end
+ UPDATE_STYLE_SCRIPT = <<-'JS'.freeze
+ var el = arguments[0];
+ el.capybara_style_cache = el.style.cssText;
+ var css = arguments[1];
+ for (var prop in css){
+ if (css.hasOwnProperty(prop)) {
+ el.style[prop] = css[prop]
+ }
+ }
+ JS
+
+ RESET_STYLE_SCRIPT = <<-'JS'.freeze
+ var el = arguments[0];
+ if (el.hasOwnProperty('capybara_style_cache')) {
+ el.style.cssText = el.capybara_style_cache;
+ delete el.capybara_style_cache;
+ }
+ JS
end
end
end