Guest User

Untitled

a guest
Mar 7th, 2018
299
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 14.98 KB | None | 0 0
  1. require "#{File.dirname(__FILE__)}/../test_helper"
  2. require 'hpricot'
  3.  
  4. PAGES = {
  5. :home => {:controller => "publications", :action => "index"},
  6. # :confirmation => {:controller => "subscription", :action => "confirmation"}
  7. :confirmation => {:controller => "application", :action => "index"}
  8. }
  9.  
  10. module Actions
  11. def be_on(page)
  12. assert_equal PAGES[page][:controller], controller.controller_name, "Wrong controller"
  13. assert_equal PAGES[page][:action], controller.action_name, "Wrong action"
  14. "be on page '#{page}' (#{PAGES[page].inspect})"
  15. end
  16.  
  17. def see(dom_id)
  18. assert_select "##{dom_id}", nil, "Could not see #{dom_id}"
  19. "see DOM id: '#{dom_id}'"
  20. end
  21.  
  22. def receive_confirmation_email
  23. "receive a subscription confirmation email"
  24. end
  25. end
  26.  
  27. class Visitor < ActionController::Integration::Session
  28. include Actions
  29.  
  30. attr_accessor :current_url, :form_action, :form_method, :form_data, :messages, :name
  31.  
  32. def initialize(name)
  33. super()
  34. @name = name
  35. @form_data = Hash.new { |h,k| h[k] = {} }
  36. @form_method = {}
  37. @form_action = {}
  38. @messages = []
  39. end
  40.  
  41. def clicks_button(title = nil, options = {})
  42. options.reverse_merge!(:in => :default)
  43.  
  44. node = if title
  45. (dom / "input").select { |el| el.attributes["type"] == "submit" && el.attributes["value"] == title}.first
  46. else
  47. # TODO target the specified form
  48. (dom / "input").select { |el| el.attributes["type"] == "submit" }.first
  49. end
  50.  
  51. form_data[options[:in]][node.attributes["name"]] = node.attributes["value"] if name = node.attributes["name"]
  52.  
  53. form = options[:in]
  54. figure_out_how_to_submit(form)
  55.  
  56. puts "Submitting form with #{form_data[form].inspect}"
  57.  
  58. self.send :"#{form_method[form]}_via_redirect", form_action[form], form_data[form]
  59.  
  60. # reset the DOM
  61. @dom = nil
  62. end
  63.  
  64. def fills_in(field, options = {})
  65. options.reverse_merge!(:in => :default)
  66. say("Visitor #{name} fills in form '#{options[:in]}' with #{options[:with].inspect} for #{field}")
  67.  
  68. flunk "No value was provided" if options[:with].nil?
  69.  
  70. if field.is_a?(String)
  71. # try to find the label within the page output to determine the name of the form field
  72.  
  73. # TODO look in the appropriate form if provided
  74.  
  75. # first, look for an input with field named "field"
  76. if (dom / "input").select { |el| el.attributes["name"] == field }.first
  77. # "field" is an actual field name, wow!
  78. else
  79. # let's assume that "field" is actually a label
  80. node = (dom / "label").select { |el| el.innerText == field }.first
  81. flunk "Could not find field '#{field}'" if node.nil?
  82.  
  83. if child = (node / "input").first
  84. # nested inputs within labels
  85. field = child.attributes["name"]
  86. else
  87. # another input somewhere else, referenced by id
  88. field_id = node.attributes["for"]
  89.  
  90. field = (dom / "##{field_id}").first
  91. flunk "Could not find input #{field_id}" if field.nil?
  92. field = field.attributes["name"]
  93. end
  94. end
  95.  
  96. form_data[options[:in]].merge!(CGIMethods::parse_query_parameters("#{field}=#{options[:with]}"))
  97. else
  98. form_data[options[:in]][field] = options[:with]
  99. end
  100.  
  101. figure_out_how_to_submit(options[:in])
  102.  
  103. logger.debug "Current form state:"
  104. logger.debug form_data.inspect
  105. end
  106.  
  107. def selects(string, options = {})
  108. options.reverse_merge!(:in => :default)
  109. say("Visitor #{name} selects '#{string}' from form '#{options[:from]}'")
  110. logger.debug("Selecting '#{string}'#{" from form #{options[:in]}" if options[:in]}")
  111.  
  112. node = (dom / "option").select { |el| el.innerHTML == string }.first
  113. input = node.parent.attributes["name"]
  114. value = node.attributes["value"]
  115.  
  116. figure_out_how_to_submit(options[:in], :start => node)
  117.  
  118. form_data[options[:in]][input] = value
  119.  
  120. logger.debug "Current form data"
  121. logger.debug(form_data.inspect)
  122. end
  123.  
  124. # form is optional
  125. def submits_form(form = :default)
  126. figure_out_how_to_submit(form)
  127.  
  128. say("Visitor #{name} submits form#{" (#{form})" if form}")
  129.  
  130. logger.debug "Submitting form with #{form_data[form].inspect}"
  131.  
  132. self.send :"#{form_method[form]}_via_redirect", form_action[form], form_data[form]
  133.  
  134. logger.debug "Response body:"
  135. logger.debug response.body
  136.  
  137. # reset the DOM
  138. @dom = nil
  139.  
  140. # inspect the body of the current page to figure out what the form's action should be
  141. end
  142.  
  143. def should(predicate = nil)
  144. say("Visitor #{name} should #{predicate}") if predicate
  145. self
  146. end
  147.  
  148. def visits(page)
  149. say("Visitor #{name} visits url '#{page}'")
  150. get page
  151. @current_url = page
  152. logger.debug "Response from #{page}:"
  153. logger.debug response.body
  154.  
  155. # reset the DOM
  156. @dom = nil
  157. end
  158.  
  159. def steps(&block)
  160. instance_eval(&block)
  161. show_steps
  162. end
  163.  
  164. def show_steps
  165. puts(messages * "\n")
  166. end
  167.  
  168. protected
  169.  
  170. def dom
  171. if @dom.nil?
  172. @dom = Hpricot(response.body)
  173.  
  174. # TODO loop through form elements
  175.  
  176. (@dom / "input").each do |node|
  177. unless node.attributes["value"].blank? || node.attributes["type"] == "submit"
  178. # TODO assign to an appropriately named form
  179. field = node.attributes["name"]
  180. value = node.attributes["value"]
  181. form_data[:default].reverse_merge!(CGIMethods::parse_query_parameters("#{field}=#{value}"))
  182. end
  183. end
  184. end
  185.  
  186. # TODO do figure_out_how_to_submit processing here
  187.  
  188. @dom
  189. end
  190.  
  191. def figure_out_how_to_submit(form, options = {})
  192. return unless form_action[form].nil? || form_action[form].nil?
  193.  
  194. if node = options[:start]
  195. while node.name != "form" do
  196. node = node.parent
  197. end
  198. else
  199. # TODO allow finding form by id (rather than defaulting to the first)
  200. node = (dom / "form").first
  201. end
  202.  
  203. @form_action[form] = node.attributes["action"] || current_url
  204. @form_method[form] = node.attributes["method"] || "get"
  205. end
  206.  
  207. def logger
  208. RAILS_DEFAULT_LOGGER
  209. end
  210.  
  211. def say(msg)
  212. messages << msg
  213. end
  214. end
  215.  
  216. class Visitor < ActionController::Integration::Session
  217. attr_accessor :response
  218. end
  219.  
  220. require 'mocha'
  221.  
  222. class VisitorTest < Test::Unit::TestCase
  223. def setup
  224. @visitor = Visitor.new("visitor")
  225. @visitor.response = ActionController::TestResponse.new
  226. end
  227.  
  228. def test_clicks_button
  229. @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>'
  230.  
  231. @visitor.expects(:get_via_redirect).with("/subscriptions/new", "subscription" => {"email" => "test@example.com"})
  232.  
  233. @visitor.clicks_button
  234. end
  235.  
  236. def test_clicks_button_with_title
  237. @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>'
  238.  
  239. @visitor.expects(:post_via_redirect).with("/subscriptions/new", "subscription" => {"email" => "test@example.com"}, "post" => "Post")
  240. @visitor.clicks_button "Post"
  241. end
  242.  
  243. def test_uses_default_values_from_form
  244. @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>'
  245.  
  246. @visitor.expects(:post_via_redirect).with("/subscriptions/new", "subscription" => {"email" => "test@example.com"})
  247. @visitor.submits_form
  248. end
  249.  
  250. def test_overrides_default_values_in_form
  251. @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>'
  252.  
  253. @visitor.expects(:post_via_redirect).with("/subscriptions/new", "subscription" => {"email" => "foo@example.com"})
  254. @visitor.fills_in "subscription[email]", :with => "foo@example.com"
  255. @visitor.submits_form
  256. end
  257.  
  258. def test_fills_in_with_string
  259. @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>'
  260.  
  261. email = "test@example.com"
  262. @visitor.fills_in "Email", :with => "test@example.com"
  263.  
  264. hash = {"subscription" => {"email" => email}}
  265. assert_equal hash, @visitor.form_data[:default]
  266. end
  267.  
  268. def test_fills_in_with_string_and_nested_label
  269. # THIS IS DIFFERENT
  270. @visitor.response.body = '<form method="post" action="/subscriptions/new"><label>Email<input id="subscription_email" name="subscription[email]" type="text" /></label></form>'
  271.  
  272. email = "test@example.com"
  273. @visitor.fills_in "Email", :with => "test@example.com"
  274.  
  275. hash = {"subscription" => {"email" => email}}
  276. assert_equal hash, @visitor.form_data[:default]
  277.  
  278. end
  279.  
  280. def test_fills_in_with_symbol
  281. @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>'
  282.  
  283. email = "test@example.com"
  284. @visitor.fills_in :email, :with => "test@example.com"
  285.  
  286. hash = {:email => email}
  287. assert_equal hash, @visitor.form_data[:default]
  288. end
  289.  
  290. def test_fills_in_with_symbol_and_form
  291. @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>'
  292.  
  293. email = "test@example.com"
  294. form = :subscription
  295. @visitor.fills_in :email, :with => "test@example.com", :in => form
  296.  
  297. hash = {:email => email}
  298. assert_equal hash, @visitor.form_data[form]
  299. end
  300.  
  301. def test_fills_in_should_determine_action_and_method
  302. @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>'
  303.  
  304. @visitor.fills_in :email, :with => "test@example.com"
  305.  
  306. assert_equal "post", @visitor.form_method[:default]
  307. assert_equal "/subscriptions/new", @visitor.form_action[:default]
  308. end
  309.  
  310. def test_fills_in_with_form_should_determine_action_and_method
  311. @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>'
  312.  
  313. form = :subscription
  314. @visitor.fills_in :email, :with => "test@example.com", :in => form
  315.  
  316. assert_equal "post", @visitor.form_method[form]
  317. assert_equal "/subscriptions/new", @visitor.form_action[form]
  318. end
  319.  
  320. def test_selects
  321. @visitor.response.body = '<form><select name="month"><option value="1">January</option></select></form>'
  322.  
  323. @visitor.selects "January"
  324.  
  325. hash = {"month" => "1"}
  326. assert_equal hash, @visitor.form_data[:default]
  327. end
  328.  
  329. def test_selects_with_input
  330. @visitor.response.body = '<form><select name="month"><option value="1">January</option></select></form>'
  331.  
  332. field_name = "month"
  333. @visitor.selects "January", :from => field_name
  334.  
  335. hash = {field_name => "1"}
  336. assert_equal hash, @visitor.form_data[:default]
  337. end
  338.  
  339. def test_selects_with_form
  340. @visitor.response.body = '<form><select name="month"><option value="1">January</option></select></form>'
  341.  
  342. form = :date
  343. @visitor.selects "January", :in => form
  344.  
  345. hash = {"month" => "1"}
  346. assert_equal hash, @visitor.form_data[form]
  347. end
  348.  
  349. def test_selects_with_input_and_form
  350. @visitor.response.body = '<form><select name="month"><option value="1">January</option></select></form>'
  351.  
  352. field_name = "month"
  353. form = :date
  354. @visitor.selects "January", :from => field_name, :in => form
  355.  
  356. hash = {field_name => "1"}
  357. assert_equal hash, @visitor.form_data[form]
  358. end
  359.  
  360. def test_selects_should_determine_action_and_method
  361. @visitor.response.body = '<form method="post" action="/subscriptions/new"><select name="month"><option value="1">January</option></select></form>'
  362.  
  363. @visitor.selects "January"
  364.  
  365. assert_equal "post", @visitor.form_method[:default]
  366. assert_equal "/subscriptions/new", @visitor.form_action[:default]
  367. end
  368.  
  369. def test_selects_with_form_should_determine_action_and_method
  370. @visitor.response.body = '<form method="post" action="/subscriptions/new"><select name="month"><option value="1">January</option></select></form>'
  371.  
  372. form = :date
  373. @visitor.selects "January", :in => form
  374.  
  375. assert_equal "post", @visitor.form_method[form]
  376. assert_equal "/subscriptions/new", @visitor.form_action[form]
  377. end
  378. end
  379.  
  380. class AcceptanceTest < ActionController::IntegrationTest
  381. class << self
  382. def acceptance_test(title, &block)
  383. define_method :"test_#{title}", &block
  384. end
  385.  
  386. def xacceptance_test(title, &block); end
  387. end
  388.  
  389. acceptance_test "Subscribes using Homepage Subscription Box" do
  390. # create a new visitor named "Seth"
  391. seth = Visitor.new("Seth")
  392.  
  393. # basic page loading and html presence
  394. seth.visits "/"
  395. seth.should.see("subscription_box")
  396.  
  397. # form manipulation
  398. seth.fills_in "Email", :with => "good@gmail.com", :in => :subscription
  399. seth.selects "New York"
  400. seth.submits_form
  401.  
  402. seth.should.be_on(:confirmation)
  403.  
  404. seth.should.receive_confirmation_email
  405.  
  406. seth.show_steps
  407. end
  408.  
  409. acceptance_test "Subscribes using Homepage Subscription Box (block form)" do
  410. # create a new visitor named "Seth"
  411. Visitor.new("Seth").steps do
  412. # basic page loading and html presence
  413. visits "/"
  414. should.see("subscription_box")
  415.  
  416. # form manipulation
  417. fills_in :subscription, :with => {:email => "good@gmail.com"}
  418. selects "New York"
  419. submits_form
  420.  
  421. should.be_on(:confirmation)
  422.  
  423. should.receive_confirmation_email
  424. end
  425. end
  426. end
  427.  
  428. __END__
  429.  
  430. Subscription using Subscription Box from Homepage
  431.  
  432. 1. Visitor visits the Homepage
  433. 2. Visitor should see the Subscription Box
  434. 3. Visitor types email address “good@gmail.com”
  435. 4. Visitor selects the publication “New York”
  436. 5. Visitor clicks Subscribe button
  437. 6. Visitor becomes a Subscriber
  438. 7. Subscriber should not be a confirmed subscriber
  439. 8. Subscriber should be subscribed to “New York”
  440. 9. Subscriber should receive a Subscription Confirmation email
  441. 10. Subscriber should see the Subscription Confirmation Page
Add Comment
Please, Sign In to add comment