-
Notifications
You must be signed in to change notification settings - Fork 220
Use Page Object On Any HTML Fragment Or Page (with WatirNokogiri)
Page Object works very well for testing your web application using different browsers. But would't it be nice to recycle all the effort done while creating and maintaining the different Page Objects into other non-browser based test (for example View testing or RSpec request tests)?
This is perfectly possible by adding an additional driver platform to Page Object, called WatirNokogiri.
This is in fact nothing new as Capybara provides a similar solution:
- https://robots.thoughtbot.com/use-capybara-on-any-html-fragment-or-page
- http://www.rubydoc.info/gems/capybara/Capybara/Node/Simple
Add the following gems to your project
For example, in case of an RSpec request test the HTML will be in the body of the returned response
get "/comments/1"
expect(response).to render_template(:show)
@browser = WatirNokogiri::Document.new(response.body)
my_page = on_page(CommentShowPageObject)
expect(my_page.author).to eql 'Jos Smos'
This code can now be extracted to an 'on_page' routine similar to the one provided by PageFactory
def on_page(page_class, &block)
raise "Response is #{response.content_type}. No page object available." unless response.content_type.to_s =~ /html/
raise "Response body is empty!" if response.body.blank?
@browser = WatirNokogiri::Document.new(response.body)
@current_page = page_class.new(@browser)
block.call @current_page if block
@current_page
end
Unfortunately rspec-rails currently is tightly coupled to capybara, the following patch will allow you to use PageObject with WatirNokogiri as a replacement
# Taken from rspec-rails 3.2.1 /lib/rspec/rails/example/feature_example_group.rb
# Ensure page-object/selenium-webdriver visit method is not overruled
module RSpec
module Rails
module FeatureExampleGroup
remove_method :visit
end
end
end
# Taken from capybara 2.4.4 /capybara-2.4.4/lib/capybara/rspec/features.rb
# required by rspec-rails 3.2.1
if RSpec::Core::Version::STRING.to_f >= 3.0
RSpec.shared_context "Capybara Features", :capybara_feature => true do
instance_eval do
alias background before
alias given let
alias given! let!
end
end
RSpec.configure do |config|
config.alias_example_group_to :feature, :capybara_feature => true, :type => :feature
config.alias_example_to :scenario
config.alias_example_to :xscenario, :skip => "Temporarily disabled with xscenario"
# config.alias_example_to :fscenario, :focus => true
end
else
module Capybara
module Features
def self.included(base)
base.instance_eval do
alias :background :before
alias :scenario :it
alias :xscenario :xit
alias :given :let
alias :given! :let!
alias :feature :describe
end
end
end
end
def self.feature(*args, &block)
options = if args.last.is_a?(Hash) then args.pop else {} end
options[:capybara_feature] = true
options[:type] = :feature
options[:caller] ||= caller
args.push(options)
#call describe on RSpec in case user has expose_dsl_globally set to false
RSpec.describe(*args, &block)
end
RSpec.configuration.include Capybara::Features, :capybara_feature => true
end