Changing :disabled option to be tristate

* Allowing true, false, or :all for all selectors with :disabled option
* Adding skip_if option to Filter to skip the filter (i.e. return true) if this value is passed
This commit is contained in:
Jillian Rosile 2015-09-18 21:22:19 -06:00
parent b826b3556a
commit 1c8406e5e7
6 changed files with 73 additions and 17 deletions

View File

@ -56,7 +56,10 @@ module Capybara
#
# @option options [Boolean] checked Match checked field?
# @option options [Boolean] unchecked Match unchecked field?
# @option options [Boolean] disabled (false) Match disabled field?
# @option options [Boolean, Symbol] disabled (false) Match disabled field?
# * true - only finds a disabled field
# * false - only finds an enabled field
# * :all - finds either an enabled or disabled field
# @option options [Boolean] readonly Match readonly field?
# @option options [String] with Value of field to match on
# @option options [String] type Type of field to match on
@ -91,7 +94,10 @@ module Capybara
# @macro waiting_behavior
#
# @param [String] locator Which button to find
# @option options [Boolean] disabled (false) Match disabled button?
# @option options [Boolean, Symbol] disabled (false) Match disabled button?
# * true - only finds a disabled button
# * false - only finds an enabled button
# * :all - finds either an enabled or disabled button
# @return [Capybara::Node::Element] The found element
#
def find_button(locator, options={})

View File

@ -20,7 +20,11 @@ module Capybara
if @options.has_key?(:valid_values) && !Array(@options[:valid_values]).include?(value)
warn "Invalid value #{value.inspect} passed to filter #{@name}"
end
@block.call(node, value)
if @options.has_key?(:skip_if) && value == @options[:skip_if]
true
else
@block.call(node, value)
end
end
end
@ -115,7 +119,7 @@ Capybara.add_selector(:field) do
xpath { |locator| XPath::HTML.field(locator) }
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) { |node, value| not(value ^ node.disabled?) }
filter(:disabled, default: false, valid_values: [true, false, :all], 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|
@ -131,7 +135,7 @@ Capybara.add_selector(:field) do
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]
states << 'disabled' if options[:disabled] == true
desc << " that is #{states.join(' and ')}" unless states.empty?
desc
end
@ -162,15 +166,15 @@ end
Capybara.add_selector(:button) do
xpath { |locator| XPath::HTML.button(locator) }
filter(:disabled, default: false, boolean: true) { |node, value| not(value ^ node.disabled?) }
describe { |options| " that is disabled" if options[:disabled] }
filter(:disabled, default: false, valid_values: [true, false, :all], skip_if: :all) { |node, value| not(value ^ node.disabled?) }
describe { |options| " that is disabled" if options[:disabled] == true }
end
Capybara.add_selector(:fillable_field) do
label "field"
xpath { |locator| XPath::HTML.fillable_field(locator) }
filter(:disabled, default: false, boolean: true) { |node, value| not(value ^ node.disabled?) }
describe { |options| " that is disabled" if options[:disabled] }
filter(:disabled, default: false, valid_values: [true, false, :all], skip_if: :all) { |node, value| not(value ^ node.disabled?) }
describe { |options| " that is disabled" if options[:disabled] == true }
end
Capybara.add_selector(:radio_button) do
@ -179,13 +183,13 @@ Capybara.add_selector(:radio_button) do
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) { |node, value| not(value ^ node.disabled?) }
filter(:disabled, default: false, valid_values: [true, false, :all], skip_if: :all) { |node, value| not(value ^ node.disabled?) }
describe do |options|
desc, states = "", []
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]
states << 'disabled' if options[:disabled] == true
desc << " that is #{states.join(' and ')}" unless states.empty?
desc
end
@ -196,13 +200,13 @@ Capybara.add_selector(:checkbox) do
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) { |node, value| not(value ^ node.disabled?) }
filter(:disabled, default: false, valid_values: [true, false, :all], skip_if: :all) { |node, value| not(value ^ node.disabled?) }
describe do |options|
desc, states = "", []
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]
states << 'disabled' if options[:disabled] == true
desc << " that is #{states.join(' and ')}" unless states.empty?
desc
end
@ -220,13 +224,13 @@ Capybara.add_selector(:select) do
actual = node.all(:xpath, './/option').select { |option| option.selected? }.map { |option| option.text }
[selected].flatten.sort == actual.sort
end
filter(:disabled, default: false, boolean: true) { |node, value| not(value ^ node.disabled?) }
filter(:disabled, default: false, valid_values: [true, false, :all], skip_if: :all) { |node, value| not(value ^ node.disabled?) }
describe do |options|
desc = ""
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]
desc << " that is disabled" if options[:disabled] == true
desc
end
end
@ -238,8 +242,8 @@ end
Capybara.add_selector(:file_field) do
label "file field"
xpath { |locator| XPath::HTML.file_field(locator) }
filter(:disabled, default: false, boolean: true) { |node, value| not(value ^ node.disabled?) }
describe { |options| " that is disabled" if options[:disabled] }
filter(:disabled, default: false, valid_values: [true, false, :all], skip_if: :all) { |node, value| not(value ^ node.disabled?) }
describe { |options| " that is disabled" if options[:disabled] == true}
end
Capybara.add_selector(:table) do

View File

@ -29,4 +29,26 @@ Capybara::SpecHelper.spec '#find_button' do
end.to raise_error(Capybara::ElementNotFound)
end
end
context "with :disabled option" do
it "should find disabled buttons when true" do
expect(@session.find_button('Disabled button', :disabled => true).value).to eq("Disabled button")
end
it "should not find disabled buttons when false" do
expect do
@session.find_button('Disabled button', :disabled => false)
end.to raise_error(Capybara::ElementNotFound)
end
it "should default to not finding disabled buttons" do
expect do
@session.find_button('Disabled button')
end.to raise_error(Capybara::ElementNotFound)
end
it "should find disabled buttons when :all" do
expect(@session.find_button('Disabled button', :disabled => :all).value).to eq("Disabled button")
end
end
end

View File

@ -60,6 +60,14 @@ Capybara::SpecHelper.spec '#find_field' do
@session.find_field("Disabled Checkbox")
end.to raise_error(Capybara::ElementNotFound)
end
it "should find disabled fields when :all" do
expect(@session.find_field("Disabled Checkbox", :disabled => :all)[:name]).to eq("form[disabled_checkbox]")
end
it "should find enabled fields when :all" do
expect(@session.find_field('Dog', :disabled => :all).value).to eq('dog')
end
end

View File

@ -24,6 +24,14 @@ Capybara::SpecHelper.spec '#has_button?' do
it "should be false for disabled buttons if :disabled => false" do
expect(@session).not_to have_button('Disabled button', :disabled => false)
end
it "should be true for disabled buttons if :disabled => :all" do
expect(@session).to have_button('Disabled button', :disabled => :all)
end
it "should be true for enabled buttons if :disabled => :all" do
expect(@session).to have_button('med', :disabled => :all)
end
end
Capybara::SpecHelper.spec '#has_no_button?' do

View File

@ -142,6 +142,14 @@ Capybara::SpecHelper.spec '#has_checked_field?' do
expect(@session).not_to have_checked_field('Disabled Checkbox', :disabled => false)
end
it "should be true for disabled checkboxes if :disabled => :all" do
expect(@session).to have_checked_field('Disabled Checkbox', :disabled => :all)
end
it "should be true for enabled checkboxes if :disabled => :all" do
expect(@session).to have_checked_field('gender_female', :disabled => :all)
end
it "should be true after an unchecked checkbox is checked" do
@session.check('form_pets_cat')
expect(@session).to have_checked_field('form_pets_cat')