Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- require "#{File.dirname(__FILE__)}/../test_helper"
- require 'hpricot'
- PAGES = {
- :home => {:controller => "publications", :action => "index"},
- # :confirmation => {:controller => "subscription", :action => "confirmation"}
- :confirmation => {:controller => "application", :action => "index"}
- }
- module Actions
- def be_on(page)
- assert_equal PAGES[page][:controller], controller.controller_name, "Wrong controller"
- assert_equal PAGES[page][:action], controller.action_name, "Wrong action"
- "be on page '#{page}' (#{PAGES[page].inspect})"
- end
- def see(dom_id)
- assert_select "##{dom_id}", nil, "Could not see #{dom_id}"
- "see DOM id: '#{dom_id}'"
- end
- def receive_confirmation_email
- "receive a subscription confirmation email"
- end
- end
- class Visitor < ActionController::Integration::Session
- include Actions
- attr_accessor :current_url, :form_action, :form_method, :form_data, :messages, :name
- def initialize(name)
- super()
- @name = name
- @form_data = Hash.new { |h,k| h[k] = {} }
- @form_method = {}
- @form_action = {}
- @messages = []
- end
- def clicks_button(title = nil, options = {})
- options.reverse_merge!(:in => :default)
- node = if title
- (dom / "input").select { |el| el.attributes["type"] == "submit" && el.attributes["value"] == title}.first
- else
- # TODO target the specified form
- (dom / "input").select { |el| el.attributes["type"] == "submit" }.first
- end
- form_data[options[:in]][node.attributes["name"]] = node.attributes["value"] if name = node.attributes["name"]
- form = options[:in]
- figure_out_how_to_submit(form)
- puts "Submitting form with #{form_data[form].inspect}"
- self.send :"#{form_method[form]}_via_redirect", form_action[form], form_data[form]
- # reset the DOM
- @dom = nil
- end
- def fills_in(field, options = {})
- options.reverse_merge!(:in => :default)
- say("Visitor #{name} fills in form '#{options[:in]}' with #{options[:with].inspect} for #{field}")
- flunk "No value was provided" if options[:with].nil?
- if field.is_a?(String)
- # try to find the label within the page output to determine the name of the form field
- # TODO look in the appropriate form if provided
- # first, look for an input with field named "field"
- if (dom / "input").select { |el| el.attributes["name"] == field }.first
- # "field" is an actual field name, wow!
- else
- # let's assume that "field" is actually a label
- node = (dom / "label").select { |el| el.innerText == field }.first
- flunk "Could not find field '#{field}'" if node.nil?
- if child = (node / "input").first
- # nested inputs within labels
- field = child.attributes["name"]
- else
- # another input somewhere else, referenced by id
- field_id = node.attributes["for"]
- field = (dom / "##{field_id}").first
- flunk "Could not find input #{field_id}" if field.nil?
- field = field.attributes["name"]
- end
- end
- form_data[options[:in]].merge!(CGIMethods::parse_query_parameters("#{field}=#{options[:with]}"))
- else
- form_data[options[:in]][field] = options[:with]
- end
- figure_out_how_to_submit(options[:in])
- logger.debug "Current form state:"
- logger.debug form_data.inspect
- end
- def selects(string, options = {})
- options.reverse_merge!(:in => :default)
- say("Visitor #{name} selects '#{string}' from form '#{options[:from]}'")
- logger.debug("Selecting '#{string}'#{" from form #{options[:in]}" if options[:in]}")
- node = (dom / "option").select { |el| el.innerHTML == string }.first
- input = node.parent.attributes["name"]
- value = node.attributes["value"]
- figure_out_how_to_submit(options[:in], :start => node)
- form_data[options[:in]][input] = value
- logger.debug "Current form data"
- logger.debug(form_data.inspect)
- end
- # form is optional
- def submits_form(form = :default)
- figure_out_how_to_submit(form)
- say("Visitor #{name} submits form#{" (#{form})" if form}")
- logger.debug "Submitting form with #{form_data[form].inspect}"
- self.send :"#{form_method[form]}_via_redirect", form_action[form], form_data[form]
- logger.debug "Response body:"
- logger.debug response.body
- # reset the DOM
- @dom = nil
- # inspect the body of the current page to figure out what the form's action should be
- end
- def should(predicate = nil)
- say("Visitor #{name} should #{predicate}") if predicate
- self
- end
- def visits(page)
- say("Visitor #{name} visits url '#{page}'")
- get page
- @current_url = page
- logger.debug "Response from #{page}:"
- logger.debug response.body
- # reset the DOM
- @dom = nil
- end
- def steps(&block)
- instance_eval(&block)
- show_steps
- end
- def show_steps
- puts(messages * "\n")
- end
- protected
- def dom
- if @dom.nil?
- @dom = Hpricot(response.body)
- # TODO loop through form elements
- (@dom / "input").each do |node|
- unless node.attributes["value"].blank? || node.attributes["type"] == "submit"
- # TODO assign to an appropriately named form
- field = node.attributes["name"]
- value = node.attributes["value"]
- form_data[:default].reverse_merge!(CGIMethods::parse_query_parameters("#{field}=#{value}"))
- end
- end
- end
- # TODO do figure_out_how_to_submit processing here
- @dom
- end
- def figure_out_how_to_submit(form, options = {})
- return unless form_action[form].nil? || form_action[form].nil?
- if node = options[:start]
- while node.name != "form" do
- node = node.parent
- end
- else
- # TODO allow finding form by id (rather than defaulting to the first)
- node = (dom / "form").first
- end
- @form_action[form] = node.attributes["action"] || current_url
- @form_method[form] = node.attributes["method"] || "get"
- end
- def logger
- RAILS_DEFAULT_LOGGER
- end
- def say(msg)
- messages << msg
- end
- end
- class Visitor < ActionController::Integration::Session
- attr_accessor :response
- end
- require 'mocha'
- class VisitorTest < Test::Unit::TestCase
- def setup
- @visitor = Visitor.new("visitor")
- @visitor.response = ActionController::TestResponse.new
- end
- def test_clicks_button
- @visitor.response.body = '<form method="get" action="/subscriptions/new"><label for="subscription_email">Email</label><input id="subscription_email" name="subscription[email]" value="test@example.com" type="text" /><input type="submit" /></form>'
- @visitor.expects(:get_via_redirect).with("/subscriptions/new", "subscription" => {"email" => "test@example.com"})
- @visitor.clicks_button
- end
- def test_clicks_button_with_title
- @visitor.response.body = '<form method="post" action="/subscriptions/new"><label for="subscription_email">Email</label><input id="subscription_email" name="subscription[email]" value="test@example.com" type="text" /><input type="submit" name="cancel" value="Cancel" /><input type="submit" name="post" value="Post" /></form>'
- @visitor.expects(:post_via_redirect).with("/subscriptions/new", "subscription" => {"email" => "test@example.com"}, "post" => "Post")
- @visitor.clicks_button "Post"
- end
- def test_uses_default_values_from_form
- @visitor.response.body = '<form method="post" action="/subscriptions/new"><label for="subscription_email">Email</label><input id="subscription_email" name="subscription[email]" value="test@example.com" type="text" /></form>'
- @visitor.expects(:post_via_redirect).with("/subscriptions/new", "subscription" => {"email" => "test@example.com"})
- @visitor.submits_form
- end
- def test_overrides_default_values_in_form
- @visitor.response.body = '<form method="post" action="/subscriptions/new"><label for="subscription_email">Email</label><input id="subscription_email" name="subscription[email]" value="test@example.com" type="text" /></form>'
- @visitor.expects(:post_via_redirect).with("/subscriptions/new", "subscription" => {"email" => "foo@example.com"})
- @visitor.fills_in "subscription[email]", :with => "foo@example.com"
- @visitor.submits_form
- end
- def test_fills_in_with_string
- @visitor.response.body = '<form method="post" action="/subscriptions/new"><label for="subscription_email">Email</label><input id="subscription_email" name="subscription[email]" type="text" /></form>'
- email = "test@example.com"
- @visitor.fills_in "Email", :with => "test@example.com"
- hash = {"subscription" => {"email" => email}}
- assert_equal hash, @visitor.form_data[:default]
- end
- def test_fills_in_with_string_and_nested_label
- # THIS IS DIFFERENT
- @visitor.response.body = '<form method="post" action="/subscriptions/new"><label>Email<input id="subscription_email" name="subscription[email]" type="text" /></label></form>'
- email = "test@example.com"
- @visitor.fills_in "Email", :with => "test@example.com"
- hash = {"subscription" => {"email" => email}}
- assert_equal hash, @visitor.form_data[:default]
- end
- def test_fills_in_with_symbol
- @visitor.response.body = '<form method="post" action="/subscriptions/new"><label for="subscription_email">Email</label><input id="subscription_email" name="subscription[email]" type="text" /></form>'
- email = "test@example.com"
- @visitor.fills_in :email, :with => "test@example.com"
- hash = {:email => email}
- assert_equal hash, @visitor.form_data[:default]
- end
- def test_fills_in_with_symbol_and_form
- @visitor.response.body = '<form method="post" action="/subscriptions/new"><label for="subscription_email">Email</label><input id="subscription_email" name="subscription[email]" type="text" /></form>'
- email = "test@example.com"
- form = :subscription
- @visitor.fills_in :email, :with => "test@example.com", :in => form
- hash = {:email => email}
- assert_equal hash, @visitor.form_data[form]
- end
- def test_fills_in_should_determine_action_and_method
- @visitor.response.body = '<form method="post" action="/subscriptions/new"><label for="subscription_email">Email</label><input id="subscription_email" name="subscription[email]" type="text" /></form>'
- @visitor.fills_in :email, :with => "test@example.com"
- assert_equal "post", @visitor.form_method[:default]
- assert_equal "/subscriptions/new", @visitor.form_action[:default]
- end
- def test_fills_in_with_form_should_determine_action_and_method
- @visitor.response.body = '<form method="post" action="/subscriptions/new"><label for="subscription_email">Email</label><input id="subscription_email" name="subscription[email]" type="text" /></form>'
- form = :subscription
- @visitor.fills_in :email, :with => "test@example.com", :in => form
- assert_equal "post", @visitor.form_method[form]
- assert_equal "/subscriptions/new", @visitor.form_action[form]
- end
- def test_selects
- @visitor.response.body = '<form><select name="month"><option value="1">January</option></select></form>'
- @visitor.selects "January"
- hash = {"month" => "1"}
- assert_equal hash, @visitor.form_data[:default]
- end
- def test_selects_with_input
- @visitor.response.body = '<form><select name="month"><option value="1">January</option></select></form>'
- field_name = "month"
- @visitor.selects "January", :from => field_name
- hash = {field_name => "1"}
- assert_equal hash, @visitor.form_data[:default]
- end
- def test_selects_with_form
- @visitor.response.body = '<form><select name="month"><option value="1">January</option></select></form>'
- form = :date
- @visitor.selects "January", :in => form
- hash = {"month" => "1"}
- assert_equal hash, @visitor.form_data[form]
- end
- def test_selects_with_input_and_form
- @visitor.response.body = '<form><select name="month"><option value="1">January</option></select></form>'
- field_name = "month"
- form = :date
- @visitor.selects "January", :from => field_name, :in => form
- hash = {field_name => "1"}
- assert_equal hash, @visitor.form_data[form]
- end
- def test_selects_should_determine_action_and_method
- @visitor.response.body = '<form method="post" action="/subscriptions/new"><select name="month"><option value="1">January</option></select></form>'
- @visitor.selects "January"
- assert_equal "post", @visitor.form_method[:default]
- assert_equal "/subscriptions/new", @visitor.form_action[:default]
- end
- def test_selects_with_form_should_determine_action_and_method
- @visitor.response.body = '<form method="post" action="/subscriptions/new"><select name="month"><option value="1">January</option></select></form>'
- form = :date
- @visitor.selects "January", :in => form
- assert_equal "post", @visitor.form_method[form]
- assert_equal "/subscriptions/new", @visitor.form_action[form]
- end
- end
- class AcceptanceTest < ActionController::IntegrationTest
- class << self
- def acceptance_test(title, &block)
- define_method :"test_#{title}", &block
- end
- def xacceptance_test(title, &block); end
- end
- acceptance_test "Subscribes using Homepage Subscription Box" do
- # create a new visitor named "Seth"
- seth = Visitor.new("Seth")
- # basic page loading and html presence
- seth.visits "/"
- seth.should.see("subscription_box")
- # form manipulation
- seth.fills_in "Email", :with => "good@gmail.com", :in => :subscription
- seth.selects "New York"
- seth.submits_form
- seth.should.be_on(:confirmation)
- seth.should.receive_confirmation_email
- seth.show_steps
- end
- acceptance_test "Subscribes using Homepage Subscription Box (block form)" do
- # create a new visitor named "Seth"
- Visitor.new("Seth").steps do
- # basic page loading and html presence
- visits "/"
- should.see("subscription_box")
- # form manipulation
- fills_in :subscription, :with => {:email => "good@gmail.com"}
- selects "New York"
- submits_form
- should.be_on(:confirmation)
- should.receive_confirmation_email
- end
- end
- end
- __END__
- Subscription using Subscription Box from Homepage
- 1. Visitor visits the Homepage
- 2. Visitor should see the Subscription Box
- 3. Visitor types email address “good@gmail.com”
- 4. Visitor selects the publication “New York”
- 5. Visitor clicks Subscribe button
- 6. Visitor becomes a Subscriber
- 7. Subscriber should not be a confirmed subscriber
- 8. Subscriber should be subscribed to “New York”
- 9. Subscriber should receive a Subscription Confirmation email
- 10. Subscriber should see the Subscription Confirmation Page
Add Comment
Please, Sign In to add comment