diff --git a/lib/capybara/selector.rb b/lib/capybara/selector.rb index 295d1776..0ed47a4e 100644 --- a/lib/capybara/selector.rb +++ b/lib/capybara/selector.rb @@ -11,13 +11,21 @@ Capybara::Selector::FilterSet.add(:_field) do expression_filter(:name) { |xpath, val| xpath[XPath.attr(:name) == val] } expression_filter(:placeholder) { |xpath, val| xpath[XPath.attr(:placeholder) == val] } + expression_filter(:disabled) { |xpath, val| val ? xpath : xpath[~XPath.attr(:disabled)] } + + describe(:expression_filters) do |name: nil, placeholder: nil, disabled: nil, **| + desc = +'' + desc << ' that is not disabled' if disabled == false + desc << " with name #{name}" if name + desc << " with placeholder #{placeholder}" if placeholder + desc + end describe(:node_filters) do |checked: nil, unchecked: nil, disabled: nil, multiple: nil, **| desc, states = +'', [] states << 'checked' if checked || (unchecked == false) states << 'not checked' if unchecked || (checked == false) states << 'disabled' if disabled == true - states << 'not disabled' if disabled == false desc << " that is #{states.join(' and ')}" unless states.empty? desc << ' with the multiple attribute' if multiple == true desc << ' without the multiple attribute' if multiple == false @@ -68,11 +76,8 @@ Capybara.add_selector(:field, locator_type: [String, Symbol]) do end end - describe_expression_filters do |type: nil, **options| - desc = +'' - (expression_filters.keys & options.keys).each { |ef| desc << " with #{ef} #{options[ef]}" } - desc << " of type #{type.inspect}" if type - desc + describe_expression_filters do |type: nil, **| + type ? " of type #{type.inspect}" : '' end describe_node_filters do |**options| @@ -90,6 +95,7 @@ Capybara.add_selector(:fieldset, locator_type: [String, Symbol]) do end node_filter(:disabled, :boolean) { |node, value| !(value ^ node.disabled?) } + expression_filter(:disabled) { |xpath, val| val ? xpath : xpath[~XPath.attr(:disabled)] } end Capybara.add_selector(:link, locator_type: [String, Symbol]) do @@ -161,8 +167,14 @@ Capybara.add_selector(:button, locator_type: [String, Symbol]) do end node_filter(:disabled, :boolean, default: false, skip_if: :all) { |node, value| !(value ^ node.disabled?) } + expression_filter(:disabled) { |xpath, val| val ? xpath : xpath[~XPath.attr(:disabled)] } + + describe_expression_filters do |disabled: nil, **options| + desc = +'' + desc << ' that is not disabled' if disabled == false + (expression_filters.keys & options.keys).inject(desc) { |memo, ef| memo << " with #{ef} #{options[ef]}" } + end - describe_expression_filters describe_node_filters do |disabled: nil, **| ' that is disabled' if disabled == true end @@ -210,7 +222,6 @@ Capybara.add_selector(:fillable_field, locator_type: [String, Symbol]) do end end - describe_expression_filters describe_node_filters do |**options| " with value #{options[:with].to_s.inspect}" if options.key?(:with) end @@ -234,7 +245,6 @@ Capybara.add_selector(:radio_button, locator_type: [String, Symbol]) do end end - describe_expression_filters describe_node_filters do |option: nil, **| " with value #{option.inspect}" if option end @@ -257,7 +267,6 @@ Capybara.add_selector(:checkbox, locator_type: [String, Symbol]) do end end - describe_expression_filters describe_node_filters do |option: nil, **| " with value #{option.inspect}" if option end @@ -304,18 +313,18 @@ Capybara.add_selector(:select, locator_type: [String, Symbol]) do end end - describe_expression_filters do |with_options: nil, **opts| + describe_expression_filters do |with_options: nil, **| desc = +'' desc << " with at least options #{with_options.inspect}" if with_options - desc << describe_all_expression_filters(opts) desc end - describe_node_filters do |options: nil, selected: nil, with_selected: nil, **| + describe_node_filters do |options: nil, selected: nil, with_selected: nil, disabled: nil, **| desc = +'' desc << " with options #{options.inspect}" if options desc << " with #{selected.inspect} selected" if selected desc << " with at least #{with_selected.inspect} selected" if with_selected + desc << ' which is disabled' if disabled desc end end @@ -343,10 +352,9 @@ Capybara.add_selector(:datalist_input, locator_type: [String, Symbol]) do end end - describe_expression_filters do |with_options: nil, **opts| + describe_expression_filters do |with_options: nil, **| desc = +'' desc << " with at least options #{with_options.inspect}" if with_options - desc << describe_all_expression_filters(opts) desc end @@ -363,11 +371,19 @@ Capybara.add_selector(:option, locator_type: [String, Symbol]) do end node_filter(:disabled, :boolean) { |node, value| !(value ^ node.disabled?) } + expression_filter(:disabled) { |xpath, val| val ? xpath : xpath[~XPath.attr(:disabled)] } + node_filter(:selected, :boolean) { |node, value| !(value ^ node.selected?) } + describe_expression_filters do |disabled: nil, **options| + desc = +'' + desc << ' that is not disabled' if disabled == false + (expression_filters.keys & options.keys).inject(desc) { |memo, ef| memo << " with #{ef} #{options[ef]}" } + end + describe_node_filters do |**options| desc = +'' - desc << " that is#{' not' unless options[:disabled]} disabled" if options.key?(:disabled) + desc << ' that is disabled' if options[:disabled] desc << " that is#{' not' unless options[:selected]} selected" if options.key?(:selected) desc end @@ -384,9 +400,16 @@ Capybara.add_selector(:datalist_option, locator_type: [String, Symbol]) do end node_filter(:disabled, :boolean) { |node, value| !(value ^ node.disabled?) } + expression_filter(:disabled) { |xpath, val| val ? xpath : xpath[~XPath.attr(:disabled)] } + + describe_expression_filters do |disabled: nil, **options| + desc = +'' + desc << ' that is not disabled' if disabled == false + (expression_filters.keys & options.keys).inject(desc) { |memo, ef| memo << " with #{ef} #{options[ef]}" } + end describe_node_filters do |**options| - " that is#{' not' unless options[:disabled]} disabled" if options.key?(:disabled) + ' that is disabled' if options[:disabled] end end @@ -400,8 +423,6 @@ Capybara.add_selector(:file_field, locator_type: [String, Symbol]) do end filter_set(:_field, %i[disabled multiple name]) - - describe_expression_filters end Capybara.add_selector(:label, locator_type: [String, Symbol]) do diff --git a/lib/capybara/spec/session/attach_file_spec.rb b/lib/capybara/spec/session/attach_file_spec.rb index 650f955c..9fbe6d07 100644 --- a/lib/capybara/spec/session/attach_file_spec.rb +++ b/lib/capybara/spec/session/attach_file_spec.rb @@ -121,7 +121,7 @@ Capybara::SpecHelper.spec '#attach_file' do context "with a locator that doesn't exist" do it 'should raise an error' do - msg = 'Unable to find file field "does not exist"' + msg = /Unable to find file field "does not exist"/ expect do @session.attach_file('does not exist', with_os_path_separators(test_file_path)) end.to raise_error(Capybara::ElementNotFound, msg) diff --git a/lib/capybara/spec/session/check_spec.rb b/lib/capybara/spec/session/check_spec.rb index e76caee3..5d54c179 100644 --- a/lib/capybara/spec/session/check_spec.rb +++ b/lib/capybara/spec/session/check_spec.rb @@ -83,7 +83,7 @@ Capybara::SpecHelper.spec '#check' do context "with a locator that doesn't exist" do it 'should raise an error' do - msg = 'Unable to find checkbox "does not exist"' + msg = /Unable to find checkbox "does not exist"/ expect do @session.check('does not exist') end.to raise_error(Capybara::ElementNotFound, msg) @@ -171,11 +171,11 @@ Capybara::SpecHelper.spec '#check' do end it 'should raise original error when no label available' do - expect { @session.check('form_cars_ariel') }.to raise_error(Capybara::ElementNotFound, 'Unable to find visible checkbox "form_cars_ariel"') + expect { @session.check('form_cars_ariel') }.to raise_error(Capybara::ElementNotFound, /Unable to find visible checkbox "form_cars_ariel"/) end it 'should raise error if not allowed to click label' do - expect { @session.check('form_cars_mclaren', allow_label_click: false) }.to raise_error(Capybara::ElementNotFound, 'Unable to find visible checkbox "form_cars_mclaren"') + expect { @session.check('form_cars_mclaren', allow_label_click: false) }.to raise_error(Capybara::ElementNotFound, /Unable to find visible checkbox "form_cars_mclaren"/) end end @@ -187,7 +187,7 @@ Capybara::SpecHelper.spec '#check' do end it 'should raise error if checkbox not visible' do - expect { @session.check('form_cars_mclaren') }.to raise_error(Capybara::ElementNotFound, 'Unable to find visible checkbox "form_cars_mclaren"') + expect { @session.check('form_cars_mclaren') }.to raise_error(Capybara::ElementNotFound, /Unable to find visible checkbox "form_cars_mclaren"/) end it 'should include node filter in error if verified' do diff --git a/lib/capybara/spec/session/choose_spec.rb b/lib/capybara/spec/session/choose_spec.rb index 435c92a2..b0eb8d83 100644 --- a/lib/capybara/spec/session/choose_spec.rb +++ b/lib/capybara/spec/session/choose_spec.rb @@ -38,7 +38,7 @@ Capybara::SpecHelper.spec '#choose' do context "with a locator that doesn't exist" do it 'should raise an error' do - msg = 'Unable to find radio button "does not exist"' + msg = /Unable to find radio button "does not exist"/ expect do @session.choose('does not exist') end.to raise_error(Capybara::ElementNotFound, msg) @@ -103,7 +103,7 @@ Capybara::SpecHelper.spec '#choose' do end it 'should raise error if not allowed to click label' do - expect { @session.choose('party_democrat', allow_label_click: false) }.to raise_error(Capybara::ElementNotFound, 'Unable to find visible radio button "party_democrat"') + expect { @session.choose('party_democrat', allow_label_click: false) }.to raise_error(Capybara::ElementNotFound, /Unable to find visible radio button "party_democrat"/) end end end diff --git a/lib/capybara/spec/session/click_button_spec.rb b/lib/capybara/spec/session/click_button_spec.rb index 3bc5620a..7b90653a 100644 --- a/lib/capybara/spec/session/click_button_spec.rb +++ b/lib/capybara/spec/session/click_button_spec.rb @@ -352,7 +352,7 @@ Capybara::SpecHelper.spec '#click_button' do context "with a locator that doesn't exist" do it 'should raise an error' do - msg = 'Unable to find button "does not exist"' + msg = /Unable to find button "does not exist"/ expect do @session.click_button('does not exist') end.to raise_error(Capybara::ElementNotFound, msg) diff --git a/lib/capybara/spec/session/fill_in_spec.rb b/lib/capybara/spec/session/fill_in_spec.rb index 07f0c27f..b2f23504 100644 --- a/lib/capybara/spec/session/fill_in_spec.rb +++ b/lib/capybara/spec/session/fill_in_spec.rb @@ -200,7 +200,7 @@ Capybara::SpecHelper.spec '#fill_in' do after { Capybara.ignore_hidden_elements = false } it 'should not find a hidden field' do - msg = 'Unable to find visible field "Super Secret"' + msg = /Unable to find visible field "Super Secret"/ expect do @session.fill_in('Super Secret', with: '777') end.to raise_error(Capybara::ElementNotFound, msg) @@ -209,7 +209,7 @@ Capybara::SpecHelper.spec '#fill_in' do context "with a locator that doesn't exist" do it 'should raise an error' do - msg = 'Unable to find field "does not exist"' + msg = /Unable to find field "does not exist"/ expect do @session.fill_in('does not exist', with: 'Blah blah') end.to raise_error(Capybara::ElementNotFound, msg) diff --git a/lib/capybara/spec/session/uncheck_spec.rb b/lib/capybara/spec/session/uncheck_spec.rb index 23066878..b5ff4200 100644 --- a/lib/capybara/spec/session/uncheck_spec.rb +++ b/lib/capybara/spec/session/uncheck_spec.rb @@ -85,11 +85,11 @@ Capybara::SpecHelper.spec '#uncheck' do end it 'should raise original error when no label available' do - expect { @session.uncheck('form_cars_porsche') }.to raise_error(Capybara::ElementNotFound, 'Unable to find visible checkbox "form_cars_porsche"') + expect { @session.uncheck('form_cars_porsche') }.to raise_error(Capybara::ElementNotFound, /Unable to find visible checkbox "form_cars_porsche"/) end it 'should raise error if not allowed to click label' do - expect { @session.uncheck('form_cars_jaguar', allow_label_click: false) }.to raise_error(Capybara::ElementNotFound, 'Unable to find visible checkbox "form_cars_jaguar"') + expect { @session.uncheck('form_cars_jaguar', allow_label_click: false) }.to raise_error(Capybara::ElementNotFound, /Unable to find visible checkbox "form_cars_jaguar"/) end it 'should include node filter description in error if necessary' do diff --git a/lib/capybara/spec/session/unselect_spec.rb b/lib/capybara/spec/session/unselect_spec.rb index 6b4f44e7..3e11766d 100644 --- a/lib/capybara/spec/session/unselect_spec.rb +++ b/lib/capybara/spec/session/unselect_spec.rb @@ -56,7 +56,7 @@ Capybara::SpecHelper.spec '#unselect' do context "with a locator that doesn't exist" do it 'should raise an error' do - msg = 'Unable to find select box "does not exist"' + msg = /Unable to find select box "does not exist"/ expect do @session.unselect('foo', from: 'does not exist') end.to raise_error(Capybara::ElementNotFound, msg) diff --git a/spec/minitest_spec_spec.rb b/spec/minitest_spec_spec.rb index fc190717..b57b0a7c 100644 --- a/spec/minitest_spec_spec.rb +++ b/spec/minitest_spec_spec.rb @@ -146,6 +146,6 @@ RSpec.describe 'capybara/minitest/spec' do reporter.report expect(output.string).to include('20 runs, 42 assertions, 1 failures, 0 errors, 1 skips') # Make sure error messages are displayed - expect(output.string).to include('expected to find select box "non_existing_form_title" but there were no matches') + expect(output.string).to match(/expected to find select box "non_existing_form_title" .*but there were no matches/) end end diff --git a/spec/rspec/shared_spec_matchers.rb b/spec/rspec/shared_spec_matchers.rb index 1f724ef7..76c00f02 100644 --- a/spec/rspec/shared_spec_matchers.rb +++ b/spec/rspec/shared_spec_matchers.rb @@ -627,8 +627,12 @@ RSpec.shared_examples Capybara::RSpecMatchers do |session, _mode| describe 'have_button matcher' do let(:html) { '' } - it 'gives proper description' do - expect(have_button('A button').description).to eq('have visible button "A button"') + it 'gives proper description with no options' do + expect(have_button('A button').description).to eq('have visible button "A button" that is not disabled') + end + + it 'gives proper description with disabled :any option' do + expect(have_button('A button', disabled: :all).description).to eq('have visible button "A button"') end it 'passes if there is such a button' do @@ -698,7 +702,7 @@ RSpec.shared_examples Capybara::RSpecMatchers do |session, _mode| end it 'gives proper description' do - expect(have_checked_field('it is checked').description).to eq('have visible field "it is checked" that is checked and not disabled') + expect(have_checked_field('it is checked').description).to eq('have visible field "it is checked" that is not disabled that is checked') end context 'with should' do @@ -747,7 +751,7 @@ RSpec.shared_examples Capybara::RSpecMatchers do |session, _mode| end it 'gives proper description' do - expect(have_unchecked_field('unchecked field').description).to eq('have visible field "unchecked field" that is not checked and not disabled') + expect(have_unchecked_field('unchecked field').description).to eq('have visible field "unchecked field" that is not disabled that is not checked') end context 'with should' do