jimjamz
jimjamz

Reputation: 69

Which style of assertion with Capybara and SitePrism?

I am using the PageObject pattern, which abstracts HTML details away from the top-level of the test. I am doing this using the SitePrism gem.

In my example, I have a home page (HomePage.rb):

class HomePage < SitePrism::Page
  set_url ENV['BASE_URL']
  section :header, HeaderSection, "div[class='headerSection']"

which refers to a common page section, HeaderSection (HeaderSection.rb):

class HeaderSection < SitePrism::Section
  element :sign_in_button, "a[class='signIn']"

and a step definition for my tests (login.rb):

And(/^I am not logged in/) do
  @home_page = HomePage.new    # actually, this is specified in env.rb     
  expect(@home_page.header).to have_sign_in_button
end

Instead of exposing the web element to the step definition, I want to encapsulate this within a class method of HomePage. It seems that the best way to do that is to put the assertion into a class method within HomePage itself (HomePage.rb):

def amILoggedIn
  expect(header).to have_sign_in_button
end

The above assumes that I am also using include RSpec::Matchers.

My method would then be the only thing exposed to the step definition (login.rb):

And(/^I am not logged in/) do
  @home_page.amILoggedIn
end

As part of SitePrism, the sign_in_button element has its own built-in methods to check for its presence, which is:

header.has_sign_in_button?

Question

In terms of best practice, which is the most recommended way of writing this assertion within the amILoggedIn method (even though it appears they both use the same instruction),

expect(header).to have_sign_in_button

or

header.has_sign_in_button?

Upvotes: 1

Views: 385

Answers (2)

Luke Hill
Luke Hill

Reputation: 458

Old question but providing updated answer

Given SitePrism now uses implicit waiting by default as Thomas has said you've got two different method signatures, and two different outputs.

Also dependent on who you speak to, it is considered poor practice to include the matchers in a variety of places. Using Cucumber with SitePrism gives you a nice separation of concerns to perform the testing in the Cucumber World (step_definitions), and isolate all other modelling concerns to the support code.

Using SitePrism as described by the official docs will allow you (when using cucumber), to access all rspec methods in the cucumber world, and test easily and effectively.

Upvotes: 0

Thomas Walpole
Thomas Walpole

Reputation: 49910

expect(header).to have_sign_in_button and header.has_sign_in_button? do two different things. The first is an assertion (raises an exception if it fails) and the second just returns a boolean response. If what you want is an assertion you could assert on the boolean response assert header.has_sign_in_button? or expect(header.has_sign_in_button?).to be true but the failure message from have_sign_in_button is going to be a lot more descriptive.

Upvotes: 2

Related Questions