module Capybara::Node::Actions
def _check_with_label(selector, checked, locator, allow_label_click: session_options.automatic_label_click, **options)
def _check_with_label(selector, checked, locator, allow_label_click: session_options.automatic_label_click, **options) options[:allow_self] = true if locator.nil? synchronize(Capybara::Queries::BaseQuery.wait(options, session_options.default_max_wait_time)) do begin el = find(selector, locator, options) el.set(checked) rescue StandardError => err raise unless allow_label_click && catch_error?(err) begin el ||= find(selector, locator, options.merge(visible: :all)) el.session.find(:label, for: el, visible: true).click unless el.checked? == checked rescue StandardError # swallow extra errors - raise original raise err end end end end
def _reset_style(element)
def _reset_style(element) element.execute_script(RESET_STYLE_SCRIPT) rescue StandardError # rubocop:disable Lint/HandleExceptions swallow extra errors end
def _update_style(element, style)
def _update_style(element, style) element.execute_script(UPDATE_STYLE_SCRIPT, style) rescue Capybara::NotSupportedByDriverError warn 'The :make_visible option is not supported by the current driver - ignoring' end
def attach_file(locator = nil, paths, make_visible: nil, **options) # rubocop:disable Style/OptionalArguments
-
(Capybara::Node::Element)- The file field element
Options Hash:
(**options)-
make_visible(true, Hash) -- 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) -
class(String, Array) -- Match fields that match the class(es) provided -
name(String) -- Match fields that match the name attribute -
id(String) -- Match fields that match the id attribute -
multiple(Boolean) -- Match field which allows multiple file selection -
exact(Boolean) -- Match the exact label name/contents or accept a partial match. -
match(Symbol) -- The matching strategy to use (:one, :first, :prefer_exact, :smart).
Parameters:
-
paths(String, Array) -- The path(s) of the file(s) that will be attached -
locator(String) -- Which field to attach the file to
Overloads:
-
attach_file([locator], paths, **options)
def attach_file(locator = nil, paths, make_visible: nil, **options) # rubocop:disable Style/OptionalArguments Array(paths).each do |path| raise Capybara::FileNotFound, "cannot attach file, #{path} does not exist" unless File.exist?(path.to_s) end options[:allow_self] = true if locator.nil? # Allow user to update the CSS style of the file input since they are so often hidden on a page if make_visible ff = find(:file_field, locator, options.merge(visible: :all)) while_visible(ff, make_visible) { |el| el.set(paths) } else find(:file_field, locator, options).set(paths) end end
def check(locator = nil, **options)
-
(Capybara::Node::Element)- The element checked or the label clicked
Options Hash:
(**options)-
class(String, Array) -- Match fields that match the class(es) provided -
name(String) -- Match fields that match the name attribute -
id(String) -- Match fields that match the id attribute -
option(String) -- Value of the checkbox to select
Parameters:
-
locator(String) -- Which check box to check
Overloads:
-
check([locator], **options)
def check(locator = nil, **options) _check_with_label(:checkbox, true, locator, options) end
def choose(locator = nil, **options)
-
(Capybara::Node::Element)- The element chosen or the label clicked
Options Hash:
(**options)-
class(String, Array) -- Match fields that match the class(es) provided -
name(String) -- Match fields that match the name attribute -
id(String) -- Match fields that match the id attribute -
option(String) -- Value of the radio_button to choose
Parameters:
-
locator(String) -- Which radio button to choose
Overloads:
-
choose([locator], **options)
def choose(locator = nil, **options) _check_with_label(:radio_button, true, locator, options) end
def click_button(locator = nil, **options)
-
(Capybara::Node::Element)- The element clicked
Parameters:
-
options() -- See {Capybara::Node::Finders#find_button} -
locator(String) -- Which button to find
Overloads:
-
click_button([locator], **options)
def click_button(locator = nil, **options) find(:button, locator, options).click end
def click_link(locator = nil, **options)
-
(Capybara::Node::Element)- The element clicked
Parameters:
-
options() -- See {Capybara::Node::Finders#find_link} -
locator(String) -- text, id, Capybara.test_id attribute, title or nested image's alt attribute
Overloads:
-
click_link([locator], options)
def click_link(locator = nil, **options) find(:link, locator, options).click end
def click_link_or_button(locator = nil, **options)
-
(Capybara::Node::Element)- The element clicked
Parameters:
-
locator(String) -- See {Capybara::Node::Actions#click_button} and {Capybara::Node::Actions#click_link}
Overloads:
-
click_link_or_button([locator], options)
Options Hash:
(**options)-
wait(false, Numeric) -- Maximum time to wait for matching element to appear.
def click_link_or_button(locator = nil, **options) find(:link_or_button, locator, options).click end
def fill_in(locator = nil, with:, currently_with: nil, fill_options: {}, **find_options)
-
(Capybara::Node::Element)- The element filled_in
Options Hash:
(**options)-
fill_options(Hash) -- Driver specific options regarding how to fill fields (Defaults come from Capybara.default_set_options) -
class(String, Array) -- Match fields that match the class(es) provided -
placeholder(String) -- Match fields that match the placeholder attribute -
name(String) -- Match fields that match the name attribute -
id(String) -- Match fields that match the id attribute -
multiple(Boolean) -- Match fields that can have multiple values? -
currently_with(String) -- The current value property of the field to fill in
Parameters:
-
with:(String) -- The value to fill_in -
options(Hash) -- -
locator(String) -- Which field to fill in
Overloads:
-
fill_in([locator], with:, **options)
def fill_in(locator = nil, with:, currently_with: nil, fill_options: {}, **find_options) find_options[:with] = currently_with if currently_with find_options[:allow_self] = true if locator.nil? find(:fillable_field, locator, find_options).set(with, fill_options) end
def find_select_or_datalist_input(from, options)
def find_select_or_datalist_input(from, options) synchronize(Capybara::Queries::BaseQuery.wait(options, session_options.default_max_wait_time)) do begin find(:select, from, options) rescue Capybara::ElementNotFound => select_error raise if %i[selected with_selected multiple].any? { |option| options.key?(option) } begin find(:datalist_input, from, options) rescue Capybara::ElementNotFound => dlinput_error raise Capybara::ElementNotFound, "#{select_error.message} and #{dlinput_error.message}" end end end end
def select(value = nil, from: nil, **options)
-
(Capybara::Node::Element)- The option element selected
Parameters:
-
from(String) -- The id, Capybara.test_id atrtribute, name or label of the select box -
value(String) -- Which option to select
def select(value = nil, from: nil, **options) el = from ? find_select_or_datalist_input(from, options) : self if el.respond_to?(:tag_name) && (el.tag_name == 'input') select_datalist_option(el, value) else el.find(:option, value, options).select_option end end
def select_datalist_option(input, value)
def select_datalist_option(input, value) datalist_options = input.evaluate_script(DATALIST_OPTIONS_SCRIPT) option = datalist_options.find { |opt| opt.values_at('value', 'label').include?(value) } raise ::Capybara::ElementNotFound, %(Unable to find datalist option "#{value}") unless option input.set(option['value']) rescue ::Capybara::NotSupportedByDriverError # Implement for drivers that don't support JS datalist = find(:xpath, XPath.descendant(:datalist)[XPath.attr(:id) == input[:list]], visible: false) option = datalist.find(:datalist_option, value, disabled: false) input.set(option.value) end
def uncheck(locator = nil, **options)
-
(Capybara::Node::Element)- The element unchecked or the label clicked
Options Hash:
(**options)-
class(String, Array) -- Match fields that match the class(es) provided -
name(String) -- Match fields that match the name attribute -
id(String) -- Match fields that match the id attribute -
option(String) -- Value of the checkbox to deselect
Parameters:
-
locator(String) -- Which check box to uncheck
Overloads:
-
uncheck([locator], **options)
def uncheck(locator = nil, **options) _check_with_label(:checkbox, false, locator, options) end
def unselect(value = nil, from: nil, **options)
-
(Capybara::Node::Element)- The option element unselected
Parameters:
-
from(String) -- The id, Capybara.test_id attribute, name or label of the select box -
value(String) -- Which option to unselect
def unselect(value = nil, from: nil, **options) scope = from ? find(:select, from, options) : self scope.find(:option, value, options).unselect_option end
def while_visible(element, visible_css)
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 yield element ensure _reset_style(element) end end