Warning: Creating default object from empty value in /homepages/39/d161420129/htdocs/p373.net/wp/wp-content/themes/p373b/admin/functions.php on line 183
Capybara custom matcher alternative

Capybara custom matcher alternative

Sometimes when writing specs, you want to test a high level case multiple times across multiple spec tests.  This test may involve asserting multiple things on the page.

There is probably a proper way to do this, like see this gist , or there is my way, which seems way simpler.

So the objective is to be able to express tests as follows:

page.should be_super_awesome
page.should have_super_awesomeness

To do this, you need to extend Capybara::Session.  So what I do is in spec/support/super_awesome_helper:

module SuperAwesomeHelper
  module Session
    def is_super?
       ...
    end
    def has_awesomeness?
       ...
    end
  end
end

Notice the grammar.  To have a helper that is be_something, the method needs to be is_something?  And to have a helper that is have_something, the method should be has_something?.

Then to load this into Capybara::Session

Capybara::Session.send(:include, SuperAwesomeHelper::Session)

This is all neat and dandy, but what about descriptive error messages?  Good question, watson!  Here’s a sample implementation:

 

module SuperAwesomeHelper
  module Session
    def super_awesome?
      errors = false
      errors ||= "Wrong path" unless current_path == super_awesome_path
      errors ||= "Missing content: You are awesome" unless !errors and has_content?("You are awesome")
      errors ||= "Missing selector: #awesome-div" unless !errors and has_selector?("#awesome-div")
      People.all.each{|p| errors ||= "missing person #{p.name}" unless !errors and has_selector?(".person-#{p.name}")}
      !errors or raise Capybara::ExpectationNotMet, errors
      return true
    end
  end
end

The magic line here is:

!errors or raise Capybara::ExpectationNotMet, errors

which is what tells capybara to catch the exception and handle it properly.  You’ll notice my pattern here will stop checking for errors(essentially) once you hit the first error(if, at all),

which I think is ideal.  But you could implement it differently so it spits back all the error messages.

Thanks for listening. :)

    This entry was posted in Coding, Ruby/Rails, Technology, Uncategorized and tagged , . Bookmark the permalink. Both comments and trackbacks are currently closed.