Skip to content

Commit

Permalink
Add syntatic sugar to have_selector and have_text matchers
Browse files Browse the repository at this point in the history
  • Loading branch information
twalpole committed May 8, 2019
1 parent 40b51e2 commit 8ec78ab
Show file tree
Hide file tree
Showing 6 changed files with 57 additions and 0 deletions.
2 changes: 2 additions & 0 deletions History.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ Release date: unreleased

* Support for multiple expression types in Selector definitions
* Reduced wirecalls for common actions in Selenium driver
* Syntactic sugar `#once`, `#twice`, `#thrice`, `#excatly`, `#at_least`, `#at_most` to
`have_selector`, `have_css`, `have_xpath`, and `have_text` RSpec matchers

### Fixed

Expand Down
36 changes: 36 additions & 0 deletions lib/capybara/rspec/matchers/count_sugar.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# frozen_string_literal: true

module Capybara
module RSpecMatchers
module CountSugar
def once; exactly(1); end
def twice; exactly(2); end
def thrice; exactly(3); end

def exactly(number)
options[:count] = number
self
end

def at_most(number)
options[:maximum] = number
self
end

def at_least(number)
options[:minimum] = number
self
end

def times
self
end

private

def options
(@args.last.is_a?(Hash) ? @args : @args.push({})).last
end
end
end
end
3 changes: 3 additions & 0 deletions lib/capybara/rspec/matchers/have_selector.rb
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
# frozen_string_literal: true

require 'capybara/rspec/matchers/base'
require 'capybara/rspec/matchers/count_sugar'

module Capybara
module RSpecMatchers
module Matchers
class HaveSelector < WrappedElementMatcher
include CountSugar

def element_matches?(el)
el.assert_selector(*@args, &@filter_block)
end
Expand Down
3 changes: 3 additions & 0 deletions lib/capybara/rspec/matchers/have_text.rb
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
# frozen_string_literal: true

require 'capybara/rspec/matchers/base'
require 'capybara/rspec/matchers/count_sugar'

module Capybara
module RSpecMatchers
module Matchers
class HaveText < WrappedElementMatcher
include CountSugar

def element_matches?(el)
el.assert_text(*@args)
end
Expand Down
7 changes: 7 additions & 0 deletions lib/capybara/spec/session/has_css_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,9 @@
context 'with count' do
it 'should be true if the content occurs the given number of times' do
expect(@session).to have_css('p', count: 3)
expect(@session).to have_css('p').exactly(3).times
expect(@session).to have_css('p a#foo', count: 1)
expect(@session).to have_css('p a#foo').once
expect(@session).to have_css('p a.doesnotexist', count: 0)
expect(@session).to have_css('li', class: /guitar|drummer/, count: 4)
expect(@session).to have_css('li', id: /john|paul/, class: /guitar|drummer/, count: 2)
Expand All @@ -161,6 +163,7 @@

it 'should be false if the content occurs a different number of times than the given' do
expect(@session).not_to have_css('p', count: 6)
expect(@session).not_to have_css('p').exactly(5).times
expect(@session).not_to have_css('p a#foo', count: 2)
expect(@session).not_to have_css('p a.doesnotexist', count: 1)
end
Expand All @@ -175,13 +178,15 @@
it 'should be true when content occurs same or fewer times than given' do
expect(@session).to have_css('h2.head', maximum: 5) # edge case
expect(@session).to have_css('h2', maximum: 10)
expect(@session).to have_css('h2').at_most(10).times
expect(@session).to have_css('p a.doesnotexist', maximum: 1)
expect(@session).to have_css('p a.doesnotexist', maximum: 0)
end

it 'should be false when content occurs more times than given' do
expect(@session).not_to have_css('h2.head', maximum: 4) # edge case
expect(@session).not_to have_css('h2', maximum: 3)
expect(@session).not_to have_css('h2').at_most(3).times
expect(@session).not_to have_css('p', maximum: 1)
end

Expand All @@ -195,12 +200,14 @@
it 'should be true when content occurs same or more times than given' do
expect(@session).to have_css('h2.head', minimum: 5) # edge case
expect(@session).to have_css('h2', minimum: 3)
expect(@session).to have_css('h2').at_least(2).times
expect(@session).to have_css('p a.doesnotexist', minimum: 0)
end

it 'should be false when content occurs fewer times than given' do
expect(@session).not_to have_css('h2.head', minimum: 6) # edge case
expect(@session).not_to have_css('h2', minimum: 8)
expect(@session).not_to have_css('h2').at_least(8).times
expect(@session).not_to have_css('p', minimum: 10)
expect(@session).not_to have_css('p a.doesnotexist', minimum: 1)
end
Expand Down
6 changes: 6 additions & 0 deletions lib/capybara/spec/session/has_text_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -166,12 +166,14 @@
it 'should be true if the text occurs the given number of times' do
@session.visit('/with_count')
expect(@session).to have_text('count', count: 2)
expect(@session).to have_text('count').exactly(2).times
end

it 'should be false if the text occurs a different number of times than the given' do
@session.visit('/with_count')
expect(@session).not_to have_text('count', count: 0)
expect(@session).not_to have_text('count', count: 1)
expect(@session).not_to have_text('count').once
expect(@session).not_to have_text(/count/, count: 3)
end

Expand All @@ -186,12 +188,14 @@
it 'should be true when text occurs same or fewer times than given' do
@session.visit('/with_count')
expect(@session).to have_text('count', maximum: 2)
expect(@session).to have_text('count').at_most(2).times
expect(@session).to have_text(/count/, maximum: 3)
end

it 'should be false when text occurs more times than given' do
@session.visit('/with_count')
expect(@session).not_to have_text('count', maximum: 1)
expect(@session).not_to have_text('count').at_most(1).times
expect(@session).not_to have_text('count', maximum: 0)
end

Expand All @@ -206,12 +210,14 @@
it 'should be true when text occurs same or more times than given' do
@session.visit('/with_count')
expect(@session).to have_text('count', minimum: 2)
expect(@session).to have_text('count').at_least(2).times
expect(@session).to have_text(/count/, minimum: 0)
end

it 'should be false when text occurs fewer times than given' do
@session.visit('/with_count')
expect(@session).not_to have_text('count', minimum: 3)
expect(@session).not_to have_text('count').at_least(3).times
end

it 'should coerce minimum to an integer' do
Expand Down

0 comments on commit 8ec78ab

Please sign in to comment.