Class: RuboCop::Cop::Carwow::NoChangeMatcherWithBrowserAction

Inherits:
Base
  • Object
show all
Defined in:
lib/rubocop/cop/carwow/no_change_matcher_with_browser_action.rb

Overview

Detects the use of ‘expect { browser_action }.to change { db_access }` in feature/system specs. This pattern is racy because `change{}` takes DB snapshots before and after the block with no guarantee the browser has finished processing the action.

Examples:

Bad

expect { submit }.not_to(change { listing.reload.state })
expect { click_button('Save') }.to change { User.count }.by(1)

Good

submit
expect(page).to have_content('Success')
expect(listing.reload.state).to eq('complete')

click_button('Save')
expect(page).to have_current_path(success_path)
expect(User.count).to eq(2)

Constant Summary collapse

MSG =
'Avoid wrapping Capybara browser actions in `expect { }.to change { }`. ' \
'The DB snapshot races the async browser. Instead: call the action, ' \
'wait with `expect(page).to have_*`, then assert the DB state.'
CAPYBARA_ACTIONS =
%i[
  visit
  click_button click_link click_on click
  fill_in choose check uncheck select attach_file
  find find_field find_button find_by_id find_link
  within within_frame within_window
  execute_script evaluate_script
  scroll_to scroll_by
  hover drag_to drop
  dismiss_confirm accept_confirm dismiss_prompt accept_prompt
  submit
].to_set.freeze

Instance Method Summary collapse

Instance Method Details

#on_send(node) ⇒ Object



71
72
73
74
75
76
77
78
# File 'lib/rubocop/cop/carwow/no_change_matcher_with_browser_action.rb', line 71

def on_send(node)
  return unless expect_to_change?(node)

  expect_block = node.receiver
  return unless block_contains_capybara_action?(expect_block)

  add_offense(node)
end