-
-
Notifications
You must be signed in to change notification settings - Fork 271
/
visibility_matcher.rb
69 lines (63 loc) · 2.35 KB
/
visibility_matcher.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
# frozen_string_literal: true
module RuboCop
module Cop
module RSpec
module Capybara
# Checks for boolean visibility in capybara finders.
#
# Capybara lets you find elements that match a certain visibility using
# the `:visible` option. `:visible` accepts both boolean and symbols as
# values, however using booleans can have unwanted effects. `visible:
# false` does not find just invisible elements, but both visible and
# invisible elements. For expressiveness and clarity, use one of the
# symbol values, `:all`, `:hidden` or `:visible`.
# (https://www.rubydoc.info/gems/capybara/Capybara%2FNode%2FFinders:all)
#
# @example
#
# # bad
# expect(page).to have_selector('.foo', visible: false)
# expect(page).to have_css('.foo', visible: true)
# expect(page).to have_link('my link', visible: false)
#
# # good
# expect(page).to have_selector('.foo', visible: :visible)
# expect(page).to have_css('.foo', visible: :all)
# expect(page).to have_link('my link', visible: :hidden)
#
class VisibilityMatcher < Cop
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
have_text
have_content
].freeze
def_node_matcher :visible_true?, <<~PATTERN
(send nil? #capybara_matcher? ... (hash <$(pair (sym :visible) true) ...>))
PATTERN
def_node_matcher :visible_false?, <<~PATTERN
(send nil? #capybara_matcher? ... (hash <$(pair (sym :visible) false) ...>))
PATTERN
def on_send(node)
visible_false?(node) { |arg| add_offense(arg, message: MSG_FALSE) }
visible_true?(node) { |arg| add_offense(arg, message: MSG_TRUE) }
end
private
def capybara_matcher?(method_name)
CAPYBARA_MATCHER_METHODS.include? method_name
end
end
end
end
end
end