mirror of
https://github.com/teamcapybara/capybara.git
synced 2022-11-09 12:08:07 -05:00
Add parity between rspec support and minitest
This commit is contained in:
parent
2a0d50cb57
commit
b7e4f8dfc9
6 changed files with 465 additions and 6 deletions
14
README.md
14
README.md
|
@ -36,6 +36,7 @@ You can read more about the missing features [here](https://github.com/teamcapyb
|
|||
- [Using Capybara with Cucumber](#using-capybara-with-cucumber)
|
||||
- [Using Capybara with RSpec](#using-capybara-with-rspec)
|
||||
- [Using Capybara with Test::Unit](#using-capybara-with-testunit)
|
||||
- [Using Capybara with MiniTest](#using-capybara-with-minitest)
|
||||
- [Using Capybara with MiniTest::Spec](#using-capybara-with-minitestspec)
|
||||
- [Drivers](#drivers)
|
||||
- [Selecting the Driver](#selecting-the-driver)
|
||||
|
@ -291,14 +292,15 @@ class BlogTest < ActionDispatch::IntegrationTest
|
|||
end
|
||||
```
|
||||
|
||||
## <a name="using-capybara-with-minitest"></a>Using Capybara with MiniTest
|
||||
|
||||
Set up your base class as with Test::Unit and additionally require capybara/minitest and include ::Capybara::Minitest::Assertions into
|
||||
your base class
|
||||
|
||||
|
||||
## <a name="using-capybara-with-minitestspec"></a>Using Capybara with MiniTest::Spec
|
||||
|
||||
Set up your base class as with Test::Unit. (On Rails, the right base class
|
||||
could be something other than ActionDispatch::IntegrationTest.)
|
||||
|
||||
The capybara_minitest_spec gem ([GitHub](https://github.com/ordinaryzelig/capybara_minitest_spec),
|
||||
[rubygems.org](https://rubygems.org/gems/capybara_minitest_spec)) provides MiniTest::Spec
|
||||
expectations for Capybara. For example:
|
||||
Follow the above instructions for MiniTest and additionally require capybara/minitest/spec
|
||||
|
||||
```ruby
|
||||
page.must_have_content('Important!')
|
||||
|
|
|
@ -35,6 +35,7 @@ Gem::Specification.new do |s|
|
|||
s.add_development_dependency("yard", [">= 0.5.8"])
|
||||
s.add_development_dependency("fuubar", [">= 0.0.1"])
|
||||
s.add_development_dependency("cucumber", [">= 0.10.5"])
|
||||
s.add_development_dependency("minitest")
|
||||
s.add_development_dependency("rake")
|
||||
s.add_development_dependency("pry")
|
||||
s.add_development_dependency("erubi") # dependency specification needed by rbx
|
||||
|
|
144
lib/capybara/minitest.rb
Normal file
144
lib/capybara/minitest.rb
Normal file
|
@ -0,0 +1,144 @@
|
|||
# frozen_string_literal: true
|
||||
require 'minitest'
|
||||
require 'capybara/dsl'
|
||||
|
||||
module Capybara
|
||||
module Minitest
|
||||
module Assertions
|
||||
def assert_text(*args)
|
||||
self.assertions += 1
|
||||
subject, *args = determine_subject(args)
|
||||
subject.assert_text(*args)
|
||||
rescue Capybara::ExpectationNotMet => e
|
||||
raise ::Minitest::Assertion, e.message
|
||||
end
|
||||
alias_method :assert_content, :assert_text
|
||||
|
||||
def assert_no_text(*args)
|
||||
self.assertions += 1
|
||||
subject, *args = determine_subject(args)
|
||||
subject.assert_no_text(*args)
|
||||
rescue Capybara::ExpectationNotMet => e
|
||||
raise ::Minitest::Assertion, e.message
|
||||
end
|
||||
alias_method :refute_text, :assert_no_text
|
||||
alias_method :refute_content, :refute_text
|
||||
alias_method :assert_no_content, :refute_text
|
||||
|
||||
def assert_selector(*args, &optional_filter_block)
|
||||
self.assertions +=1
|
||||
subject, *args = determine_subject(args)
|
||||
subject.assert_selector(*args, &optional_filter_block)
|
||||
rescue Capybara::ExpectationNotMet => e
|
||||
raise ::Minitest::Assertion, e.message
|
||||
end
|
||||
|
||||
def assert_no_selector(*args, &optional_filter_block)
|
||||
self.assertions +=1
|
||||
subject, *args = determine_subject(args)
|
||||
subject.assert_no_selector(*args, &optional_filter_block)
|
||||
rescue Capybara::ExpectationNotMet => e
|
||||
raise ::Minitest::Assertion, e.message
|
||||
end
|
||||
alias_method :refute_selector, :assert_no_selector
|
||||
|
||||
def assert_matches_selector(*args)
|
||||
self.assertions += 1
|
||||
subject, *args = determine_subject(args)
|
||||
subject.assert_matches_selector(*args)
|
||||
rescue Capybara::ExpectationNotMet => e
|
||||
raise ::Minitest::Assertion, e.message
|
||||
end
|
||||
|
||||
def assert_not_matches_selector(*args)
|
||||
self.assertions += 1
|
||||
subject, *args = determine_subject(args)
|
||||
subject.assert_not_matches_selector(*args)
|
||||
rescue Capybara::ExpectationNotMet => e
|
||||
raise ::Minitest::Assertion, e.message
|
||||
end
|
||||
alias_method :refute_matches_selector, :assert_not_matches_selector
|
||||
|
||||
%w(title current_path).each do |selector_type|
|
||||
define_method "assert_#{selector_type}" do |*args|
|
||||
begin
|
||||
self.assertions += 1
|
||||
subject, *args = determine_subject(args)
|
||||
subject.public_send("assert_#{selector_type}",*args)
|
||||
rescue Capybara::ExpectationNotMet => e
|
||||
raise ::Minitest::Assertion, e.message
|
||||
end
|
||||
end
|
||||
|
||||
define_method "assert_no_#{selector_type}" do |*args|
|
||||
begin
|
||||
self.assertions += 1
|
||||
subject, *args = determine_subject(args)
|
||||
subject.public_send("assert_no_#{selector_type}",*args)
|
||||
rescue Capybara::ExpectationNotMet => e
|
||||
raise ::Minitest::Assertion, e.message
|
||||
end
|
||||
end
|
||||
alias_method "refute_#{selector_type}", "assert_no_#{selector_type}"
|
||||
end
|
||||
|
||||
%w(xpath css link button field select table).each do |selector_type|
|
||||
define_method "assert_#{selector_type}" do |*args, &optional_filter_block|
|
||||
subject, *args = determine_subject(args)
|
||||
locator, options = *args, {}
|
||||
locator, options = nil, locator if locator.is_a? Hash
|
||||
assert_selector(subject, selector_type.to_sym, locator, options, &optional_filter_block)
|
||||
end
|
||||
|
||||
define_method "assert_no_#{selector_type}" do |*args, &optional_filter_block|
|
||||
subject, *args = determine_subject(args)
|
||||
locator, options = *args, {}
|
||||
locator, options = nil, locator if locator.is_a? Hash
|
||||
assert_no_selector(subject, selector_type.to_sym, locator, options, &optional_filter_block)
|
||||
end
|
||||
alias_method "refute_#{selector_type}", "assert_no_#{selector_type}"
|
||||
end
|
||||
|
||||
%w(xpath css).each do |selector_type|
|
||||
define_method "assert_matches_#{selector_type}" do |*args, &optional_filter_block|
|
||||
subject, *args = determine_subject(args)
|
||||
assert_matches_selector(subject, selector_type.to_sym, *args, &optional_filter_block)
|
||||
end
|
||||
|
||||
define_method "assert_not_matches_#{selector_type}" do |*args, &optional_filter_block|
|
||||
subject, *args = determine_subject(args)
|
||||
assert_not_matches_selector(subject, selector_type.to_sym, *args, &optional_filter_block)
|
||||
end
|
||||
alias_method "refute_matches_#{selector_type}", "assert_not_matches_#{selector_type}"
|
||||
end
|
||||
|
||||
%w(checked unchecked).each do |field_type|
|
||||
define_method "assert_#{field_type}_field" do |*args, &optional_filter_block|
|
||||
subject, *args = determine_subject(args)
|
||||
locator, options = *args, {}
|
||||
locator, options = nil, locator if locator.is_a? Hash
|
||||
assert_selector(subject, :field, locator, options.merge(field_type.to_sym => true), &optional_filter_block)
|
||||
end
|
||||
|
||||
define_method "assert_no_#{field_type}_field" do |*args, &optional_filter_block|
|
||||
subject, *args = determine_subject(args)
|
||||
locator, options = *args, {}
|
||||
locator, options = nil, locator if locator.is_a? Hash
|
||||
assert_no_selector(subject, :field, locator, options.merge(field_type.to_sym => true), &optional_filter_block)
|
||||
end
|
||||
alias_method "refute_#{field_type}_field", "assert_no_#{field_type}_field"
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def determine_subject(args)
|
||||
case args.first
|
||||
when Capybara::Session, Capybara::Node::Base, Capybara::Node::Simple
|
||||
args
|
||||
else
|
||||
[page, *args]
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
69
lib/capybara/minitest/spec.rb
Normal file
69
lib/capybara/minitest/spec.rb
Normal file
|
@ -0,0 +1,69 @@
|
|||
require 'minitest/spec'
|
||||
|
||||
module Capybara
|
||||
module Minitest
|
||||
module Expectations
|
||||
%w(text content title current_path).each do |assertion|
|
||||
infect_an_assertion "assert_#{assertion}", "must_have_#{assertion}", :reverse
|
||||
infect_an_assertion "refute_#{assertion}", "wont_have_#{assertion}", :reverse
|
||||
end
|
||||
|
||||
# Unfortunately infect_an_assertion doesn't pass through the optional filter block so we can't use it for these
|
||||
%w(selector xpath css link button field select table checked_field unchecked_field).each do |assertion|
|
||||
self.class_eval <<-EOM
|
||||
def must_have_#{assertion} *args, &optional_filter_block
|
||||
::Minitest::Expectation.new(self, ::Minitest::Spec.current).must_have_#{assertion}(*args, &optional_filter_block)
|
||||
end
|
||||
|
||||
def wont_have_#{assertion} *args, &optional_filter_block
|
||||
::Minitest::Expectation.new(self, ::Minitest::Spec.current).wont_have_#{assertion}(*args, &optional_filter_block)
|
||||
end
|
||||
EOM
|
||||
|
||||
::Minitest::Expectation.class_eval <<-EOM, __FILE__, __LINE__ + 1
|
||||
def must_have_#{assertion} *args, &optional_filter_block
|
||||
ctx.assert_#{assertion}(target, *args, &optional_filter_block)
|
||||
end
|
||||
|
||||
def wont_have_#{assertion} *args, &optional_filter_block
|
||||
ctx.refute_#{assertion}(target, *args, &optional_filter_block)
|
||||
end
|
||||
EOM
|
||||
end
|
||||
|
||||
%w(selector xpath css).each do |assertion|
|
||||
self.class_eval <<-EOM
|
||||
def must_match_#{assertion} *args, &optional_filter_block
|
||||
::Minitest::Expectation.new(self, ::Minitest::Spec.current).must_match_#{assertion}(*args, &optional_filter_block)
|
||||
end
|
||||
|
||||
def wont_match_#{assertion} *args, &optional_filter_block
|
||||
::Minitest::Expectation.new(self, ::Minitest::Spec.current).wont_match_#{assertion}(*args, &optional_filter_block)
|
||||
end
|
||||
EOM
|
||||
|
||||
::Minitest::Expectation.class_eval <<-EOM, __FILE__, __LINE__ + 1
|
||||
def must_match_#{assertion} *args, &optional_filter_block
|
||||
ctx.assert_matches_#{assertion}(target, *args, &optional_filter_block)
|
||||
end
|
||||
|
||||
def wont_match_#{assertion} *args, &optional_filter_block
|
||||
ctx.refute_matches_#{assertion}(target, *args, &optional_filter_block)
|
||||
end
|
||||
EOM
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
class Capybara::Session
|
||||
include Capybara::Minitest::Expectations unless ENV["MT_NO_EXPECTATIONS"]
|
||||
end
|
||||
|
||||
class Capybara::Node::Base
|
||||
include Capybara::Minitest::Expectations unless ENV["MT_NO_EXPECTATIONS"]
|
||||
end
|
||||
|
||||
class Capybara::Node::Simple
|
||||
include Capybara::Minitest::Expectations unless ENV["MT_NO_EXPECTATIONS"]
|
||||
end
|
122
spec/minitest_spec.rb
Normal file
122
spec/minitest_spec.rb
Normal file
|
@ -0,0 +1,122 @@
|
|||
# frozen_string_literal: true
|
||||
require 'spec_helper'
|
||||
require 'capybara/minitest'
|
||||
|
||||
class MinitestTest < Minitest::Test
|
||||
include Capybara::DSL
|
||||
include Capybara::Minitest::Assertions
|
||||
|
||||
def setup
|
||||
visit('/form')
|
||||
end
|
||||
|
||||
def teardown
|
||||
Capybara.reset_sessions!
|
||||
end
|
||||
|
||||
def test_assert_text
|
||||
assert_text('Form')
|
||||
assert_no_text('Not on the page')
|
||||
refute_text('Also Not on the page')
|
||||
end
|
||||
|
||||
def test_assert_title
|
||||
visit('/with_title')
|
||||
assert_title('Test Title')
|
||||
assert_no_title('Not the title')
|
||||
refute_title('Not the title')
|
||||
end
|
||||
|
||||
def test_assert_current_path
|
||||
assert_current_path('/form')
|
||||
assert_no_current_path('/not_form')
|
||||
refute_current_path('/not_form')
|
||||
end
|
||||
|
||||
def test_assert_xpath
|
||||
assert_xpath('.//select[@id="form_title"]')
|
||||
assert_xpath('.//select', count: 1) { |el| el[:id] == "form_title" }
|
||||
assert_no_xpath('.//select[@id="not_form_title"]')
|
||||
assert_no_xpath('.//select') { |el| el[:id] == "not_form_title"}
|
||||
refute_xpath('.//select[@id="not_form_title"]')
|
||||
end
|
||||
|
||||
def test_assert_css
|
||||
assert_css('select#form_title')
|
||||
assert_no_css('select#not_form_title')
|
||||
end
|
||||
|
||||
def test_assert_link
|
||||
visit('/with_html')
|
||||
assert_link('A link')
|
||||
assert_link(count: 1){ |el| el.text == 'A link'}
|
||||
assert_no_link('Not on page')
|
||||
end
|
||||
|
||||
def test_assert_button
|
||||
assert_button('fresh_btn')
|
||||
assert_button(count: 1){ |el| el[:id] == 'fresh_btn' }
|
||||
assert_no_button('not_btn')
|
||||
end
|
||||
|
||||
def test_assert_field
|
||||
assert_field('customer_email')
|
||||
assert_no_field('not_on_the_form')
|
||||
end
|
||||
|
||||
def test_assert_select
|
||||
assert_select('form_title')
|
||||
assert_no_select('not_form_title')
|
||||
end
|
||||
|
||||
def test_assert_checked_field
|
||||
assert_checked_field('form_pets_dog')
|
||||
assert_no_checked_field('form_pets_cat')
|
||||
refute_checked_field('form_pets_snake')
|
||||
end
|
||||
|
||||
def test_assert_unchecked_field
|
||||
assert_unchecked_field('form_pets_cat')
|
||||
assert_no_unchecked_field('form_pets_dog')
|
||||
refute_unchecked_field('form_pets_snake')
|
||||
end
|
||||
|
||||
def test_assert_table
|
||||
visit('/tables')
|
||||
assert_table('agent_table')
|
||||
assert_no_table('not_on_form')
|
||||
refute_table('not_on_form')
|
||||
end
|
||||
|
||||
def test_assert_matches_selector
|
||||
assert_matches_selector(find(:field, 'customer_email'), :field, 'customer_email')
|
||||
assert_not_matches_selector(find(:select, 'form_title'), :field, 'customer_email')
|
||||
refute_matches_selector(find(:select, 'form_title'), :field, 'customer_email')
|
||||
end
|
||||
|
||||
def test_assert_matches_css
|
||||
assert_matches_css(find(:select, 'form_title'), 'select#form_title')
|
||||
refute_matches_css(find(:select, 'form_title'), 'select#form_other_title')
|
||||
end
|
||||
|
||||
def test_assert_matches_xpath
|
||||
assert_matches_xpath(find(:select, 'form_title'), './/select[@id="form_title"]')
|
||||
refute_matches_xpath(find(:select, 'form_title'), './/select[@id="form_other_title"]')
|
||||
end
|
||||
end
|
||||
|
||||
RSpec.describe 'capybara/minitest' do
|
||||
before do
|
||||
Capybara.current_driver = :rack_test
|
||||
Capybara.app = TestApp
|
||||
end
|
||||
|
||||
it "should support minitest" do
|
||||
output = StringIO.new
|
||||
reporter = Minitest::SummaryReporter.new(output)
|
||||
reporter.start
|
||||
MinitestTest.run reporter, {}
|
||||
reporter.report
|
||||
expect(output.string).to include("15 runs, 42 assertions, 0 failures, 0 errors, 0 skips")
|
||||
end
|
||||
end
|
121
spec/minitest_spec_spec.rb
Normal file
121
spec/minitest_spec_spec.rb
Normal file
|
@ -0,0 +1,121 @@
|
|||
# frozen_string_literal: true
|
||||
require 'spec_helper'
|
||||
require 'capybara/minitest'
|
||||
require 'capybara/minitest/spec'
|
||||
|
||||
class MinitestSpecTest < Minitest::Spec
|
||||
include ::Capybara::DSL
|
||||
include ::Capybara::Minitest::Assertions
|
||||
|
||||
before do
|
||||
visit('/form')
|
||||
end
|
||||
after do
|
||||
Capybara.reset_sessions!
|
||||
end
|
||||
|
||||
it "supports text expectations" do
|
||||
page.must_have_text('Form', minimum: 1)
|
||||
page.wont_have_text('Not a form')
|
||||
form = find(:css, 'form', text: 'Title')
|
||||
form.must_have_text('Customer Email')
|
||||
form.wont_have_text('Some other email')
|
||||
end
|
||||
|
||||
it "supports current_path expectations" do
|
||||
page.must_have_current_path('/form')
|
||||
page.wont_have_current_path('/form2')
|
||||
end
|
||||
|
||||
it "supports title expectations" do
|
||||
visit('/with_title')
|
||||
page.must_have_title('Test Title')
|
||||
page.wont_have_title('Not the title')
|
||||
end
|
||||
|
||||
it "supports xpath expectations" do
|
||||
page.must_have_xpath('.//input[@id="customer_email"]')
|
||||
page.wont_have_xpath('.//select[@id="not_form_title"]')
|
||||
page.wont_have_xpath('.//input[@id="customer_email"]') { |el| el[:id] == "not_customer_email" }
|
||||
el = find(:select, 'form_title')
|
||||
el.must_have_xpath('.//option[@class="title"]')
|
||||
el.must_have_xpath('.//option', count: 1) { |el| el[:class] != 'title' && !el.disabled?}
|
||||
el.wont_have_xpath('.//input[@id="customer_email"]')
|
||||
end
|
||||
|
||||
it "support css expectations" do
|
||||
page.must_have_css('input#customer_email')
|
||||
page.wont_have_css('select#not_form_title')
|
||||
el = find(:select, 'form_title')
|
||||
el.must_have_css('option.title')
|
||||
el.wont_have_css('input#customer_email')
|
||||
end
|
||||
|
||||
it "supports link expectations" do
|
||||
visit('/with_html')
|
||||
page.must_have_link('A link')
|
||||
page.wont_have_link('Not on page')
|
||||
end
|
||||
|
||||
it "supports button expectations" do
|
||||
page.must_have_button('fresh_btn')
|
||||
page.wont_have_button('not_btn')
|
||||
end
|
||||
|
||||
it "supports field expectations" do
|
||||
page.must_have_field('customer_email')
|
||||
page.wont_have_field('not_on_the_form')
|
||||
end
|
||||
|
||||
it "supports select expectations" do
|
||||
page.must_have_select('form_title')
|
||||
page.wont_have_select('not_form_title')
|
||||
end
|
||||
|
||||
it "supports checked_field expectations" do
|
||||
page.must_have_checked_field('form_pets_dog')
|
||||
page.wont_have_checked_field('form_pets_cat')
|
||||
end
|
||||
|
||||
it "supports unchecked_field expectations" do
|
||||
page.must_have_unchecked_field('form_pets_cat')
|
||||
page.wont_have_unchecked_field('form_pets_dog')
|
||||
end
|
||||
|
||||
it "supports table expectations" do
|
||||
visit('/tables')
|
||||
page.must_have_table('agent_table')
|
||||
page.wont_have_table('not_on_form')
|
||||
end
|
||||
|
||||
it "supports match_selector expectations" do
|
||||
find(:field, 'customer_email').must_match_selector(:field, 'customer_email')
|
||||
find(:select, 'form_title').wont_match_selector(:field, 'customer_email')
|
||||
end
|
||||
|
||||
it "supports match_css expectations" do
|
||||
find(:select, 'form_title').must_match_css('select#form_title')
|
||||
find(:select, 'form_title').wont_match_css('select#form_other_title')
|
||||
end
|
||||
|
||||
it "supports match_xpath expectations" do
|
||||
find(:select, 'form_title').must_match_xpath('.//select[@id="form_title"]')
|
||||
find(:select, 'form_title').wont_match_xpath('.//select[@id="not_on_page"]')
|
||||
end
|
||||
end
|
||||
|
||||
RSpec.describe 'capybara/minitest/spec' do
|
||||
before do
|
||||
Capybara.current_driver = :rack_test
|
||||
Capybara.app = TestApp
|
||||
end
|
||||
|
||||
it "should support minitest spec" do
|
||||
output = StringIO.new
|
||||
reporter = Minitest::SummaryReporter.new(output)
|
||||
reporter.start
|
||||
MinitestSpecTest.run reporter, {}
|
||||
reporter.report
|
||||
expect(output.string).to include("15 runs, 38 assertions, 0 failures, 0 errors, 0 skips")
|
||||
end
|
||||
end
|
Loading…
Reference in a new issue