On Github iantruslove / cucumber-and-page-object-presentation
Ian Truslove / ian.truslove@nsidc.org
26 Feb 2013
I didn't invent this.
I don't think Alister Scott did either, but it's from his blog article that I picked up the technique.
Use the Page Object pattern to better organize your code
A Page Object is an object that represents a web page
...or a service endpoint, or anything else
Feature: Smoke tests for metadata feeds harvested by NSIDC's GI-Cat Scenario Outline: Check Feed Endpoints Given that <Datacenter>'s feed URL is <URL> When I access the feed Then the response code will be a 200 And the number of results will be greater than zero Scenarios: Feed Endpoints | Datacenter | URL | | NSIDC | http://nsidc.org/oai/provider | | CISL | http://www.aoncadis.org/oai/ | | NMI | http://access.met.no/metamod/oai | | EOL | http://data.eol.ucar.edu/jedi/catalog |
require 'rubygems' require 'net/http' require 'open-uri' require 'nokogiri' Given /^the feed URL is (.*)$/ do |url| @url = url end When /^I access the feed$/ do @results = Nokogiri::XML(open("#{@url}")) end Then /^the response code will be a 200$/ do resp = Net::HTTP.get_response(URI.parse(@url)) resp.code.should == "200" end Then /^the number of results will be equal to (.*)$/ do |count| @results.xpath('//oai:record', { "oai" => "http://www.openarchives.org/OAI/2.0/"} ).count.should == count.to_i end
Given /^that (.*)'s feed URL is (.*)$/ do |datacenter, url| @feed = (datacenter == "EOL" ? Thredds.new(url) : Dif.new(url)) end When /^I access the feed$/ do @feed.access_feed end Then /^the response code will be a 200$/ do @feed.response_code.should == "200" end Then /^the number of results will be greater than zero$/ do @feed.num_records.should > 0 end
require 'net/http' require 'open-uri' require 'nokogiri' class Feed def initialize(url) @base_url = url.sub(/\/+$/, '') # strip trailing slashes end def access_feed @results = Nokogiri::XML(open("#{@base_url}")) end def response_code resp = Net::HTTP.get_response(URI.parse(@base_url)) resp.code end def get_records(element, namespace) @results.xpath("//#{element}", namespace) end end
Given /^I am on the search page$/ do url = ENV["URL"] || "http://integration.nsidc.org/acadis/search" @search_page = AcadisSearchPage.new(url, @browser) end When /^I search for "(.*?)"$/ do |search_term| @search_page.search_for(search_term) end When /^I click the next page button$/ do @search_page.click_next_page_button end Then /^there should be some search results$/ do @search_page.results_count.should >= 1 end Then /^all search results should have a button$/ do @search_page.count_data_buttons.should == @search_page.results_count end Then /^the page number should be "(.*?)"$/ do |page_number| @search_page.current_page_number.should == page_number end
(chopped for brevity)
require "watir-webdriver" class AcadisSearchPage def initialize(url, browser=nil) @url = url @browser = browser or Watir::Browser.new @browser.goto @url wait_until_loading_is_complete end def wait_until_loading_is_complete @browser.div(:id => 'loading-results').wait_while_present @browser.span(:class, 'results-count').wait_until_present sleep 0.5 end def search_for(term) @browser.text_field(:id, 'keyword').set term @browser.button(:id, 'search-now').click wait_until_loading_is_complete @results_history.push AcadisSearchResultsPage.new(@browser) end def click_next_page_button @browser.a(:class, 'button next').click wait_until_loading_is_complete @results_history.push AcadisSearchResultsPage.new(@browser) end # Accessors def total_results_count last_results_page.total_num_results end def current_page_number last_results_page.current_page_number end def first_result_date_modified last_results_page.first_date_modified end end
There's no magic
Basic OO, Interface Segregation Principle