= RSpec/Capybara

== RSpec/Capybara/CurrentPathExpectation

|===
| Enabled by default | Safe | Supports autocorrection | Version Added | Version Changed

| Enabled
| Yes
| Yes
| 1.18
| 2.0
|===

Checks that no expectations are set on Capybara's `current_path`.

The
https://www.rubydoc.info/github/teamcapybara/capybara/master/Capybara/RSpecMatchers#have_current_path-instance_method[`have_current_path` matcher]
should be used on `page` to set expectations on Capybara's
current path, since it uses
https://github.com/teamcapybara/capybara/blob/master/README.md#asynchronous-javascript-ajax-and-friends[Capybara's waiting functionality]
which ensures that preceding actions (like `click_link`) have
completed.

This cop does not support autocorrection in some cases.

=== Examples

[source,ruby]
----
# bad
expect(current_path).to eq('/callback')

# good
expect(page).to have_current_path('/callback')

# bad (does not support autocorrection)
expect(page.current_path).to match(variable)

# good
expect(page).to have_current_path('/callback')
----

=== References

* https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/Capybara/CurrentPathExpectation

== RSpec/Capybara/FeatureMethods

|===
| Enabled by default | Safe | Supports autocorrection | Version Added | Version Changed

| Enabled
| Yes
| Yes
| 1.17
| 2.0
|===

Checks for consistent method usage in feature specs.

By default, the cop disables all Capybara-specific methods that have
the same native RSpec method (e.g. are just aliases). Some teams
however may prefer using some of the Capybara methods (like `feature`)
to make it obvious that the test uses Capybara, while still disable
the rest of the methods, like `given` (alias for `let`), `background`
(alias for `before`), etc. You can configure which of the methods to
be enabled by using the EnabledMethods configuration option.

=== Examples

[source,ruby]
----
# bad
feature 'User logs in' do
  given(:user) { User.new }

  background do
    visit new_session_path
  end

  scenario 'with OAuth' do
    # ...
  end
end

# good
describe 'User logs in' do
  let(:user) { User.new }

  before do
    visit new_session_path
  end

  it 'with OAuth' do
    # ...
  end
end
----

=== Configurable attributes

|===
| Name | Default value | Configurable values

| EnabledMethods
| `[]`
| Array
|===

=== References

* https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/Capybara/FeatureMethods

== RSpec/Capybara/NegationMatcher

|===
| Enabled by default | Safe | Supports autocorrection | Version Added | Version Changed

| Pending
| Yes
| Yes
| 2.14
| -
|===

Enforces use of `have_no_*` or `not_to` for negated expectations.

=== Examples

==== EnforcedStyle: not_to (default)

[source,ruby]
----
# bad
expect(page).to have_no_selector
expect(page).to have_no_css('a')

# good
expect(page).not_to have_selector
expect(page).not_to have_css('a')
----

==== EnforcedStyle: have_no

[source,ruby]
----
# bad
expect(page).not_to have_selector
expect(page).not_to have_css('a')

# good
expect(page).to have_no_selector
expect(page).to have_no_css('a')
----

=== Configurable attributes

|===
| Name | Default value | Configurable values

| EnforcedStyle
| `not_to`
| `have_no`, `not_to`
|===

=== References

* https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/Capybara/NegationMatcher

== RSpec/Capybara/SpecificActions

|===
| Enabled by default | Safe | Supports autocorrection | Version Added | Version Changed

| Pending
| Yes
| No
| 2.14
| -
|===

Checks for there is a more specific actions offered by Capybara.

=== Examples

[source,ruby]
----
# bad
find('a').click
find('button.cls').click
find('a', exact_text: 'foo').click
find('div button').click

# good
click_link
click_button(class: 'cls')
click_link(exact_text: 'foo')
find('div').click_button
----

=== References

* https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/Capybara/SpecificActions

== RSpec/Capybara/SpecificFinders

|===
| Enabled by default | Safe | Supports autocorrection | Version Added | Version Changed

| Pending
| Yes
| Yes
| 2.13
| -
|===

Checks if there is a more specific finder offered by Capybara.

=== Examples

[source,ruby]
----
# bad
find('#some-id')
find('[visible][id=some-id]')

# good
find_by_id('some-id')
find_by_id('some-id', visible: true)
----

=== References

* https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/Capybara/SpecificFinders

== RSpec/Capybara/SpecificMatcher

|===
| Enabled by default | Safe | Supports autocorrection | Version Added | Version Changed

| Pending
| Yes
| No
| 2.12
| -
|===

Checks for there is a more specific matcher offered by Capybara.

=== Examples

[source,ruby]
----
# bad
expect(page).to have_selector('button')
expect(page).to have_no_selector('button.cls')
expect(page).to have_css('button')
expect(page).to have_no_css('a.cls', href: 'http://example.com')
expect(page).to have_css('table.cls')
expect(page).to have_css('select')
expect(page).to have_css('input', exact_text: 'foo')

# good
expect(page).to have_button
expect(page).to have_no_button(class: 'cls')
expect(page).to have_button
expect(page).to have_no_link('foo', class: 'cls', href: 'http://example.com')
expect(page).to have_table(class: 'cls')
expect(page).to have_select
expect(page).to have_field('foo')
----

=== References

* https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/Capybara/SpecificMatcher

== RSpec/Capybara/VisibilityMatcher

|===
| Enabled by default | Safe | Supports autocorrection | Version Added | Version Changed

| Enabled
| Yes
| No
| 1.39
| 2.0
|===

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`.
Read more in
https://www.rubydoc.info/gems/capybara/Capybara%2FNode%2FFinders:all[the documentation].

=== Examples

[source,ruby]
----
# 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)
----

=== References

* https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/Capybara/VisibilityMatcher
