codenamev
1/29/2014 - 8:14 PM

Simple base class implementing "Page Objects" as referenced: http://gaslight.co/blog/6-ways-to-remove-pain-from-feature-testing-in-ruby-on-r

Simple base class implementing "Page Objects" as referenced: http://gaslight.co/blog/6-ways-to-remove-pain-from-feature-testing-in-ruby-on-rails

require 'spec_helper'

feature 'User views post' do
  let(:post)           { create :post, categories: [ruby_category, ninja_category] }
  let(:ruby_category)  { create :category, name: 'ruby' }
  let(:ninja_category) { create :category, name: 'ninja' }
  let(:post_page)      { PostPage.new }
  
  scenario "User sees categories within a post" do
    expect(post_page).to have_categories(ruby_category, ninja_category)
  end
end
class PostPage < PageObject
  def has_category?(category)
    has_css?('.category', category)
  end
  
  def has_categories?(*categories)
    categories.each do |category|
      has_category?(category)
    end
  end
end
class PageObject
  include Capybara::DSL
  include RSpec::Matchers
  include Rails.application.routes.url_helpers

  attr_accessor :path, :object

  def initialize(object = nil)
    raise "#{self.class} must be initialized with a model instance" unless !is_singular_object_page? or object
    @path   = "#{path_name}_path"
    @object = object
    visit_page
  end

  def visit_page(options = {})
    if @object.is_a? Hash
      visit send(@path, @object.merge(options))
    else
      visit send(@path, @object, options)
    end
  end

  private

  def path_name
    self.class.to_s.gsub(/Page\Z/, '').underscore
  end

  def is_singular_object_page?
    (!path_name.ends_with?('s') and !path_name.starts_with?('new_'))
  end
end