rubocop-capybara 2.23.0 → 3.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +53 -0
- data/README.md +1 -1
- data/config/default.yml +97 -32
- data/lib/rubocop/capybara/plugin.rb +2 -3
- data/lib/rubocop/capybara/version.rb +1 -1
- data/lib/rubocop/cop/capybara/absolute_x_path_in_element_scope.rb +104 -0
- data/lib/rubocop/cop/capybara/always_true_count_query.rb +75 -0
- data/lib/rubocop/cop/capybara/ambiguous_click.rb +1 -1
- data/lib/rubocop/cop/capybara/assert_style.rb +1 -1
- data/lib/rubocop/cop/capybara/chained_find.rb +175 -0
- data/lib/rubocop/cop/capybara/find_all_first.rb +13 -41
- data/lib/rubocop/cop/capybara/ignored_query_option.rb +242 -0
- data/lib/rubocop/cop/capybara/mixin/capybara_help.rb +86 -2
- data/lib/rubocop/cop/capybara/mixin/css_attributes_parser.rb +23 -5
- data/lib/rubocop/cop/capybara/mixin/css_selector.rb +13 -10
- data/lib/rubocop/cop/capybara/mixin/query_methods.rb +120 -0
- data/lib/rubocop/cop/capybara/mixin/visibility.rb +53 -0
- data/lib/rubocop/cop/capybara/modal_method_without_block.rb +37 -0
- data/lib/rubocop/cop/capybara/native_attribute.rb +76 -0
- data/lib/rubocop/cop/capybara/redundant_within_find.rb +10 -21
- data/lib/rubocop/cop/capybara/rspec/current_path_expectation.rb +13 -16
- data/lib/rubocop/cop/capybara/rspec/current_url_expectation.rb +122 -0
- data/lib/rubocop/cop/capybara/rspec/find_element_value_eq.rb +173 -0
- data/lib/rubocop/cop/capybara/rspec/have_content.rb +1 -1
- data/lib/rubocop/cop/capybara/rspec/have_selector.rb +26 -15
- data/lib/rubocop/cop/capybara/rspec/match_style.rb +1 -1
- data/lib/rubocop/cop/capybara/rspec/negation_matcher.rb +1 -1
- data/lib/rubocop/cop/capybara/rspec/negation_matcher_after_visit.rb +2 -2
- data/lib/rubocop/cop/capybara/rspec/predicate_matcher.rb +43 -7
- data/lib/rubocop/cop/capybara/rspec/specific_matcher.rb +8 -2
- data/lib/rubocop/cop/capybara/rspec/visibility_matcher.rb +29 -24
- data/lib/rubocop/cop/capybara/rspec.rb +25 -0
- data/lib/rubocop/cop/capybara/specific_actions.rb +12 -7
- data/lib/rubocop/cop/capybara/specific_finders.rb +149 -28
- data/lib/rubocop/cop/capybara/unordered_window_access.rb +40 -0
- data/lib/rubocop/cop/capybara/visibility_option.rb +64 -0
- data/lib/rubocop/cop/capybara.rb +28 -0
- data/lib/rubocop/cop/capybara_cops.rb +4 -17
- data/lib/rubocop-capybara.rb +7 -5
- metadata +18 -6
- data/config/obsoletion.yml +0 -18
- data/lib/rubocop/cop/capybara/click_link_or_button_style.rb +0 -87
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 5b880f22effca543e3fcbabf13ff06e0055eabeddec7342ec5ff2375a6ceb336
|
|
4
|
+
data.tar.gz: b4937b0aa90a9bb9e095ca0d19418a7ee294bf1bc6cabc84c2001bd8fa46aa92
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: d141ff264d07fb784bc62ec4d47f04153b033e599d3297a1f9b063c8398b877e507cdb3e575c3497ff96612b4acea6ad15a82694b28c03913fd1e59b02423c91
|
|
7
|
+
data.tar.gz: 04abfbff88016558648d3cff263ce0b3ef2413dda3a3f381849d26e3a3bbffcd4b7762c76020d8db0892609e2585af7a0413b41fd20712caec161738f3fa852d
|
data/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,59 @@
|
|
|
2
2
|
|
|
3
3
|
## Edge (Unreleased)
|
|
4
4
|
|
|
5
|
+
## 3.1.0 (2026-10-16)
|
|
6
|
+
|
|
7
|
+
- Add new `Capybara/UnorderedWindowAccess` cop. ([@ydah])
|
|
8
|
+
- Add new `Capybara/AbsoluteXPathInElementScope` cop. ([@ydah])
|
|
9
|
+
- Add new `Capybara/AlwaysTrueCountQuery` cop. ([@ydah])
|
|
10
|
+
- Add new `Capybara/RSpec/CurrentUrlExpectation` cop. ([@ydah])
|
|
11
|
+
- Add new `Capybara/ModalMethodWithoutBlock` cop. ([@ydah])
|
|
12
|
+
- Add new `Capybara/NativeAttribute` cop. ([@ydah])
|
|
13
|
+
- Add new `Capybara/VisibilityOption` cop. ([@ydah])
|
|
14
|
+
- Add new `Capybara/ChainedFind` cop. ([@ydah])
|
|
15
|
+
- Add new `Capybara/IgnoredQueryOption` cop. ([@ydah])
|
|
16
|
+
- Add new `Capybara/RSpec/FindElementValueEq` cop. ([@ydah])
|
|
17
|
+
- Recognize `have_element` and `have_no_element` in the RSpec negation cops. ([@ydah])
|
|
18
|
+
- Detect `have_no_selector` in `Capybara/RSpec/HaveSelector`. ([@ydah])
|
|
19
|
+
- Autocorrect `visible: true` in `Capybara/RSpec/VisibilityMatcher` for known selectors. ([@ydah])
|
|
20
|
+
- Add support for using `find` with `:link` and `:field` in `Capybara/SpecificFinders` cop. ([@ydah])
|
|
21
|
+
- Speed up loading rubocop-capybara by lazily loading only the cops needed for a run. This requires RuboCop 1.89.0+. ([@koic])
|
|
22
|
+
- Fix false positives in `Capybara/RSpec/SpecificMatcher` for input types excluded by `have_field`. ([@ydah])
|
|
23
|
+
- Avoid interpolating literal `#{...}`, `#@...`, and `#$...` patterns in `Capybara/RSpec/CurrentPathExpectation` and `Capybara/RSpec/CurrentUrlExpectation` autocorrection. ([@ydah])
|
|
24
|
+
- Fix false positives and negatives for `Capybara/SpecificActions` when CSS attribute values contain spaces. ([@ydah])
|
|
25
|
+
- Honor `DefaultSelector: null` in selector-dependent cops, including `Capybara/RSpec/HaveSelector`. ([@ydah])
|
|
26
|
+
- Fix false positives for custom elements in `Capybara/SpecificActions` and `Capybara/RSpec/SpecificMatcher`. ([@ydah])
|
|
27
|
+
- Avoid unsafe block autocorrection and unnecessary receiver parentheses in `Capybara/RSpec/PredicateMatcher`. ([@ydah])
|
|
28
|
+
- Fix a crash in `Capybara/RSpec/CurrentPathExpectation` for invalid regexp strings. ([@ydah])
|
|
29
|
+
- Fix `Capybara/SpecificFinders` when CSS id values are `true` or `false`. ([@ydah])
|
|
30
|
+
- Fix a crash in `Capybara/SpecificActions` for blank `find` selectors. ([@ydah])
|
|
31
|
+
- Fix reversed autocorrection in `Capybara/RSpec/PredicateMatcher` for `eql` and `equal` boolean matchers. ([@ydah])
|
|
32
|
+
- Avoid errors and unsafe autocorrection in `Capybara/SpecificFinders` with dynamic `class:` options. ([@ydah])
|
|
33
|
+
- Fix incorrect autocorrections and missed offenses for non-CSS locators in `Capybara/SpecificFinders`. ([@ydah])
|
|
34
|
+
- Use the `:id` selector when `Capybara/RedundantWithinFind` autocorrects `find_by_id`, preserving special and dynamic IDs. ([@ydah])
|
|
35
|
+
- Avoid unsafe `find_field` autocorrections for input types and boolean attributes in `Capybara/SpecificFinders`. ([@ydah])
|
|
36
|
+
- Fix false positives and incorrect autocorrections for `Capybara/FindAllFirst` when `find` or `all` uses `match: :first`. ([@ydah])
|
|
37
|
+
- Avoid `Capybara/FindAllFirst` offenses when the result is used with safe navigation or as a condition. ([@ydah])
|
|
38
|
+
- Fix an incorrect autocorrect for `Capybara/RedundantWithinFind` when `find_by_id` uses a dynamic id. ([@ydah])
|
|
39
|
+
- Fix an incorrect autocorrect for `Capybara/RedundantWithinFind` when a finder call has a block argument. ([@ydah])
|
|
40
|
+
- Fix a false positive for `Capybara/RSpec/HaveSelector` when `DefaultSelector` is unsupported. ([@ydah])
|
|
41
|
+
- Fix an incorrect autocorrect for `Capybara/SpecificFinders` when a selector class is empty or contains an escaped dot. ([@ydah])
|
|
42
|
+
- Fix a false positive for `Capybara/SpecificFinders` when an id selector contains unsupported CSS identifier syntax. ([@ydah])
|
|
43
|
+
- Fix a false negative for `Capybara/RSpec/NegationMatcherAfterVisit` when using `to_not`. ([@ydah])
|
|
44
|
+
- Fix an incorrect autocorrect for `Capybara/RSpec/PredicateMatcher` when `EnforcedStyle: explicit` and `expect` actual is a complex expression. ([@ydah])
|
|
45
|
+
- Fix `Capybara/RSpec/CurrentPathExpectation` autocorrection for `match` when the URL has a query string. ([@ydah])
|
|
46
|
+
- Fix a false positive for `Capybara/SpecificActions` when `click` uses arguments or a block. ([@ydah])
|
|
47
|
+
- Fix an incorrect autocorrect for `Capybara/SpecificFinders` when a selector class is used with nested `class:` options. ([@ydah])
|
|
48
|
+
- Fix CSS attribute parsing when attribute values contain quotes. ([@ydah])
|
|
49
|
+
- Fix CSS attribute parsing to return raw values and format Ruby literals in autocorrection. ([@ydah])
|
|
50
|
+
- Fix a false negative for `Capybara/SpecificFinders` when using `find` with input field attributes. ([@ydah])
|
|
51
|
+
|
|
52
|
+
## 3.0.0 (2026-06-22)
|
|
53
|
+
|
|
54
|
+
- Enable pending cops by default for the 3.0 release. ([@ydah])
|
|
55
|
+
- Remove the deprecated `Capybara/ClickLinkOrButtonStyle` cop. ([@ydah])
|
|
56
|
+
- Remove obsolete cop name migration config for the 2.x to 3.0 transition. ([@ydah])
|
|
57
|
+
|
|
5
58
|
## 2.23.0 (2026-04-30)
|
|
6
59
|
|
|
7
60
|
- Bump RuboCop requirement to +1.81. ([@ydah])
|
data/README.md
CHANGED
data/config/default.yml
CHANGED
|
@@ -9,6 +9,18 @@ Capybara:
|
|
|
9
9
|
- "**/*_steps.rb"
|
|
10
10
|
- "**/features/step_definitions/**/*"
|
|
11
11
|
|
|
12
|
+
Capybara/AbsoluteXPathInElementScope:
|
|
13
|
+
Description: Checks for absolute XPath searches on Capybara elements.
|
|
14
|
+
Enabled: pending
|
|
15
|
+
VersionAdded: '3.1'
|
|
16
|
+
Reference: https://www.rubydoc.info/gems/rubocop-capybara/RuboCop/Cop/Capybara/AbsoluteXPathInElementScope
|
|
17
|
+
|
|
18
|
+
Capybara/AlwaysTrueCountQuery:
|
|
19
|
+
Description: Checks for positive queries that succeed when there are no matches.
|
|
20
|
+
Enabled: pending
|
|
21
|
+
VersionAdded: '3.1'
|
|
22
|
+
Reference: https://www.rubydoc.info/gems/rubocop-capybara/RuboCop/Cop/Capybara/AlwaysTrueCountQuery
|
|
23
|
+
|
|
12
24
|
Capybara/AmbiguousClick:
|
|
13
25
|
Description: Specify the exact target to click on.
|
|
14
26
|
Enabled: false
|
|
@@ -17,82 +29,132 @@ Capybara/AmbiguousClick:
|
|
|
17
29
|
|
|
18
30
|
Capybara/AssertStyle:
|
|
19
31
|
Description: Checks for usage of deprecated assert style method.
|
|
20
|
-
Enabled:
|
|
32
|
+
Enabled: true
|
|
21
33
|
VersionAdded: '2.23'
|
|
34
|
+
VersionChanged: '3.0'
|
|
22
35
|
Reference: https://www.rubydoc.info/gems/rubocop-capybara/RuboCop/Cop/Capybara/AssertStyle
|
|
23
36
|
|
|
24
|
-
Capybara/
|
|
25
|
-
Description:
|
|
26
|
-
Enabled:
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
SupportedStyles:
|
|
31
|
-
- link_or_button
|
|
32
|
-
- strict
|
|
33
|
-
Reference: https://www.rubydoc.info/gems/rubocop-capybara/RuboCop/Cop/Capybara/ClickLinkOrButtonStyle
|
|
37
|
+
Capybara/ChainedFind:
|
|
38
|
+
Description: Avoid chaining `find` methods and combine selectors.
|
|
39
|
+
Enabled: pending
|
|
40
|
+
DefaultSelector: css
|
|
41
|
+
VersionAdded: '3.1'
|
|
42
|
+
Reference: https://www.rubydoc.info/gems/rubocop-capybara/RuboCop/Cop/Capybara/ChainedFind
|
|
34
43
|
|
|
35
44
|
Capybara/FindAllFirst:
|
|
36
45
|
Description: Enforces use of `first` instead of `all` with `first` or `[0]`.
|
|
37
|
-
Enabled:
|
|
46
|
+
Enabled: true
|
|
38
47
|
SafeAutoCorrect: false
|
|
39
48
|
VersionAdded: '2.22'
|
|
40
|
-
VersionChanged: '
|
|
49
|
+
VersionChanged: '3.0'
|
|
41
50
|
Reference: https://www.rubydoc.info/gems/rubocop-capybara/RuboCop/Cop/Capybara/FindAllFirst
|
|
42
51
|
|
|
52
|
+
Capybara/IgnoredQueryOption:
|
|
53
|
+
Description: Checks for query options that have no effect in Capybara.
|
|
54
|
+
Enabled: pending
|
|
55
|
+
DefaultSelector: css
|
|
56
|
+
VersionAdded: '3.1'
|
|
57
|
+
Reference: https://www.rubydoc.info/gems/rubocop-capybara/RuboCop/Cop/Capybara/IgnoredQueryOption
|
|
58
|
+
|
|
59
|
+
Capybara/ModalMethodWithoutBlock:
|
|
60
|
+
Description: Checks that modal handling methods are called with a block.
|
|
61
|
+
Enabled: pending
|
|
62
|
+
VersionAdded: '3.1'
|
|
63
|
+
Reference: https://www.rubydoc.info/gems/rubocop-capybara/RuboCop/Cop/Capybara/ModalMethodWithoutBlock
|
|
64
|
+
|
|
65
|
+
Capybara/NativeAttribute:
|
|
66
|
+
Description: Enforces use of `Element#[]` instead of `native.attribute`.
|
|
67
|
+
Enabled: pending
|
|
68
|
+
SafeAutoCorrect: false
|
|
69
|
+
VersionAdded: '3.1'
|
|
70
|
+
Reference: https://www.rubydoc.info/gems/rubocop-capybara/RuboCop/Cop/Capybara/NativeAttribute
|
|
71
|
+
|
|
43
72
|
Capybara/RedundantWithinFind:
|
|
44
73
|
Description: Checks for redundant `within find(...)` calls.
|
|
45
|
-
Enabled:
|
|
74
|
+
Enabled: true
|
|
46
75
|
VersionAdded: '2.20'
|
|
76
|
+
VersionChanged: '3.0'
|
|
47
77
|
Reference: https://www.rubydoc.info/gems/rubocop-capybara/RuboCop/Cop/Capybara/RedundantWithinFind
|
|
48
78
|
|
|
49
79
|
Capybara/SpecificActions:
|
|
50
80
|
Description: Checks for there is a more specific actions offered by Capybara.
|
|
51
|
-
Enabled:
|
|
81
|
+
Enabled: true
|
|
52
82
|
VersionAdded: '2.14'
|
|
83
|
+
VersionChanged: '3.0'
|
|
53
84
|
Reference: https://www.rubydoc.info/gems/rubocop-capybara/RuboCop/Cop/Capybara/SpecificActions
|
|
54
85
|
|
|
55
86
|
Capybara/SpecificFinders:
|
|
56
87
|
Description: Checks if there is a more specific finder offered by Capybara.
|
|
57
|
-
Enabled:
|
|
88
|
+
Enabled: true
|
|
58
89
|
VersionAdded: '2.13'
|
|
90
|
+
VersionChanged: '3.0'
|
|
59
91
|
Reference: https://www.rubydoc.info/gems/rubocop-capybara/RuboCop/Cop/Capybara/SpecificFinders
|
|
60
92
|
|
|
93
|
+
Capybara/UnorderedWindowAccess:
|
|
94
|
+
Description: Checks positional access to Capybara windows, whose order is undefined.
|
|
95
|
+
Enabled: pending
|
|
96
|
+
VersionAdded: '3.1'
|
|
97
|
+
Reference: https://www.rubydoc.info/gems/rubocop-capybara/RuboCop/Cop/Capybara/UnorderedWindowAccess
|
|
98
|
+
|
|
99
|
+
Capybara/VisibilityOption:
|
|
100
|
+
Description: Checks for boolean values passed to Capybara's `visible` option.
|
|
101
|
+
Enabled: pending
|
|
102
|
+
DefaultSelector: css
|
|
103
|
+
VersionAdded: '3.1'
|
|
104
|
+
Reference: https://www.rubydoc.info/gems/rubocop-capybara/RuboCop/Cop/Capybara/VisibilityOption
|
|
105
|
+
|
|
61
106
|
Capybara/RSpec:
|
|
62
107
|
Enabled: true
|
|
63
108
|
Include: *1
|
|
64
109
|
|
|
65
110
|
Capybara/RSpec/CurrentPathExpectation:
|
|
66
111
|
Description: Checks that no expectations are set on Capybara's `current_path`.
|
|
67
|
-
Enabled:
|
|
112
|
+
Enabled: true
|
|
68
113
|
VersionAdded: '1.18'
|
|
69
|
-
VersionChanged: '
|
|
114
|
+
VersionChanged: '3.0'
|
|
70
115
|
Reference: https://www.rubydoc.info/gems/rubocop-capybara/RuboCop/Cop/Capybara/RSpec/CurrentPathExpectation
|
|
71
116
|
|
|
117
|
+
Capybara/RSpec/CurrentUrlExpectation:
|
|
118
|
+
Description: Checks expectations on `current_url` that bypass Capybara's waiting.
|
|
119
|
+
Enabled: pending
|
|
120
|
+
SafeAutoCorrect: false
|
|
121
|
+
VersionAdded: '3.1'
|
|
122
|
+
Reference: https://www.rubydoc.info/gems/rubocop-capybara/RuboCop/Cop/Capybara/RSpec/CurrentUrlExpectation
|
|
123
|
+
|
|
124
|
+
Capybara/RSpec/FindElementValueEq:
|
|
125
|
+
Description: Checks for expectations on the value of an element found by Capybara.
|
|
126
|
+
Enabled: pending
|
|
127
|
+
SafeAutoCorrect: false
|
|
128
|
+
VersionAdded: '3.1'
|
|
129
|
+
Reference: https://www.rubydoc.info/gems/rubocop-capybara/RuboCop/Cop/Capybara/RSpec/FindElementValueEq
|
|
130
|
+
|
|
72
131
|
Capybara/RSpec/HaveContent:
|
|
73
132
|
Description: Checks for usage of `have_content` and `have_no_content`.
|
|
74
|
-
Enabled:
|
|
133
|
+
Enabled: true
|
|
75
134
|
VersionAdded: '2.23'
|
|
135
|
+
VersionChanged: '3.0'
|
|
76
136
|
Reference: https://www.rubydoc.info/gems/rubocop-capybara/RuboCop/Cop/Capybara/RSpec/HaveContent
|
|
77
137
|
|
|
78
138
|
Capybara/RSpec/HaveSelector:
|
|
79
|
-
Description: Use
|
|
80
|
-
Enabled:
|
|
139
|
+
Description: Use CSS or XPath matchers instead of generic selector matchers.
|
|
140
|
+
Enabled: true
|
|
81
141
|
DefaultSelector: css
|
|
82
142
|
VersionAdded: '2.19'
|
|
143
|
+
VersionChanged: '3.0'
|
|
83
144
|
Reference: https://www.rubydoc.info/gems/rubocop-capybara/RuboCop/Cop/Capybara/RSpec/HaveSelector
|
|
84
145
|
|
|
85
146
|
Capybara/RSpec/MatchStyle:
|
|
86
147
|
Description: Checks for usage of deprecated style methods in RSpec matchers.
|
|
87
|
-
Enabled:
|
|
148
|
+
Enabled: true
|
|
88
149
|
VersionAdded: '2.23'
|
|
150
|
+
VersionChanged: '3.0'
|
|
89
151
|
Reference: https://www.rubydoc.info/gems/rubocop-capybara/RuboCop/Cop/Capybara/RSpec/MatchStyle
|
|
90
152
|
|
|
91
153
|
Capybara/RSpec/NegationMatcher:
|
|
92
154
|
Description: Enforces use of `have_no_*` or `not_to` for negated expectations.
|
|
93
|
-
Enabled:
|
|
155
|
+
Enabled: true
|
|
94
156
|
VersionAdded: '2.14'
|
|
95
|
-
VersionChanged: '
|
|
157
|
+
VersionChanged: '3.0'
|
|
96
158
|
EnforcedStyle: have_no
|
|
97
159
|
SupportedStyles:
|
|
98
160
|
- have_no
|
|
@@ -101,14 +163,14 @@ Capybara/RSpec/NegationMatcher:
|
|
|
101
163
|
|
|
102
164
|
Capybara/RSpec/NegationMatcherAfterVisit:
|
|
103
165
|
Description: Do not allow negative matchers to be used immediately after `visit`.
|
|
104
|
-
Enabled:
|
|
166
|
+
Enabled: true
|
|
105
167
|
VersionAdded: '2.22'
|
|
106
|
-
VersionChanged: '
|
|
168
|
+
VersionChanged: '3.0'
|
|
107
169
|
Reference: https://www.rubydoc.info/gems/rubocop-capybara/RuboCop/Cop/Capybara/RSpec/NegationMatcherAfterVisit
|
|
108
170
|
|
|
109
171
|
Capybara/RSpec/PredicateMatcher:
|
|
110
172
|
Description: Prefer using predicate matcher over using predicate method directly.
|
|
111
|
-
Enabled:
|
|
173
|
+
Enabled: true
|
|
112
174
|
Strict: true
|
|
113
175
|
EnforcedStyle: inflected
|
|
114
176
|
AllowedExplicitMatchers: []
|
|
@@ -116,18 +178,21 @@ Capybara/RSpec/PredicateMatcher:
|
|
|
116
178
|
- inflected
|
|
117
179
|
- explicit
|
|
118
180
|
VersionAdded: '2.19'
|
|
181
|
+
VersionChanged: '3.0'
|
|
119
182
|
Reference: https://www.rubydoc.info/gems/rubocop-capybara/RuboCop/Cop/Capybara/RSpec/PredicateMatcher
|
|
120
183
|
|
|
121
184
|
Capybara/RSpec/SpecificMatcher:
|
|
122
185
|
Description: Checks for there is a more specific matcher offered by Capybara.
|
|
123
|
-
Enabled:
|
|
186
|
+
Enabled: true
|
|
124
187
|
VersionAdded: '2.12'
|
|
125
|
-
VersionChanged: '
|
|
188
|
+
VersionChanged: '3.0'
|
|
126
189
|
Reference: https://www.rubydoc.info/gems/rubocop-capybara/RuboCop/Cop/Capybara/RSpec/SpecificMatcher
|
|
127
190
|
|
|
128
191
|
Capybara/RSpec/VisibilityMatcher:
|
|
129
|
-
Description: Checks for boolean visibility in Capybara
|
|
130
|
-
Enabled:
|
|
192
|
+
Description: Checks for boolean visibility in Capybara RSpec matchers.
|
|
193
|
+
Enabled: true
|
|
194
|
+
SafeAutoCorrect: false
|
|
195
|
+
DefaultSelector: css
|
|
131
196
|
VersionAdded: '1.39'
|
|
132
|
-
VersionChanged:
|
|
197
|
+
VersionChanged: "<<next>>"
|
|
133
198
|
Reference: https://www.rubydoc.info/gems/rubocop-capybara/RuboCop/Cop/Capybara/RSpec/VisibilityMatcher
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
require 'pathname'
|
|
4
|
+
|
|
3
5
|
require 'lint_roller'
|
|
4
6
|
|
|
5
7
|
module RuboCop
|
|
@@ -24,9 +26,6 @@ module RuboCop
|
|
|
24
26
|
def rules(_context)
|
|
25
27
|
project_root = Pathname.new(__dir__).join('../../..')
|
|
26
28
|
|
|
27
|
-
obsoletion = project_root.join('config', 'obsoletion.yml')
|
|
28
|
-
ConfigObsoletion.files << obsoletion if obsoletion.exist?
|
|
29
|
-
|
|
30
29
|
LintRoller::Rules.new(
|
|
31
30
|
type: :path,
|
|
32
31
|
config_format: :rubocop,
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module RuboCop
|
|
4
|
+
module Cop
|
|
5
|
+
module Capybara
|
|
6
|
+
# Checks for absolute XPath searches on Capybara elements.
|
|
7
|
+
#
|
|
8
|
+
# An XPath starting with `//` searches from the document root, even when
|
|
9
|
+
# the query is called on an element. Use `.//` to stay within it.
|
|
10
|
+
# Direct RSpec `let` and named `subject` element definitions are
|
|
11
|
+
# recognized.
|
|
12
|
+
#
|
|
13
|
+
# @example
|
|
14
|
+
# # bad
|
|
15
|
+
# page.find('.dialog').find(:xpath, '//button')
|
|
16
|
+
# dialog = page.find('.dialog')
|
|
17
|
+
# dialog.find(:xpath, '//button')
|
|
18
|
+
# RSpec.describe 'dialog' do
|
|
19
|
+
# let(:dialog) { find('.dialog') }
|
|
20
|
+
# it { dialog.find(:xpath, '//button') }
|
|
21
|
+
# end
|
|
22
|
+
#
|
|
23
|
+
# # good
|
|
24
|
+
# page.find('.dialog').find(:xpath, './/button')
|
|
25
|
+
# page.find(:xpath, '//button')
|
|
26
|
+
#
|
|
27
|
+
class AbsoluteXPathInElementScope < RuboCop::Cop::Base
|
|
28
|
+
include CapybaraHelp
|
|
29
|
+
|
|
30
|
+
MSG = 'Use `.//` for an XPath search within an element.'
|
|
31
|
+
RESTRICT_ON_SEND = %i[find all find_all first].freeze
|
|
32
|
+
RSPEC_GROUPS = %i[
|
|
33
|
+
describe context feature shared_examples shared_context
|
|
34
|
+
].freeze
|
|
35
|
+
RSPEC_HELPERS = %i[let let! subject].freeze
|
|
36
|
+
|
|
37
|
+
# @!method xpath_literal(node)
|
|
38
|
+
def_node_matcher :xpath_literal, '(call _ _ (sym :xpath) $(str _) ...)'
|
|
39
|
+
|
|
40
|
+
# @!method element_finder?(node)
|
|
41
|
+
def_node_matcher :element_finder?, <<~PATTERN
|
|
42
|
+
(call #capybara_receiver? :find ...)
|
|
43
|
+
PATTERN
|
|
44
|
+
|
|
45
|
+
def on_send(node)
|
|
46
|
+
xpath = xpath_literal(node)
|
|
47
|
+
return unless xpath&.value&.start_with?('//')
|
|
48
|
+
return unless element_receiver?(node.receiver)
|
|
49
|
+
|
|
50
|
+
add_offense(xpath)
|
|
51
|
+
end
|
|
52
|
+
alias on_csend on_send
|
|
53
|
+
|
|
54
|
+
private
|
|
55
|
+
|
|
56
|
+
def element_receiver?(node)
|
|
57
|
+
return true if node&.call_type? && element_finder?(node)
|
|
58
|
+
return element_finder?(local_variable_value(node)) if node&.lvar_type?
|
|
59
|
+
|
|
60
|
+
element_finder?(rspec_helper_value(node)) if node&.call_type?
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
def rspec_helper_value(node)
|
|
64
|
+
return unless node.receiver.nil? && node.arguments.empty?
|
|
65
|
+
|
|
66
|
+
node.each_ancestor(:block).each do |group|
|
|
67
|
+
next unless rspec_group?(group)
|
|
68
|
+
|
|
69
|
+
definition = named_helper(group, node.method_name)
|
|
70
|
+
return definition.body if definition
|
|
71
|
+
end
|
|
72
|
+
nil
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
def rspec_group?(block)
|
|
76
|
+
call = block.send_node
|
|
77
|
+
return false unless RSPEC_GROUPS.include?(call.method_name)
|
|
78
|
+
|
|
79
|
+
call.receiver.nil? || (call.receiver.const_type? &&
|
|
80
|
+
call.receiver.const_name == 'RSpec')
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
def named_helper(group, name)
|
|
84
|
+
body = group.body
|
|
85
|
+
statements = body.begin_type? ? body.children : [body]
|
|
86
|
+
statements.reverse_each.find do |statement|
|
|
87
|
+
named_rspec_helper?(statement, name)
|
|
88
|
+
end
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
def named_rspec_helper?(statement, name)
|
|
92
|
+
return false unless statement.block_type?
|
|
93
|
+
|
|
94
|
+
call = statement.send_node
|
|
95
|
+
return false if call.receiver
|
|
96
|
+
return false unless RSPEC_HELPERS.include?(call.method_name)
|
|
97
|
+
|
|
98
|
+
argument = call.first_argument
|
|
99
|
+
argument&.sym_type? && argument.value == name
|
|
100
|
+
end
|
|
101
|
+
end
|
|
102
|
+
end
|
|
103
|
+
end
|
|
104
|
+
end
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module RuboCop
|
|
4
|
+
module Cop
|
|
5
|
+
module Capybara
|
|
6
|
+
# Checks for positive queries that succeed when there are no matches.
|
|
7
|
+
#
|
|
8
|
+
# @example
|
|
9
|
+
# # bad
|
|
10
|
+
# expect(page).to have_css('.item', minimum: 0)
|
|
11
|
+
# page.has_css?('.item', minimum: 0)
|
|
12
|
+
#
|
|
13
|
+
# # good
|
|
14
|
+
# expect(page).to have_css('.item')
|
|
15
|
+
# expect(page).to have_css('.item', minimum: 0, maximum: 2)
|
|
16
|
+
# all('.item', minimum: 0)
|
|
17
|
+
#
|
|
18
|
+
class AlwaysTrueCountQuery < RuboCop::Cop::Base
|
|
19
|
+
include CapybaraHelp
|
|
20
|
+
|
|
21
|
+
MSG = '`minimum: 0` makes this positive query succeed with no matches.'
|
|
22
|
+
OTHER_COUNT_OPTIONS = %i[count maximum between].freeze
|
|
23
|
+
RESTRICT_ON_SEND = QueryMethods.names(:selector).select do |name|
|
|
24
|
+
name = name.to_s
|
|
25
|
+
name.start_with?('assert_', 'has_', 'have_', 'must_have_') &&
|
|
26
|
+
!name.start_with?('assert_no_', 'has_no_', 'have_no_')
|
|
27
|
+
end.freeze
|
|
28
|
+
|
|
29
|
+
# @!method zero_minimum?(node)
|
|
30
|
+
def_node_matcher :zero_minimum?, '(pair (sym :minimum) (int 0))'
|
|
31
|
+
|
|
32
|
+
def on_send(node)
|
|
33
|
+
return unless capybara_receiver?(node.receiver)
|
|
34
|
+
return unless positive_usage?(node)
|
|
35
|
+
|
|
36
|
+
minimum = always_true_minimum(node.last_argument)
|
|
37
|
+
add_offense(minimum) if minimum
|
|
38
|
+
end
|
|
39
|
+
alias on_csend on_send
|
|
40
|
+
|
|
41
|
+
private
|
|
42
|
+
|
|
43
|
+
def positive_usage?(node)
|
|
44
|
+
return true unless node.method_name.to_s.start_with?('have_')
|
|
45
|
+
|
|
46
|
+
parent = node.parent
|
|
47
|
+
parent&.send_type? && parent.method?(:to) &&
|
|
48
|
+
parent.first_argument == node
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def always_true_minimum(options)
|
|
52
|
+
return unless known_options?(options)
|
|
53
|
+
|
|
54
|
+
pairs = options.pairs
|
|
55
|
+
return if pairs.any? { |pair| other_count_option?(pair) }
|
|
56
|
+
|
|
57
|
+
minimum = pairs.select { |pair| pair.key.value == :minimum }
|
|
58
|
+
minimum.first if minimum.one? && zero_minimum?(minimum.first)
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def known_options?(options)
|
|
62
|
+
return false unless options&.hash_type? && !options.braces?
|
|
63
|
+
|
|
64
|
+
options.children.all? do |child|
|
|
65
|
+
child.pair_type? && child.key.sym_type?
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
def other_count_option?(pair)
|
|
70
|
+
OTHER_COUNT_OPTIONS.include?(pair.key.value) && !pair.value.nil_type?
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
end
|
|
@@ -17,7 +17,7 @@ module RuboCop
|
|
|
17
17
|
# click_link('foo')
|
|
18
18
|
# click_button('foo')
|
|
19
19
|
#
|
|
20
|
-
class AmbiguousClick <
|
|
20
|
+
class AmbiguousClick < RuboCop::Cop::Base
|
|
21
21
|
MSG = 'Use `click_link` or `click_button` instead of `%<method>s`.'
|
|
22
22
|
RESTRICT_ON_SEND = %i[click_link_or_button click_on].freeze
|
|
23
23
|
|
|
@@ -12,7 +12,7 @@ module RuboCop
|
|
|
12
12
|
# # good
|
|
13
13
|
# page.find(:css, '#first').assert_matches_style(display: 'block')
|
|
14
14
|
#
|
|
15
|
-
class AssertStyle <
|
|
15
|
+
class AssertStyle < RuboCop::Cop::Base
|
|
16
16
|
extend AutoCorrector
|
|
17
17
|
|
|
18
18
|
MSG = 'Use `assert_matches_style` instead of `assert_style`.'
|