Skip to content

Commit 648ac5c

Browse files
twalpolepirj
authored andcommitted
Support multiple matchers for Capybara/VisibilityMatcher cop
1 parent 9d17505 commit 648ac5c

File tree

4 files changed

+59
-20
lines changed

4 files changed

+59
-20
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
* Add new `RSpec/VariableName` cop. ([@tejasbubane][])
66
* Add new `RSpec/VariableDefinition` cop. ([@tejasbubane][])
7+
* Expand `Capybara/VisibilityMatcher` to support more than just `have_selector`. ([@twalpole][])
78

89
## 1.39.0 (2020-05-01)
910

@@ -506,3 +507,4 @@ Compatibility release so users can upgrade RuboCop to 0.51.0. No new features.
506507
[@aried3r]: https://github.com/aried3r
507508
[@AlexWayfer]: https://github.com/AlexWayfer
508509
[@tejasbubane]: https://github.com/tejasbubane
510+
[@twalpole]: https://github.com/twalpole

lib/rubocop/cop/rspec/capybara/visibility_matcher.rb

Lines changed: 26 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -18,35 +18,50 @@ module Capybara
1818
#
1919
# # bad
2020
# expect(page).to have_selector('.foo', visible: false)
21-
#
22-
# # bad
23-
# expect(page).to have_selector('.foo', visible: true)
24-
#
25-
# # good
26-
# expect(page).to have_selector('.foo', visible: :all)
27-
#
28-
# # good
29-
# expect(page).to have_selector('.foo', visible: :hidden)
21+
# expect(page).to have_css('.foo', visible: true)
22+
# expect(page).to have_link('my link', visible: false)
3023
#
3124
# # good
3225
# expect(page).to have_selector('.foo', visible: :visible)
26+
# expect(page).to have_css('.foo', visible: :all)
27+
# expect(page).to have_link('my link', visible: :hidden)
3328
#
3429
class VisibilityMatcher < Cop
3530
MSG_FALSE = 'Use `:all` or `:hidden` instead of `false`.'
3631
MSG_TRUE = 'Use `:visible` instead of `true`.'
32+
CAPYBARA_MATCHER_METHODS = %i[
33+
have_selector
34+
have_css
35+
have_xpath
36+
have_link
37+
have_button
38+
have_field
39+
have_select
40+
have_table
41+
have_checked_field
42+
have_unchecked_field
43+
have_text
44+
have_content
45+
].freeze
3746

3847
def_node_matcher :visible_true?, <<~PATTERN
39-
(send nil? :have_selector ... (hash <$(pair (sym :visible) true) ...>))
48+
(send nil? #capybara_matcher? ... (hash <$(pair (sym :visible) true) ...>))
4049
PATTERN
4150

4251
def_node_matcher :visible_false?, <<~PATTERN
43-
(send nil? :have_selector ... (hash <$(pair (sym :visible) false) ...>))
52+
(send nil? #capybara_matcher? ... (hash <$(pair (sym :visible) false) ...>))
4453
PATTERN
4554

4655
def on_send(node)
4756
visible_false?(node) { |arg| add_offense(arg, message: MSG_FALSE) }
4857
visible_true?(node) { |arg| add_offense(arg, message: MSG_TRUE) }
4958
end
59+
60+
private
61+
62+
def capybara_matcher?(method_name)
63+
CAPYBARA_MATCHER_METHODS.include? method_name
64+
end
5065
end
5166
end
5267
end

manual/cops_capybara.md

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -109,18 +109,13 @@ symbol values, `:all`, `:hidden` or `:visible`.
109109
```ruby
110110
# bad
111111
expect(page).to have_selector('.foo', visible: false)
112-
113-
# bad
114-
expect(page).to have_selector('.foo', visible: true)
115-
116-
# good
117-
expect(page).to have_selector('.foo', visible: :all)
118-
119-
# good
120-
expect(page).to have_selector('.foo', visible: :hidden)
112+
expect(page).to have_css('.foo', visible: true)
113+
expect(page).to have_link('my link', visible: false)
121114

122115
# good
123116
expect(page).to have_selector('.foo', visible: :visible)
117+
expect(page).to have_css('.foo', visible: :all)
118+
expect(page).to have_link('my link', visible: :hidden)
124119
```
125120

126121
### Configurable attributes

spec/rubocop/cop/rspec/capybara/visibility_matcher_spec.rb

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,33 @@
1717
RUBY
1818
end
1919

20+
it 'recognizes multiple matchers' do
21+
expect_offense(<<-RUBY)
22+
expect(page).to have_css('.profile', visible: false)
23+
^^^^^^^^^^^^^^ Use `:all` or `:hidden` instead of `false`.
24+
expect(page).to have_xpath('.//profile', visible: false)
25+
^^^^^^^^^^^^^^ Use `:all` or `:hidden` instead of `false`.
26+
expect(page).to have_link('news', visible: false)
27+
^^^^^^^^^^^^^^ Use `:all` or `:hidden` instead of `false`.
28+
expect(page).to have_button('login', visible: false)
29+
^^^^^^^^^^^^^^ Use `:all` or `:hidden` instead of `false`.
30+
expect(page).to have_field('name', visible: false)
31+
^^^^^^^^^^^^^^ Use `:all` or `:hidden` instead of `false`.
32+
expect(page).to have_select('sauce', visible: false)
33+
^^^^^^^^^^^^^^ Use `:all` or `:hidden` instead of `false`.
34+
expect(page).to have_table('arrivals', visible: false)
35+
^^^^^^^^^^^^^^ Use `:all` or `:hidden` instead of `false`.
36+
expect(page).to have_checked_field('cat', visible: false)
37+
^^^^^^^^^^^^^^ Use `:all` or `:hidden` instead of `false`.
38+
expect(page).to have_unchecked_field('cat', visible: false)
39+
^^^^^^^^^^^^^^ Use `:all` or `:hidden` instead of `false`.
40+
expect(page).to have_text('My homepage', visible: false)
41+
^^^^^^^^^^^^^^ Use `:all` or `:hidden` instead of `false`.
42+
expect(page).to have_content('Success', visible: false)
43+
^^^^^^^^^^^^^^ Use `:all` or `:hidden` instead of `false`.
44+
RUBY
45+
end
46+
2047
it 'registers an offense when using a selector`' do
2148
expect_offense(<<-RUBY)
2249
expect(page).to have_selector(:css, '.my_element', visible: false)

0 commit comments

Comments
 (0)