diff --git a/CHANGELOG.md b/CHANGELOG.md index 21ee6660b..fb44ee2d6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ * Fix an error for `RSpec/Capybara/SpecificFinders` with no parentheses. ([@ydah][]) * Fix a false positive for `RSpec/NoExpectationExample` with pending using `skip` or `pending` inside an example. ([@ydah][]) * Exclude `have_text` and `have_content` that raise `ArgumentError` with `RSpec/Capybara/VisibilityMatcher` where `:visible` is an invalid option. ([@ydah][]) +* Fix a false negative for `RSpec/Capybara/VisibilityMatcher` with negative matchers. ([@ydah][]) ## 2.13.1 (2022-09-12) diff --git a/lib/rubocop/cop/rspec/capybara/visibility_matcher.rb b/lib/rubocop/cop/rspec/capybara/visibility_matcher.rb index fa2e433e6..c5714332b 100644 --- a/lib/rubocop/cop/rspec/capybara/visibility_matcher.rb +++ b/lib/rubocop/cop/rspec/capybara/visibility_matcher.rb @@ -29,18 +29,20 @@ module Capybara class VisibilityMatcher < Base MSG_FALSE = 'Use `:all` or `:hidden` instead of `false`.' MSG_TRUE = 'Use `:visible` instead of `true`.' - CAPYBARA_MATCHER_METHODS = %i[ - have_selector - have_css - have_xpath - have_link - have_button - have_field - have_select - have_table - have_checked_field - have_unchecked_field - ].freeze + CAPYBARA_MATCHER_METHODS = %w[ + button + checked_field + css + field + link + select + selector + table + unchecked_field + xpath + ].flat_map do |element| + ["have_#{element}".to_sym, "have_no_#{element}".to_sym] + end RESTRICT_ON_SEND = CAPYBARA_MATCHER_METHODS diff --git a/spec/rubocop/cop/rspec/capybara/visibility_matcher_spec.rb b/spec/rubocop/cop/rspec/capybara/visibility_matcher_spec.rb index f67dc1e27..c6c493679 100644 --- a/spec/rubocop/cop/rspec/capybara/visibility_matcher_spec.rb +++ b/spec/rubocop/cop/rspec/capybara/visibility_matcher_spec.rb @@ -38,6 +38,29 @@ RUBY end + it 'recognizes multiple negative matchers' do + expect_offense(<<-RUBY) + expect(page).to have_no_css('.profile', visible: false) + ^^^^^^^^^^^^^^ Use `:all` or `:hidden` instead of `false`. + expect(page).to have_no_xpath('.//profile', visible: false) + ^^^^^^^^^^^^^^ Use `:all` or `:hidden` instead of `false`. + expect(page).to have_no_link('news', visible: false) + ^^^^^^^^^^^^^^ Use `:all` or `:hidden` instead of `false`. + expect(page).to have_no_button('login', visible: false) + ^^^^^^^^^^^^^^ Use `:all` or `:hidden` instead of `false`. + expect(page).to have_no_field('name', visible: false) + ^^^^^^^^^^^^^^ Use `:all` or `:hidden` instead of `false`. + expect(page).to have_no_select('sauce', visible: false) + ^^^^^^^^^^^^^^ Use `:all` or `:hidden` instead of `false`. + expect(page).to have_no_table('arrivals', visible: false) + ^^^^^^^^^^^^^^ Use `:all` or `:hidden` instead of `false`. + expect(page).to have_no_checked_field('cat', visible: false) + ^^^^^^^^^^^^^^ Use `:all` or `:hidden` instead of `false`. + expect(page).to have_no_unchecked_field('cat', visible: false) + ^^^^^^^^^^^^^^ Use `:all` or `:hidden` instead of `false`. + RUBY + end + it 'registers an offense when using a selector`' do expect_offense(<<-RUBY) expect(page).to have_selector(:css, '.my_element', visible: false)