mirror of
https://github.com/teamcapybara/capybara.git
synced 2022-11-09 12:08:07 -05:00
DRY up selectors with filter set
This commit is contained in:
parent
5030a152f3
commit
03bf2ae447
3 changed files with 53 additions and 76 deletions
|
@ -71,8 +71,12 @@ module Capybara
|
|||
# @option options [String] :with The value to fill in - required
|
||||
# @option options [Hash] :fill_options Driver specific options regarding how to fill fields
|
||||
# @option options [Boolean] :multiple Match fields that can have multiple values?
|
||||
# @option options [String] id Match fields that match the id attribute
|
||||
# @option options [String] name Match fields that match the name attribute
|
||||
# @option options [String] placeholder Match fields that match the placeholder attribute
|
||||
#
|
||||
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)
|
||||
|
@ -93,6 +97,8 @@ module Capybara
|
|||
# @param [String] locator Which radio button to choose
|
||||
#
|
||||
# @option options [String] :option Value of the radio_button to choose
|
||||
# @option options [String] id Match fields that match the id attribute
|
||||
# @option options [String] name Match fields that match the name attribute
|
||||
# @macro waiting_behavior
|
||||
# @macro click_label
|
||||
def choose(locator, options={})
|
||||
|
@ -125,6 +131,8 @@ module Capybara
|
|||
# @param [String] locator Which check box to check
|
||||
#
|
||||
# @option options [String] :option Value of the checkbox to select
|
||||
# @option options [String] id Match fields that match the id attribute
|
||||
# @option options [String] name Match fields that match the name attribute
|
||||
# @macro click_label
|
||||
# @macro waiting_behavior
|
||||
#
|
||||
|
@ -158,6 +166,8 @@ module Capybara
|
|||
# @param [String] locator Which check box to uncheck
|
||||
#
|
||||
# @option options [String] :option Value of the checkbox to deselect
|
||||
# @option options [String] id Match fields that match the id attribute
|
||||
# @option options [String] name Match fields that match the name attribute
|
||||
# @macro click_label
|
||||
# @macro waiting_behavior
|
||||
#
|
||||
|
@ -241,8 +251,11 @@ module Capybara
|
|||
# @option options [Symbol] match (Capybara.match) The matching strategy to use (:one, :first, :prefer_exact, :smart).
|
||||
# @option options [Boolean] exact (Capybara.exact) Match the exact label name/contents or accept a partial match.
|
||||
# @option options [Boolean] multiple Match field which allows multiple file selection
|
||||
# @option options [String] id Match fields that match the id attribute
|
||||
# @option options [String] name Match fields that match the name attribute
|
||||
#
|
||||
def attach_file(locator, path, options={})
|
||||
locator, path, options = nil, locator, path if path.is_a? Hash
|
||||
Array(path).each do |p|
|
||||
raise Capybara::FileNotFound, "cannot attach file, #{p} does not exist" unless File.exist?(p.to_s)
|
||||
end
|
||||
|
|
|
@ -67,6 +67,9 @@ module Capybara
|
|||
# @option options [String] with Value of field to match on
|
||||
# @option options [String] type Type of field to match on
|
||||
# @option options [Boolean] multiple Match fields that can have multiple values?
|
||||
# @option options [String] id Match fields that match the id attribute
|
||||
# @option options [String] name Match fields that match the name attribute
|
||||
# @option options [String] placeholder Match fields that match the placeholder attribute
|
||||
# @return [Capybara::Node::Element] The found element
|
||||
#
|
||||
|
||||
|
|
|
@ -80,10 +80,10 @@ module Capybara
|
|||
custom_filters[name] = Filter.new(name, block, options)
|
||||
end
|
||||
|
||||
def filter_set(name)
|
||||
def filter_set(name, filters_to_use = nil)
|
||||
f_set = FilterSet.all[name]
|
||||
f_set.filters.each do | name, filter |
|
||||
custom_filters[name] = filter
|
||||
custom_filters[name] = filter if filters_to_use.nil? || filters_to_use.include?(name)
|
||||
end
|
||||
f_set.descriptions.each { |desc| @filter_set.describe &desc }
|
||||
end
|
||||
|
@ -102,20 +102,6 @@ module Capybara
|
|||
locate_field += XPath.descendant(:label)[XPath.string.n.is(locator)].descendant(xpath)
|
||||
locate_field
|
||||
end
|
||||
|
||||
FilterSet.add(:locate_field) do
|
||||
filter(:id) { |node, id| node['id'] == id }
|
||||
filter(:name) { |node, name| node['name'] == name }
|
||||
filter(:placeholder) { |node, placeholder| node['placeholder'] == placeholder }
|
||||
|
||||
describe do |options|
|
||||
desc = String.new
|
||||
[:id, :name, :placeholder].each do |opt|
|
||||
desc << " with #{opt.to_s} #{options[opt]}" if options.has_key?(opt)
|
||||
end
|
||||
desc
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -131,6 +117,30 @@ Capybara.add_selector(:id) do
|
|||
xpath { |id| XPath.descendant[XPath.attr(:id) == id.to_s] }
|
||||
end
|
||||
|
||||
Capybara::Selector::FilterSet.add(:_field) do
|
||||
filter(:id) { |node, id| node['id'] == id }
|
||||
filter(:name) { |node, name| node['name'] == name }
|
||||
filter(:placeholder) { |node, placeholder| node['placeholder'] == placeholder }
|
||||
filter(:checked, boolean: true) { |node, value| not(value ^ node.checked?) }
|
||||
filter(:unchecked, boolean: true) { |node, value| (value ^ node.checked?) }
|
||||
filter(:disabled, default: false, boolean: true, skip_if: :all) { |node, value| not(value ^ node.disabled?) }
|
||||
filter(:multiple, boolean: true) { |node, value| !(value ^ node[:multiple]) }
|
||||
|
||||
describe do |options|
|
||||
desc, states = String.new, []
|
||||
[:id, :name, :placeholder].each do |opt|
|
||||
desc << " with #{opt.to_s} #{options[opt]}" if options.has_key?(opt)
|
||||
end
|
||||
states << 'checked' if options[:checked] || (options[:unchecked] === false)
|
||||
states << 'not checked' if options[:unchecked] || (options[:checked] === false)
|
||||
states << 'disabled' if options[:disabled] == true
|
||||
desc << " that is #{states.join(' and ')}" unless states.empty?
|
||||
desc << " with the multiple attribute" if options[:multiple] == true
|
||||
desc << " without the multiple attribute" if options[:multiple] === false
|
||||
desc
|
||||
end
|
||||
end
|
||||
|
||||
Capybara.add_selector(:field) do
|
||||
xpath do |locator|
|
||||
xpath = XPath.descendant(:input, :textarea, :select)[~XPath.attr(:type).one_of('submit', 'image', 'hidden')]
|
||||
|
@ -138,11 +148,8 @@ Capybara.add_selector(:field) do
|
|||
xpath
|
||||
end
|
||||
|
||||
filter_set(:locate_field)
|
||||
filter_set(:_field)
|
||||
|
||||
filter(:checked, boolean: true) { |node, value| not(value ^ node.checked?) }
|
||||
filter(:unchecked, boolean: true) { |node, value| (value ^ node.checked?) }
|
||||
filter(:disabled, default: false, boolean: true, skip_if: :all) { |node, value| not(value ^ node.disabled?) }
|
||||
filter(:readonly, boolean: true) { |node, value| not(value ^ node[:readonly]) }
|
||||
filter(:with) { |node, with| node.value == with.to_s }
|
||||
filter(:type) do |node, type|
|
||||
|
@ -152,17 +159,11 @@ Capybara.add_selector(:field) do
|
|||
node[:type] == type
|
||||
end
|
||||
end
|
||||
filter(:multiple, boolean: true) { |node, value| !(value ^ node[:multiple]) }
|
||||
# filter(:multiple, boolean: true) { |node, value| !(value ^ node[:multiple]) }
|
||||
describe do |options|
|
||||
desc, states = String.new, []
|
||||
desc << " of type #{options[:type].inspect}" if options[:type]
|
||||
desc << " with value #{options[:with].to_s.inspect}" if options.has_key?(:with)
|
||||
states << 'checked' if options[:checked] || (options.has_key?(:unchecked) && !options[:unchecked])
|
||||
states << 'not checked' if options[:unchecked] || (options.has_key?(:checked) && !options[:checked])
|
||||
states << 'disabled' if options[:disabled] == true
|
||||
desc << " that is #{states.join(' and ')}" unless states.empty?
|
||||
desc << " with the multiple attribute" if options[:multiple] == true
|
||||
desc << " without the multiple attribute" if options[:multiple] === false
|
||||
desc
|
||||
end
|
||||
end
|
||||
|
@ -226,7 +227,7 @@ Capybara.add_selector(:link_or_button) do
|
|||
self.class.all.values_at(:link, :button).map {|selector| selector.xpath.call(locator)}.reduce(:+)
|
||||
end
|
||||
|
||||
filter(:disabled, default: false, boolean: true) { |node, value| node.tag_name == "a" or not(value ^ node.disabled?) }
|
||||
filter(:disabled, default: false, boolean: true, skip_if: :all) { |node, value| node.tag_name == "a" or not(value ^ node.disabled?) }
|
||||
|
||||
describe { |options| " that is disabled" if options[:disabled] }
|
||||
end
|
||||
|
@ -239,18 +240,7 @@ Capybara.add_selector(:fillable_field) do
|
|||
xpath
|
||||
end
|
||||
|
||||
filter_set(:locate_field)
|
||||
|
||||
filter(:disabled, default: false, boolean: true, skip_if: :all) { |node, value| not(value ^ node.disabled?) }
|
||||
filter(:multiple, boolean: true) { |node, value| !(value ^ node[:multiple]) }
|
||||
|
||||
describe do |options|
|
||||
desc = String.new
|
||||
desc << " that is disabled" if options[:disabled] == true
|
||||
desc << " with the multiple attribute" if options[:multiple] == true
|
||||
desc << " without the multiple attribute" if options[:multiple] === false
|
||||
desc
|
||||
end
|
||||
filter_set(:_field, [:id, :name, :placeholder, :disabled, :multiple])
|
||||
end
|
||||
|
||||
Capybara.add_selector(:radio_button) do
|
||||
|
@ -261,20 +251,13 @@ Capybara.add_selector(:radio_button) do
|
|||
xpath
|
||||
end
|
||||
|
||||
filter_set(:locate_field)
|
||||
filter_set(:_field, [:id, :name, :checked, :unchecked, :disabled])
|
||||
|
||||
filter(:checked, boolean: true) { |node, value| not(value ^ node.checked?) }
|
||||
filter(:unchecked, boolean: true) { |node, value| (value ^ node.checked?) }
|
||||
filter(:option) { |node, value| node.value == value.to_s }
|
||||
filter(:disabled, default: false, boolean: true, skip_if: :all) { |node, value| not(value ^ node.disabled?) }
|
||||
|
||||
describe do |options|
|
||||
desc, states = String.new, []
|
||||
desc = String.new
|
||||
desc << " with value #{options[:option].inspect}" if options[:option]
|
||||
states << 'checked' if options[:checked] || (options.has_key?(:unchecked) && !options[:unchecked])
|
||||
states << 'not checked' if options[:unchecked] || (options.has_key?(:checked) && !options[:checked])
|
||||
states << 'disabled' if options[:disabled] == true
|
||||
desc << " that is #{states.join(' and ')}" unless states.empty?
|
||||
desc
|
||||
end
|
||||
end
|
||||
|
@ -286,20 +269,13 @@ Capybara.add_selector(:checkbox) do
|
|||
xpath
|
||||
end
|
||||
|
||||
filter_set(:locate_field)
|
||||
filter_set(:_field, [:id, :name, :checked, :unchecked, :disabled])
|
||||
|
||||
filter(:checked, boolean: true) { |node, value| not(value ^ node.checked?) }
|
||||
filter(:unchecked, boolean: true) { |node, value| (value ^ node.checked?) }
|
||||
filter(:option) { |node, value| node.value == value.to_s }
|
||||
filter(:disabled, default: false, boolean: true, skip_if: :all) { |node, value| not(value ^ node.disabled?) }
|
||||
|
||||
describe do |options|
|
||||
desc, states = String.new, []
|
||||
desc = String.new
|
||||
desc << " with value #{options[:option].inspect}" if options[:option]
|
||||
states << 'checked' if options[:checked] || (options.has_key?(:unchecked) && !options[:unchecked])
|
||||
states << 'not checked' if options[:unchecked] || (options.has_key?(:checked) && !options[:checked])
|
||||
states << 'disabled' if options[:disabled] == true
|
||||
desc << " that is #{states.join(' and ')}" unless states.empty?
|
||||
desc
|
||||
end
|
||||
end
|
||||
|
@ -312,7 +288,7 @@ Capybara.add_selector(:select) do
|
|||
xpath
|
||||
end
|
||||
|
||||
filter_set(:locate_field)
|
||||
filter_set(:_field, [:id, :name, :placeholder, :disabled, :multiple])
|
||||
|
||||
filter(:options) do |node, options|
|
||||
if node.visible?
|
||||
|
@ -333,17 +309,12 @@ Capybara.add_selector(:select) do
|
|||
actual = node.all(:xpath, './/option', visible: false).select { |option| option.selected? }.map { |option| option.text(:all) }
|
||||
[selected].flatten.sort == actual.sort
|
||||
end
|
||||
filter(:disabled, default: false, boolean: true, skip_if: :all) { |node, value| not(value ^ node.disabled?) }
|
||||
filter(:multiple, boolean: true) { |node, value| !(value ^ node[:multiple]) }
|
||||
|
||||
describe do |options|
|
||||
desc = String.new
|
||||
desc << " with options #{options[:options].inspect}" if options[:options]
|
||||
desc << " with at least options #{options[:with_options].inspect}" if options[:with_options]
|
||||
desc << " with #{options[:selected].inspect} selected" if options[:selected]
|
||||
desc << " that is disabled" if options[:disabled] == true
|
||||
desc << " that allows multiple selection" if options[:multiple] == true
|
||||
desc << " that only allows single selection" if options[:multiple] === false
|
||||
desc
|
||||
end
|
||||
end
|
||||
|
@ -374,18 +345,7 @@ Capybara.add_selector(:file_field) do
|
|||
xpath
|
||||
end
|
||||
|
||||
filter_set(:locate_field)
|
||||
|
||||
filter(:disabled, default: false, boolean: true, skip_if: :all) { |node, value| not(value ^ node.disabled?) }
|
||||
filter(:multiple, boolean: true) { |node, value| !(value ^ node[:multiple]) }
|
||||
|
||||
describe do |options|
|
||||
desc = String.new
|
||||
desc << " that is disabled" if options[:disabled] == true
|
||||
desc << " that allows multiple files" if options[:multiple] == true
|
||||
desc << " that only allows a single file" if options[:multiple] === false
|
||||
desc
|
||||
end
|
||||
filter_set(:_field, [:id, :name, :disabled, :multiple])
|
||||
end
|
||||
|
||||
Capybara.add_selector(:label) do
|
||||
|
@ -411,6 +371,7 @@ Capybara.add_selector(:label) do
|
|||
describe do |options|
|
||||
desc = String.new
|
||||
desc << " for #{options[:for]}" if options[:for]
|
||||
desc
|
||||
end
|
||||
end
|
||||
|
||||
|
|
Loading…
Reference in a new issue