Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add cop for Capybara expectations set on current_path #470

Merged
merged 1 commit into from
Sep 27, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
## Master (Unreleased)

* Fix false positive in `Capybara/FeatureMethods`. ([@Darhazer][])
* Add `RSpec/Capybara/CurrentPathExpectation` cop for feature specs, disallowing setting expectations on `current_path`. ([@timrogers][])

## 1.17.1 (2017-09-20)

Expand Down Expand Up @@ -250,3 +251,4 @@
[@pocke]: https://github.com/pocke
[@bmorrall]: https:/github.com/bmorrall
[@zverok]: https:/github.com/zverok
[@timrogers]: https://github.com/timrogers
5 changes: 5 additions & 0 deletions config/default.yml
Original file line number Diff line number Diff line change
Expand Up @@ -325,6 +325,11 @@ RSpec/VoidExpect:
Enabled: true
StyleGuide: http://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/VoidExpect

Capybara/CurrentPathExpectation:
Description: Checks that no expectations are set on Capybara's `current_path`.
Enabled: true
StyleGuide: http://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/Capybara/CurrentPathExpectation

Capybara/FeatureMethods:
Description: Checks for consistent method usage in feature specs.
Enabled: true
Expand Down
1 change: 1 addition & 0 deletions lib/rubocop-rspec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
require 'rubocop/cop/rspec/around_block'
require 'rubocop/cop/rspec/be_eql'
require 'rubocop/cop/rspec/before_after_all'
require 'rubocop/cop/rspec/capybara/current_path_expectation'
require 'rubocop/cop/rspec/capybara/feature_methods'
require 'rubocop/cop/rspec/describe_class'
require 'rubocop/cop/rspec/describe_method'
Expand Down
42 changes: 42 additions & 0 deletions lib/rubocop/cop/rspec/capybara/current_path_expectation.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
module RuboCop
module Cop
module RSpec
module Capybara
# Checks that no expectations are set on Capybara's `current_path`.
#
# The `have_current_path` matcher (http://www.rubydoc.info/github/
# teamcapybara/capybara/master/Capybara/RSpecMatchers#have_current_path-
# instance_method) should be used on `page` to set expectations on
# Capybara's current path, since it uses Capybara's waiting
# functionality (https://github.com/teamcapybara/capybara/blob/master/
# README.md#asynchronous-javascript-ajax-and-friends) which ensures that
# preceding actions (like `click_link`) have completed.
#
# @example
# # bad
# expect(current_path).to eq('/callback')
# expect(page.current_path).to match(/widgets/)
#
# # good
# expect(page).to have_current_path("/callback")
# expect(page).to have_current_path(/widgets/)
#
class CurrentPathExpectation < Cop
MSG = 'Do not set an RSpec expectation on `current_path` in ' \
'Capybara feature specs - instead, use the ' \
'`have_current_path` matcher on `page`'.freeze

def_node_matcher :expectation_set_on_current_path, <<-PATTERN
(send nil :expect (send {(send nil :page) nil} :current_path))
PATTERN

def on_send(node)
expectation_set_on_current_path(node) do
add_offense(node, :selector)
end
end
end
end
end
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
RSpec.describe RuboCop::Cop::RSpec::Capybara::CurrentPathExpectation do
subject(:cop) { described_class.new }

it 'flags violations for `expect(current_path)`' do
expect_offense(<<-RUBY)
expect(current_path).to eq("/callback")
^^^^^^ Do not set an RSpec expectation on `current_path` in Capybara feature specs - instead, use the `have_current_path` matcher on `page`
RUBY
end

it 'flags violations for `expect(page.current_path)`' do
expect_offense(<<-RUBY)
expect(page.current_path).to eq("/callback")
^^^^^^ Do not set an RSpec expectation on `current_path` in Capybara feature specs - instead, use the `have_current_path` matcher on `page`
RUBY
end

it "doesn't flag a violation for other expectations" do
expect_no_offenses(<<-RUBY)
expect(current_user).to eq(user)
RUBY
end

it "doesn't flag a violation for other references to `current_path`" do
expect_no_offenses(<<-RUBY)
current_path = WalkingRoute.last.path
RUBY
end
end