winton-sum 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (280) hide show
  1. data/Capfile +3 -0
  2. data/MIT-LICENSE +18 -0
  3. data/README.markdown +55 -0
  4. data/Rakefile +45 -0
  5. data/config/database.example.yml +10 -0
  6. data/config/deploy.example.rb +36 -0
  7. data/config/externals.yml +18 -0
  8. data/config/mail.example.yml +32 -0
  9. data/config/schedule.rb +20 -0
  10. data/config.ru +3 -0
  11. data/db/migrate/001_users.rb +22 -0
  12. data/db/migrate/002_user_emails.rb +15 -0
  13. data/features/front_page.feature +14 -0
  14. data/features/read_email.feature +446 -0
  15. data/features/receive_email.feature +59 -0
  16. data/features/step_definitions/email.rb +52 -0
  17. data/features/step_definitions/given.rb +60 -0
  18. data/features/step_definitions/then.rb +32 -0
  19. data/features/step_definitions/when.rb +41 -0
  20. data/features/support/env.rb +27 -0
  21. data/features/support/helpers.rb +44 -0
  22. data/features/support/rspec.rb +11 -0
  23. data/features/support/webrat.rb +3 -0
  24. data/features/update_user.feature +76 -0
  25. data/gemspec.rb +45 -0
  26. data/lib/sum/boot.rb +29 -0
  27. data/lib/sum/controller/cron.rb +12 -0
  28. data/lib/sum/controller/front.rb +6 -0
  29. data/lib/sum/controller/new.rb +15 -0
  30. data/lib/sum/helper/application.rb +8 -0
  31. data/lib/sum/helper/cron.rb +12 -0
  32. data/lib/sum/helper/new.rb +26 -0
  33. data/lib/sum/model/incoming_mail.rb +89 -0
  34. data/lib/sum/model/user.rb +286 -0
  35. data/lib/sum/model/user_email.rb +31 -0
  36. data/lib/sum/view/email.haml +70 -0
  37. data/lib/sum/view/field.haml +10 -0
  38. data/lib/sum/view/form.haml +12 -0
  39. data/lib/sum/view/front.haml +25 -0
  40. data/lib/sum/view/layout.haml +26 -0
  41. data/lib/sum/view/new.haml +15 -0
  42. data/lib/sum.rb +30 -0
  43. data/public/image/1.png +0 -0
  44. data/public/image/2.png +0 -0
  45. data/public/image/3.png +0 -0
  46. data/public/image/bg.png +0 -0
  47. data/public/image/bot.png +0 -0
  48. data/public/image/facebox/b.png +0 -0
  49. data/public/image/facebox/bl.png +0 -0
  50. data/public/image/facebox/br.png +0 -0
  51. data/public/image/facebox/closelabel.gif +0 -0
  52. data/public/image/facebox/loading.gif +0 -0
  53. data/public/image/facebox/tl.png +0 -0
  54. data/public/image/facebox/tr.png +0 -0
  55. data/public/image/favicon.png +0 -0
  56. data/public/image/field_off.png +0 -0
  57. data/public/image/field_on.png +0 -0
  58. data/public/image/ribbon.png +0 -0
  59. data/public/image/screenshot_receive.png +0 -0
  60. data/public/image/screenshot_send.png +0 -0
  61. data/public/image/submit.png +0 -0
  62. data/public/image/top.png +0 -0
  63. data/public/javascript/facebox.js +319 -0
  64. data/public/javascript/jquery-1.3.2.js +19 -0
  65. data/public/javascript/sum.js +9 -0
  66. data/public/style/facebox.css +95 -0
  67. data/public/style/ie.css +35 -0
  68. data/public/style/print.css +30 -0
  69. data/public/style/screen.css +256 -0
  70. data/public/style/sum.css +22 -0
  71. data/public/style/sum.less +135 -0
  72. data/spec/spec.opts +1 -0
  73. data/spec/spec_helper.rb +58 -0
  74. data/spec/sum/model/incoming_mail_spec.rb +106 -0
  75. data/spec/sum/model/user_spec.rb +171 -0
  76. data/sum.gemspec +69 -0
  77. data/vendor/webrat/History.txt +358 -0
  78. data/vendor/webrat/MIT-LICENSE.txt +19 -0
  79. data/vendor/webrat/README.rdoc +85 -0
  80. data/vendor/webrat/Rakefile +200 -0
  81. data/vendor/webrat/install.rb +1 -0
  82. data/vendor/webrat/lib/webrat/core/configuration.rb +102 -0
  83. data/vendor/webrat/lib/webrat/core/elements/area.rb +31 -0
  84. data/vendor/webrat/lib/webrat/core/elements/element.rb +33 -0
  85. data/vendor/webrat/lib/webrat/core/elements/field.rb +409 -0
  86. data/vendor/webrat/lib/webrat/core/elements/form.rb +103 -0
  87. data/vendor/webrat/lib/webrat/core/elements/label.rb +31 -0
  88. data/vendor/webrat/lib/webrat/core/elements/link.rb +93 -0
  89. data/vendor/webrat/lib/webrat/core/elements/select_option.rb +35 -0
  90. data/vendor/webrat/lib/webrat/core/locators/area_locator.rb +38 -0
  91. data/vendor/webrat/lib/webrat/core/locators/button_locator.rb +54 -0
  92. data/vendor/webrat/lib/webrat/core/locators/field_by_id_locator.rb +37 -0
  93. data/vendor/webrat/lib/webrat/core/locators/field_labeled_locator.rb +56 -0
  94. data/vendor/webrat/lib/webrat/core/locators/field_locator.rb +25 -0
  95. data/vendor/webrat/lib/webrat/core/locators/field_named_locator.rb +41 -0
  96. data/vendor/webrat/lib/webrat/core/locators/form_locator.rb +19 -0
  97. data/vendor/webrat/lib/webrat/core/locators/label_locator.rb +34 -0
  98. data/vendor/webrat/lib/webrat/core/locators/link_locator.rb +74 -0
  99. data/vendor/webrat/lib/webrat/core/locators/locator.rb +20 -0
  100. data/vendor/webrat/lib/webrat/core/locators/select_option_locator.rb +59 -0
  101. data/vendor/webrat/lib/webrat/core/locators.rb +20 -0
  102. data/vendor/webrat/lib/webrat/core/logging.rb +24 -0
  103. data/vendor/webrat/lib/webrat/core/matchers/have_content.rb +73 -0
  104. data/vendor/webrat/lib/webrat/core/matchers/have_selector.rb +74 -0
  105. data/vendor/webrat/lib/webrat/core/matchers/have_tag.rb +21 -0
  106. data/vendor/webrat/lib/webrat/core/matchers/have_xpath.rb +147 -0
  107. data/vendor/webrat/lib/webrat/core/matchers.rb +4 -0
  108. data/vendor/webrat/lib/webrat/core/methods.rb +63 -0
  109. data/vendor/webrat/lib/webrat/core/mime.rb +29 -0
  110. data/vendor/webrat/lib/webrat/core/save_and_open_page.rb +48 -0
  111. data/vendor/webrat/lib/webrat/core/scope.rb +350 -0
  112. data/vendor/webrat/lib/webrat/core/session.rb +299 -0
  113. data/vendor/webrat/lib/webrat/core/xml/hpricot.rb +19 -0
  114. data/vendor/webrat/lib/webrat/core/xml/nokogiri.rb +76 -0
  115. data/vendor/webrat/lib/webrat/core/xml/rexml.rb +24 -0
  116. data/vendor/webrat/lib/webrat/core/xml.rb +115 -0
  117. data/vendor/webrat/lib/webrat/core.rb +14 -0
  118. data/vendor/webrat/lib/webrat/core_extensions/blank.rb +58 -0
  119. data/vendor/webrat/lib/webrat/core_extensions/deprecate.rb +8 -0
  120. data/vendor/webrat/lib/webrat/core_extensions/detect_mapped.rb +12 -0
  121. data/vendor/webrat/lib/webrat/core_extensions/meta_class.rb +6 -0
  122. data/vendor/webrat/lib/webrat/core_extensions/nil_to_param.rb +5 -0
  123. data/vendor/webrat/lib/webrat/core_extensions/tcp_socket.rb +27 -0
  124. data/vendor/webrat/lib/webrat/mechanize.rb +74 -0
  125. data/vendor/webrat/lib/webrat/merb.rb +9 -0
  126. data/vendor/webrat/lib/webrat/merb_multipart_support.rb +27 -0
  127. data/vendor/webrat/lib/webrat/merb_session.rb +82 -0
  128. data/vendor/webrat/lib/webrat/rack.rb +25 -0
  129. data/vendor/webrat/lib/webrat/rails.rb +106 -0
  130. data/vendor/webrat/lib/webrat/rspec-rails.rb +10 -0
  131. data/vendor/webrat/lib/webrat/selenium/application_server_factory.rb +40 -0
  132. data/vendor/webrat/lib/webrat/selenium/application_servers/base.rb +46 -0
  133. data/vendor/webrat/lib/webrat/selenium/application_servers/external.rb +26 -0
  134. data/vendor/webrat/lib/webrat/selenium/application_servers/merb.rb +50 -0
  135. data/vendor/webrat/lib/webrat/selenium/application_servers/rails.rb +44 -0
  136. data/vendor/webrat/lib/webrat/selenium/application_servers/sinatra.rb +37 -0
  137. data/vendor/webrat/lib/webrat/selenium/application_servers.rb +5 -0
  138. data/vendor/webrat/lib/webrat/selenium/location_strategy_javascript/button.js +19 -0
  139. data/vendor/webrat/lib/webrat/selenium/location_strategy_javascript/label.js +16 -0
  140. data/vendor/webrat/lib/webrat/selenium/location_strategy_javascript/webrat.js +5 -0
  141. data/vendor/webrat/lib/webrat/selenium/location_strategy_javascript/webratlink.js +12 -0
  142. data/vendor/webrat/lib/webrat/selenium/location_strategy_javascript/webratlinkwithin.js +15 -0
  143. data/vendor/webrat/lib/webrat/selenium/location_strategy_javascript/webratselectwithoption.js +5 -0
  144. data/vendor/webrat/lib/webrat/selenium/matchers/have_content.rb +66 -0
  145. data/vendor/webrat/lib/webrat/selenium/matchers/have_selector.rb +49 -0
  146. data/vendor/webrat/lib/webrat/selenium/matchers/have_tag.rb +72 -0
  147. data/vendor/webrat/lib/webrat/selenium/matchers/have_xpath.rb +45 -0
  148. data/vendor/webrat/lib/webrat/selenium/matchers.rb +4 -0
  149. data/vendor/webrat/lib/webrat/selenium/selenium_extensions.js +6 -0
  150. data/vendor/webrat/lib/webrat/selenium/selenium_rc_server.rb +84 -0
  151. data/vendor/webrat/lib/webrat/selenium/selenium_session.rb +248 -0
  152. data/vendor/webrat/lib/webrat/selenium/silence_stream.rb +18 -0
  153. data/vendor/webrat/lib/webrat/selenium.rb +81 -0
  154. data/vendor/webrat/lib/webrat/sinatra.rb +11 -0
  155. data/vendor/webrat/lib/webrat.rb +31 -0
  156. data/vendor/webrat/spec/fakes/test_session.rb +34 -0
  157. data/vendor/webrat/spec/integration/merb/Rakefile +35 -0
  158. data/vendor/webrat/spec/integration/merb/app/controllers/application.rb +2 -0
  159. data/vendor/webrat/spec/integration/merb/app/controllers/exceptions.rb +13 -0
  160. data/vendor/webrat/spec/integration/merb/app/controllers/testing.rb +27 -0
  161. data/vendor/webrat/spec/integration/merb/app/views/exceptions/not_acceptable.html.erb +63 -0
  162. data/vendor/webrat/spec/integration/merb/app/views/exceptions/not_found.html.erb +47 -0
  163. data/vendor/webrat/spec/integration/merb/app/views/layout/application.html.erb +12 -0
  164. data/vendor/webrat/spec/integration/merb/app/views/testing/show_form.html.erb +27 -0
  165. data/vendor/webrat/spec/integration/merb/app/views/testing/upload.html.erb +9 -0
  166. data/vendor/webrat/spec/integration/merb/config/environments/development.rb +15 -0
  167. data/vendor/webrat/spec/integration/merb/config/environments/rake.rb +11 -0
  168. data/vendor/webrat/spec/integration/merb/config/environments/test.rb +14 -0
  169. data/vendor/webrat/spec/integration/merb/config/init.rb +25 -0
  170. data/vendor/webrat/spec/integration/merb/config/rack.rb +11 -0
  171. data/vendor/webrat/spec/integration/merb/config/router.rb +34 -0
  172. data/vendor/webrat/spec/integration/merb/spec/spec.opts +1 -0
  173. data/vendor/webrat/spec/integration/merb/spec/spec_helper.rb +24 -0
  174. data/vendor/webrat/spec/integration/merb/spec/webrat_spec.rb +39 -0
  175. data/vendor/webrat/spec/integration/merb/tasks/merb.thor/app_script.rb +31 -0
  176. data/vendor/webrat/spec/integration/merb/tasks/merb.thor/common.rb +64 -0
  177. data/vendor/webrat/spec/integration/merb/tasks/merb.thor/gem_ext.rb +124 -0
  178. data/vendor/webrat/spec/integration/merb/tasks/merb.thor/main.thor +150 -0
  179. data/vendor/webrat/spec/integration/merb/tasks/merb.thor/ops.rb +93 -0
  180. data/vendor/webrat/spec/integration/merb/tasks/merb.thor/utils.rb +40 -0
  181. data/vendor/webrat/spec/integration/rack/Rakefile +5 -0
  182. data/vendor/webrat/spec/integration/rack/app.rb +73 -0
  183. data/vendor/webrat/spec/integration/rack/test/helper.rb +20 -0
  184. data/vendor/webrat/spec/integration/rack/test/webrat_rack_test.rb +62 -0
  185. data/vendor/webrat/spec/integration/rails/Rakefile +30 -0
  186. data/vendor/webrat/spec/integration/rails/app/controllers/application.rb +15 -0
  187. data/vendor/webrat/spec/integration/rails/app/controllers/buttons_controller.rb +7 -0
  188. data/vendor/webrat/spec/integration/rails/app/controllers/fields_controller.rb +4 -0
  189. data/vendor/webrat/spec/integration/rails/app/controllers/links_controller.rb +7 -0
  190. data/vendor/webrat/spec/integration/rails/app/controllers/webrat_controller.rb +43 -0
  191. data/vendor/webrat/spec/integration/rails/app/helpers/buttons_helper.rb +2 -0
  192. data/vendor/webrat/spec/integration/rails/app/helpers/fields_helper.rb +2 -0
  193. data/vendor/webrat/spec/integration/rails/app/helpers/links_helper.rb +2 -0
  194. data/vendor/webrat/spec/integration/rails/app/views/buttons/show.html.erb +11 -0
  195. data/vendor/webrat/spec/integration/rails/app/views/fields/show.html.erb +9 -0
  196. data/vendor/webrat/spec/integration/rails/app/views/links/show.html.erb +5 -0
  197. data/vendor/webrat/spec/integration/rails/app/views/webrat/before_redirect_form.html.erb +4 -0
  198. data/vendor/webrat/spec/integration/rails/app/views/webrat/buttons.html.erb +11 -0
  199. data/vendor/webrat/spec/integration/rails/app/views/webrat/form.html.erb +28 -0
  200. data/vendor/webrat/spec/integration/rails/config/boot.rb +109 -0
  201. data/vendor/webrat/spec/integration/rails/config/environment.rb +12 -0
  202. data/vendor/webrat/spec/integration/rails/config/environments/development.rb +17 -0
  203. data/vendor/webrat/spec/integration/rails/config/environments/selenium.rb +22 -0
  204. data/vendor/webrat/spec/integration/rails/config/environments/test.rb +22 -0
  205. data/vendor/webrat/spec/integration/rails/config/initializers/inflections.rb +10 -0
  206. data/vendor/webrat/spec/integration/rails/config/initializers/mime_types.rb +5 -0
  207. data/vendor/webrat/spec/integration/rails/config/initializers/new_rails_defaults.rb +17 -0
  208. data/vendor/webrat/spec/integration/rails/config/locales/en.yml +5 -0
  209. data/vendor/webrat/spec/integration/rails/config/routes.rb +18 -0
  210. data/vendor/webrat/spec/integration/rails/public/404.html +30 -0
  211. data/vendor/webrat/spec/integration/rails/public/422.html +30 -0
  212. data/vendor/webrat/spec/integration/rails/public/500.html +33 -0
  213. data/vendor/webrat/spec/integration/rails/script/about +4 -0
  214. data/vendor/webrat/spec/integration/rails/script/console +3 -0
  215. data/vendor/webrat/spec/integration/rails/script/dbconsole +3 -0
  216. data/vendor/webrat/spec/integration/rails/script/destroy +3 -0
  217. data/vendor/webrat/spec/integration/rails/script/generate +3 -0
  218. data/vendor/webrat/spec/integration/rails/script/performance/benchmarker +3 -0
  219. data/vendor/webrat/spec/integration/rails/script/performance/profiler +3 -0
  220. data/vendor/webrat/spec/integration/rails/script/performance/request +3 -0
  221. data/vendor/webrat/spec/integration/rails/script/plugin +3 -0
  222. data/vendor/webrat/spec/integration/rails/script/process/inspector +3 -0
  223. data/vendor/webrat/spec/integration/rails/script/process/reaper +3 -0
  224. data/vendor/webrat/spec/integration/rails/script/process/spawner +3 -0
  225. data/vendor/webrat/spec/integration/rails/script/runner +3 -0
  226. data/vendor/webrat/spec/integration/rails/script/server +3 -0
  227. data/vendor/webrat/spec/integration/rails/test/integration/button_click_test.rb +80 -0
  228. data/vendor/webrat/spec/integration/rails/test/integration/fill_in_test.rb +24 -0
  229. data/vendor/webrat/spec/integration/rails/test/integration/link_click_test.rb +27 -0
  230. data/vendor/webrat/spec/integration/rails/test/integration/webrat_test.rb +97 -0
  231. data/vendor/webrat/spec/integration/rails/test/test_helper.rb +25 -0
  232. data/vendor/webrat/spec/integration/sinatra/Rakefile +5 -0
  233. data/vendor/webrat/spec/integration/sinatra/classic_app.rb +64 -0
  234. data/vendor/webrat/spec/integration/sinatra/modular_app.rb +16 -0
  235. data/vendor/webrat/spec/integration/sinatra/test/classic_app_test.rb +37 -0
  236. data/vendor/webrat/spec/integration/sinatra/test/modular_app_test.rb +18 -0
  237. data/vendor/webrat/spec/integration/sinatra/test/test_helper.rb +16 -0
  238. data/vendor/webrat/spec/private/core/configuration_spec.rb +116 -0
  239. data/vendor/webrat/spec/private/core/field_spec.rb +85 -0
  240. data/vendor/webrat/spec/private/core/link_spec.rb +24 -0
  241. data/vendor/webrat/spec/private/core/logging_spec.rb +10 -0
  242. data/vendor/webrat/spec/private/core/session_spec.rb +195 -0
  243. data/vendor/webrat/spec/private/mechanize/mechanize_session_spec.rb +81 -0
  244. data/vendor/webrat/spec/private/merb/attaches_file_spec.rb +93 -0
  245. data/vendor/webrat/spec/private/merb/merb_session_spec.rb +61 -0
  246. data/vendor/webrat/spec/private/nokogiri_spec.rb +77 -0
  247. data/vendor/webrat/spec/private/rails/attaches_file_spec.rb +81 -0
  248. data/vendor/webrat/spec/private/rails/rails_session_spec.rb +112 -0
  249. data/vendor/webrat/spec/private/selenium/application_servers/rails_spec.rb +26 -0
  250. data/vendor/webrat/spec/public/basic_auth_spec.rb +24 -0
  251. data/vendor/webrat/spec/public/check_spec.rb +191 -0
  252. data/vendor/webrat/spec/public/choose_spec.rb +118 -0
  253. data/vendor/webrat/spec/public/click_area_spec.rb +106 -0
  254. data/vendor/webrat/spec/public/click_button_spec.rb +496 -0
  255. data/vendor/webrat/spec/public/click_link_spec.rb +511 -0
  256. data/vendor/webrat/spec/public/fill_in_spec.rb +209 -0
  257. data/vendor/webrat/spec/public/locators/field_by_xpath_spec.rb +19 -0
  258. data/vendor/webrat/spec/public/locators/field_labeled_spec.rb +172 -0
  259. data/vendor/webrat/spec/public/locators/field_with_id_spec.rb +16 -0
  260. data/vendor/webrat/spec/public/matchers/contain_spec.rb +114 -0
  261. data/vendor/webrat/spec/public/matchers/have_selector_spec.rb +142 -0
  262. data/vendor/webrat/spec/public/matchers/have_tag_spec.rb +39 -0
  263. data/vendor/webrat/spec/public/matchers/have_xpath_spec.rb +136 -0
  264. data/vendor/webrat/spec/public/reload_spec.rb +10 -0
  265. data/vendor/webrat/spec/public/save_and_open_spec.rb +70 -0
  266. data/vendor/webrat/spec/public/select_date_spec.rb +112 -0
  267. data/vendor/webrat/spec/public/select_datetime_spec.rb +137 -0
  268. data/vendor/webrat/spec/public/select_spec.rb +249 -0
  269. data/vendor/webrat/spec/public/select_time_spec.rb +100 -0
  270. data/vendor/webrat/spec/public/selenium/application_server_factory_spec.rb +49 -0
  271. data/vendor/webrat/spec/public/selenium/application_servers/external_spec.rb +12 -0
  272. data/vendor/webrat/spec/public/selenium/selenium_session_spec.rb +37 -0
  273. data/vendor/webrat/spec/public/set_hidden_field_spec.rb +5 -0
  274. data/vendor/webrat/spec/public/submit_form_spec.rb +5 -0
  275. data/vendor/webrat/spec/public/visit_spec.rb +58 -0
  276. data/vendor/webrat/spec/public/within_spec.rb +177 -0
  277. data/vendor/webrat/spec/rcov.opts +1 -0
  278. data/vendor/webrat/spec/spec.opts +2 -0
  279. data/vendor/webrat/spec/spec_helper.rb +50 -0
  280. metadata +554 -0
@@ -0,0 +1,350 @@
1
+ require "webrat/core/elements/form"
2
+ require "webrat/core/locators"
3
+ require "webrat/core_extensions/deprecate"
4
+
5
+ module Webrat
6
+ # An HTML element (link, button, field, etc.) that Webrat expected was not found on the page
7
+ class NotFoundError < WebratError
8
+ end
9
+
10
+ class Scope
11
+ include Logging
12
+ include Locators
13
+
14
+ def self.from_page(session, response, response_body) #:nodoc:
15
+ new(session) do
16
+ @response = response
17
+ @response_body = response_body
18
+ end
19
+ end
20
+
21
+ def self.from_scope(session, scope, selector) #:nodoc:
22
+ new(session) do
23
+ @scope = scope
24
+ @selector = selector
25
+ end
26
+ end
27
+
28
+ attr_reader :session
29
+
30
+ def initialize(session, &block) #:nodoc:
31
+ @session = session
32
+ instance_eval(&block) if block_given?
33
+
34
+ if @selector && scoped_dom.nil?
35
+ raise Webrat::NotFoundError.new("The scope was not found on the page: #{@selector.inspect}")
36
+ end
37
+ end
38
+
39
+ # Verifies an input field or textarea exists on the current page, and stores a value for
40
+ # it which will be sent when the form is submitted.
41
+ #
42
+ # Examples:
43
+ # fill_in "Email", :with => "user@example.com"
44
+ # fill_in "user[email]", :with => "user@example.com"
45
+ #
46
+ # The field value is required, and must be specified in <tt>options[:with]</tt>.
47
+ # <tt>field</tt> can be either the value of a name attribute (i.e. <tt>user[email]</tt>)
48
+ # or the text inside a <tt><label></tt> element that points at the <tt><input></tt> field.
49
+ def fill_in(field_locator, options = {})
50
+ field = locate_field(field_locator, TextField, TextareaField, PasswordField)
51
+ field.raise_error_if_disabled
52
+ field.set(options[:with])
53
+ end
54
+
55
+ webrat_deprecate :fills_in, :fill_in
56
+
57
+ # Verifies that a hidden field exists on the current page and sets
58
+ # the value to that given by the <tt>:to</tt> option.
59
+ #
60
+ # Example:
61
+ # set_hidden_field 'user_id', :to => 1
62
+ def set_hidden_field(field_locator, options = {})
63
+ field = locate_field(field_locator, HiddenField)
64
+ field.set(options[:to])
65
+ end
66
+
67
+ # Verifies that an input checkbox exists on the current page and marks it
68
+ # as checked, so that the value will be submitted with the form.
69
+ #
70
+ # Example:
71
+ # check 'Remember Me'
72
+ def check(field_locator)
73
+ locate_field(field_locator, CheckboxField).check
74
+ end
75
+
76
+ webrat_deprecate :checks, :check
77
+
78
+ # Verifies that an input checkbox exists on the current page and marks it
79
+ # as unchecked, so that the value will not be submitted with the form.
80
+ #
81
+ # Example:
82
+ # uncheck 'Remember Me'
83
+ def uncheck(field_locator)
84
+ locate_field(field_locator, CheckboxField).uncheck
85
+ end
86
+
87
+ webrat_deprecate :unchecks, :uncheck
88
+
89
+ # Verifies that an input radio button exists on the current page and marks it
90
+ # as checked, so that the value will be submitted with the form.
91
+ #
92
+ # Example:
93
+ # choose 'First Option'
94
+ def choose(field_locator)
95
+ locate_field(field_locator, RadioField).choose
96
+ end
97
+
98
+ webrat_deprecate :chooses, :choose
99
+
100
+ # Verifies that a an option element exists on the current page with the specified
101
+ # text. You can optionally restrict the search to a specific select list by
102
+ # assigning <tt>options[:from]</tt> the value of the select list's name or
103
+ # a label. Stores the option's value to be sent when the form is submitted.
104
+ #
105
+ # Examples:
106
+ # select "January"
107
+ # select "February", :from => "event_month"
108
+ # select "February", :from => "Event Month"
109
+ def select(option_text, options = {})
110
+ select_option(option_text, options[:from]).choose
111
+ end
112
+
113
+ webrat_deprecate :selects, :select
114
+
115
+ DATE_TIME_SUFFIXES = {
116
+ :year => '1i',
117
+ :month => '2i',
118
+ :day => '3i',
119
+ :hour => '4i',
120
+ :minute => '5i'
121
+ }
122
+
123
+ # Verifies that date elements (year, month, day) exist on the current page
124
+ # with the specified values. You can optionally restrict the search to a specific
125
+ # date's elements by assigning <tt>options[:from]</tt> the value of the date's
126
+ # label. Selects all the date elements with date provided. The date provided may
127
+ # be a string or a Date/Time object.
128
+ #
129
+ # Rail's convention is used for detecting the date elements. All elements
130
+ # are assumed to have a shared prefix. You may also specify the prefix
131
+ # by assigning <tt>options[:id_prefix]</tt>.
132
+ #
133
+ # Examples:
134
+ # select_date "January 23, 2004"
135
+ # select_date "April 26, 1982", :from => "Birthday"
136
+ # select_date Date.parse("December 25, 2000"), :from => "Event"
137
+ # select_date "April 26, 1982", :id_prefix => 'birthday'
138
+ def select_date(date_to_select, options ={})
139
+ date = date_to_select.is_a?(Date) || date_to_select.is_a?(Time) ?
140
+ date_to_select : Date.parse(date_to_select)
141
+
142
+ id_prefix = locate_id_prefix(options) do
143
+ year_field = FieldByIdLocator.new(@session, dom, /(.*?)_#{DATE_TIME_SUFFIXES[:year]}$/).locate
144
+ raise NotFoundError.new("No date fields were found") unless year_field && year_field.id =~ /(.*?)_1i/
145
+ $1
146
+ end
147
+
148
+ select date.year, :from => "#{id_prefix}_#{DATE_TIME_SUFFIXES[:year]}"
149
+ select date.strftime('%B'), :from => "#{id_prefix}_#{DATE_TIME_SUFFIXES[:month]}"
150
+ select date.day, :from => "#{id_prefix}_#{DATE_TIME_SUFFIXES[:day]}"
151
+ end
152
+
153
+ webrat_deprecate :selects_date, :select_date
154
+
155
+ # Verifies that time elements (hour, minute) exist on the current page
156
+ # with the specified values. You can optionally restrict the search to a specific
157
+ # time's elements by assigning <tt>options[:from]</tt> the value of the time's
158
+ # label. Selects all the time elements with date provided. The time provided may
159
+ # be a string or a Time object.
160
+ #
161
+ # Rail's convention is used for detecting the time elements. All elements are
162
+ # assumed to have a shared prefix. You may specify the prefix by assigning
163
+ # <tt>options[:id_prefix]</tt>.
164
+ #
165
+ # Note: Just like Rails' time_select helper this assumes the form is using
166
+ # 24 hour select boxes, and not 12 hours with AM/PM.
167
+ #
168
+ # Examples:
169
+ # select_time "9:30"
170
+ # select_date "3:30PM", :from => "Party Time"
171
+ # select_date Time.parse("10:00PM"), :from => "Event"
172
+ # select_date "10:30AM", :id_prefix => 'meeting'
173
+ def select_time(time_to_select, options ={})
174
+ time = time_to_select.is_a?(Time) ? time_to_select : Time.parse(time_to_select)
175
+
176
+ id_prefix = locate_id_prefix(options) do
177
+ hour_field = FieldByIdLocator.new(@session, dom, /(.*?)_#{DATE_TIME_SUFFIXES[:hour]}$/).locate
178
+ raise NotFoundError.new("No time fields were found") unless hour_field && hour_field.id =~ /(.*?)_4i/
179
+ $1
180
+ end
181
+
182
+ select time.hour.to_s.rjust(2,'0'), :from => "#{id_prefix}_#{DATE_TIME_SUFFIXES[:hour]}"
183
+ select time.min.to_s.rjust(2,'0'), :from => "#{id_prefix}_#{DATE_TIME_SUFFIXES[:minute]}"
184
+ end
185
+
186
+ webrat_deprecate :selects_time, :select_time
187
+
188
+ # Verifies and selects all the date and time elements on the current page.
189
+ # See #select_time and #select_date for more details and available options.
190
+ #
191
+ # Examples:
192
+ # select_datetime "January 23, 2004 10:30AM"
193
+ # select_datetime "April 26, 1982 7:00PM", :from => "Birthday"
194
+ # select_datetime Time.parse("December 25, 2000 15:30"), :from => "Event"
195
+ # select_datetime "April 26, 1982 5:50PM", :id_prefix => 'birthday'
196
+ def select_datetime(time_to_select, options ={})
197
+ time = time_to_select.is_a?(Time) ? time_to_select : Time.parse(time_to_select)
198
+
199
+ options[:id_prefix] ||= (options[:from] ? FieldByIdLocator.new(@session, dom, options[:from]).locate : nil)
200
+
201
+ select_date time, options
202
+ select_time time, options
203
+ end
204
+
205
+ webrat_deprecate :selects_datetime, :select_datetime
206
+
207
+ # Verifies that an input file field exists on the current page and sets
208
+ # its value to the given +file+, so that the file will be uploaded
209
+ # along with the form. An optional <tt>content_type</tt> may be given.
210
+ #
211
+ # Example:
212
+ # attach_file "Resume", "/path/to/the/resume.txt"
213
+ # attach_file "Photo", "/path/to/the/image.png", "image/png"
214
+ def attach_file(field_locator, path, content_type = nil)
215
+ locate_field(field_locator, FileField).set(path, content_type)
216
+ end
217
+
218
+ webrat_deprecate :attaches_file, :attach_file
219
+
220
+ # Issues a request for the URL pointed to by an <tt>area</tt> tag
221
+ # on the current page, follows any redirects, and verifies the
222
+ # final page load was successful.
223
+ #
224
+ # The area used is the first area whose title or id contains the
225
+ # given +area_name+ (case is ignored).
226
+ #
227
+ # Example:
228
+ # click_area 'Australia'
229
+ def click_area(area_name)
230
+ find_area(area_name).click
231
+ end
232
+
233
+ webrat_deprecate :clicks_area, :click_area
234
+
235
+ # Issues a request for the URL pointed to by a link on the current page,
236
+ # follows any redirects, and verifies the final page load was successful.
237
+ #
238
+ # click_link has very basic support for detecting Rails-generated
239
+ # JavaScript onclick handlers for PUT, POST and DELETE links, as well as
240
+ # CSRF authenticity tokens if they are present.
241
+ #
242
+ # Javascript imitation can be disabled by passing the option :javascript => false
243
+ #
244
+ # Passing a :method in the options hash overrides the HTTP method used
245
+ # for making the link request
246
+ #
247
+ # It will try to find links by (in order of precedence):
248
+ # innerHTML, with simple &nbsp; handling
249
+ # title
250
+ # id
251
+ #
252
+ # innerHTML and title are matchable by text subtring or Regexp
253
+ # id is matchable by full text equality or Regexp
254
+ #
255
+ # Example:
256
+ # click_link "Sign up"
257
+ # click_link "Sign up", :javascript => false
258
+ # click_link "Sign up", :method => :put
259
+ def click_link(text_or_title_or_id, options = {})
260
+ find_link(text_or_title_or_id).click(options)
261
+ end
262
+
263
+ webrat_deprecate :clicks_link, :click_link
264
+
265
+ # Verifies that a submit button exists for the form, then submits the form, follows
266
+ # any redirects, and verifies the final page was successful.
267
+ #
268
+ # Example:
269
+ # click_button "Login"
270
+ # click_button
271
+ #
272
+ # The URL and HTTP method for the form submission are automatically read from the
273
+ # <tt>action</tt> and <tt>method</tt> attributes of the <tt><form></tt> element.
274
+ def click_button(value = nil)
275
+ find_button(value).click
276
+ end
277
+
278
+ webrat_deprecate :clicks_button, :click_button
279
+
280
+ # Submit the form with the given id.
281
+ #
282
+ # Note that +click_button+ is usually preferrable for simulating
283
+ # form submissions, as you may specify part of the button text
284
+ # rather than the form id.
285
+ #
286
+ # Example:
287
+ # submit_form 'login'
288
+ def submit_form(id)
289
+ FormLocator.new(@session, dom, id).locate.submit
290
+ end
291
+
292
+ def dom # :nodoc:
293
+ return @dom if @dom
294
+
295
+ if @selector
296
+ @dom = scoped_dom
297
+ else
298
+ @dom = page_dom
299
+ end
300
+
301
+ return @dom
302
+ end
303
+
304
+ protected
305
+
306
+ def page_dom #:nodoc:
307
+ return @response.dom if @response.respond_to?(:dom)
308
+
309
+ if @session.xml_content_type?
310
+ dom = Webrat::XML.xml_document(@response_body)
311
+ else
312
+ dom = Webrat::XML.html_document(@response_body)
313
+ end
314
+
315
+ Webrat.define_dom_method(@response, dom)
316
+ return dom
317
+ end
318
+
319
+ def scoped_dom
320
+ Webrat::XML.css_at(@scope.dom, @selector)
321
+ end
322
+
323
+ def locate_field(field_locator, *field_types) #:nodoc:
324
+ if field_locator.is_a?(Field)
325
+ field_locator
326
+ else
327
+ field(field_locator, *field_types)
328
+ end
329
+ end
330
+
331
+ def locate_id_prefix(options, &location_strategy) #:nodoc:
332
+ return options[:id_prefix] if options[:id_prefix]
333
+
334
+ if options[:from]
335
+ if (label = LabelLocator.new(@session, dom, options[:from]).locate)
336
+ label.for_id
337
+ else
338
+ raise NotFoundError.new("Could not find the label with text #{options[:from]}")
339
+ end
340
+ else
341
+ yield
342
+ end
343
+ end
344
+
345
+ def forms #:nodoc:
346
+ @forms ||= Form.load_all(@session, dom)
347
+ end
348
+
349
+ end
350
+ end
@@ -0,0 +1,299 @@
1
+ require "forwardable"
2
+ require "ostruct"
3
+
4
+ require "webrat/core/mime"
5
+ require "webrat/core/save_and_open_page"
6
+
7
+ module Webrat
8
+ # A page load or form submission returned an unsuccessful response code (500-599)
9
+ class PageLoadError < WebratError
10
+ end
11
+
12
+ class InfiniteRedirectError < WebratError
13
+ end
14
+
15
+ def self.session_class
16
+ case Webrat.configuration.mode
17
+ when :rails
18
+ RailsSession
19
+ when :merb
20
+ MerbSession
21
+ when :rack
22
+ RackSession
23
+ when :rack_test
24
+ warn("The :rack_test mode is deprecated. Please use :rack instead")
25
+ require "webrat/rack"
26
+ RackSession
27
+ when :sinatra
28
+ warn("The :sinatra mode is deprecated. Please use :rack instead")
29
+ SinatraSession
30
+ when :selenium
31
+ SeleniumSession
32
+ when :sinatra
33
+ SinatraSession
34
+ when :mechanize
35
+ MechanizeSession
36
+ else
37
+ raise WebratError.new(<<-STR)
38
+ Unknown Webrat mode: #{Webrat.configuration.mode.inspect}
39
+
40
+ Please ensure you have a Webrat configuration block that specifies a mode
41
+ in your test_helper.rb, spec_helper.rb, or env.rb (for Cucumber).
42
+
43
+ This configure block supercedes the need to require "webrat/<framework>".
44
+
45
+ For example:
46
+
47
+ Webrat.configure do |config|
48
+ config.mode = :rails
49
+ end
50
+ STR
51
+ end
52
+ end
53
+
54
+ class Session
55
+ extend Forwardable
56
+ include Logging
57
+ include SaveAndOpenPage
58
+ attr_reader :current_url
59
+ attr_reader :elements
60
+
61
+ def_delegators :@adapter, :response, :response_code, :response_body,
62
+ :response_body=, :response_code=,
63
+ :get, :post, :put, :delete
64
+
65
+ def initialize(adapter=nil)
66
+ @http_method = :get
67
+ @data = {}
68
+ @default_headers = {}
69
+ @custom_headers = {}
70
+ @adapter = adapter
71
+
72
+ reset
73
+ end
74
+
75
+ def current_dom #:nodoc:
76
+ current_scope.dom
77
+ end
78
+
79
+ # For backwards compatibility -- removing in 1.0
80
+ def current_page #:nodoc:
81
+ warn "current_page is deprecated and will be going away in the next release. Use current_url instead."
82
+ page = OpenStruct.new
83
+ page.url = @current_url
84
+ page.http_method = @http_method
85
+ page.data = @data
86
+ page
87
+ end
88
+
89
+ def doc_root #:nodoc:
90
+ nil
91
+ end
92
+
93
+ def header(key, value)
94
+ @custom_headers[key] = value
95
+ end
96
+
97
+ def http_accept(mime_type)
98
+ header('Accept', Webrat::MIME.mime_type(mime_type))
99
+ end
100
+
101
+ def basic_auth(user, pass)
102
+ encoded_login = ["#{user}:#{pass}"].pack("m*")
103
+ header('HTTP_AUTHORIZATION', "Basic #{encoded_login}")
104
+ end
105
+
106
+ def headers #:nodoc:
107
+ @default_headers.dup.merge(@custom_headers.dup)
108
+ end
109
+
110
+ def request_page(url, http_method, data) #:nodoc:
111
+ h = headers
112
+ h['HTTP_REFERER'] = @current_url if @current_url
113
+
114
+ debug_log "REQUESTING PAGE: #{http_method.to_s.upcase} #{url} with #{data.inspect} and HTTP headers #{h.inspect}"
115
+
116
+ process_request(http_method, url, data, h)
117
+
118
+ save_and_open_page if exception_caught? && Webrat.configuration.open_error_files?
119
+ raise PageLoadError.new("Page load was not successful (Code: #{response_code.inspect}):\n#{formatted_error}") unless success_code?
120
+
121
+ reset
122
+
123
+ @current_url = url
124
+ @http_method = http_method
125
+ @data = data
126
+
127
+ if internal_redirect?
128
+ check_for_infinite_redirects
129
+ request_page(response_location, :get, {})
130
+ end
131
+
132
+ return response
133
+ end
134
+
135
+ def check_for_infinite_redirects
136
+ if current_url == response_location
137
+ @_identical_redirect_count ||= 0
138
+ @_identical_redirect_count += 1
139
+ end
140
+
141
+ if infinite_redirect_limit_exceeded?
142
+ raise InfiniteRedirectError.new("#{Webrat.configuration.infinite_redirect_limit} redirects to the same URL (#{current_url.inspect})")
143
+ end
144
+ end
145
+
146
+ def infinite_redirect_limit_exceeded?
147
+ Webrat.configuration.infinite_redirect_limit &&
148
+ (@_identical_redirect_count || 0) > Webrat.configuration.infinite_redirect_limit
149
+ end
150
+
151
+ def success_code? #:nodoc:
152
+ (200..499).include?(response_code)
153
+ end
154
+
155
+ def redirect? #:nodoc:
156
+ (response_code / 100).to_i == 3
157
+ end
158
+
159
+ def internal_redirect?
160
+ return false unless redirect?
161
+ #should keep internal_redirects if the subdomain changes
162
+ current_host_domain = current_host.split('.')[-2..-1].join('.') rescue current_host
163
+ response_location_host_domain = response_location_host.split('.')[-2..-1].join('.') rescue response_location_host
164
+ current_host_domain == response_location_host_domain
165
+ end
166
+
167
+ #easy helper to pull out where we were redirected to
168
+ def redirected_to
169
+ redirect? ? response_location : nil
170
+ end
171
+
172
+ def exception_caught? #:nodoc:
173
+ response_body =~ /Exception caught/
174
+ end
175
+
176
+ def current_scope #:nodoc:
177
+ scopes.last || page_scope
178
+ end
179
+
180
+ # Reloads the last page requested. Note that this will resubmit forms
181
+ # and their data.
182
+ def reload
183
+ request_page(@current_url, @http_method, @data)
184
+ end
185
+
186
+ webrat_deprecate :reloads, :reload
187
+
188
+
189
+ # Works like click_link, but only looks for the link text within a given selector
190
+ #
191
+ # Example:
192
+ # click_link_within "#user_12", "Vote"
193
+ def click_link_within(selector, link_text)
194
+ within(selector) do
195
+ click_link(link_text)
196
+ end
197
+ end
198
+
199
+ webrat_deprecate :clicks_link_within, :click_link_within
200
+
201
+ def within(selector)
202
+ scopes.push(Scope.from_scope(self, current_scope, selector))
203
+ ret = yield(current_scope)
204
+ scopes.pop
205
+ return ret
206
+ end
207
+
208
+ # Issues a GET request for a page, follows any redirects, and verifies the final page
209
+ # load was successful.
210
+ #
211
+ # Example:
212
+ # visit "/"
213
+ def visit(url = nil, http_method = :get, data = {})
214
+ request_page(url, http_method, data)
215
+ end
216
+
217
+ webrat_deprecate :visits, :visit
218
+
219
+ # Subclasses can override this to show error messages without html
220
+ def formatted_error #:nodoc:
221
+ response_body
222
+ end
223
+
224
+ def scopes #:nodoc:
225
+ @_scopes ||= []
226
+ end
227
+
228
+ def page_scope #:nodoc:
229
+ @_page_scope ||= Scope.from_page(self, response, response_body)
230
+ end
231
+
232
+ def dom
233
+ page_scope.dom
234
+ end
235
+
236
+ def xml_content_type?
237
+ false
238
+ end
239
+
240
+ def simulate
241
+ return if Webrat.configuration.mode == :selenium
242
+ yield
243
+ end
244
+
245
+ def automate
246
+ return unless Webrat.configuration.mode == :selenium
247
+ yield
248
+ end
249
+
250
+ def_delegators :current_scope, :fill_in, :fills_in
251
+ def_delegators :current_scope, :set_hidden_field
252
+ def_delegators :current_scope, :submit_form
253
+ def_delegators :current_scope, :check, :checks
254
+ def_delegators :current_scope, :uncheck, :unchecks
255
+ def_delegators :current_scope, :choose, :chooses
256
+ def_delegators :current_scope, :select, :selects
257
+ def_delegators :current_scope, :select_datetime, :selects_datetime
258
+ def_delegators :current_scope, :select_date, :selects_date
259
+ def_delegators :current_scope, :select_time, :selects_time
260
+ def_delegators :current_scope, :attach_file, :attaches_file
261
+ def_delegators :current_scope, :click_area, :clicks_area
262
+ def_delegators :current_scope, :click_link, :clicks_link
263
+ def_delegators :current_scope, :click_button, :clicks_button
264
+ def_delegators :current_scope, :field_labeled
265
+ def_delegators :current_scope, :field_by_xpath
266
+ def_delegators :current_scope, :field_with_id
267
+ def_delegators :current_scope, :select_option
268
+ def_delegators :current_scope, :field_named
269
+
270
+ private
271
+
272
+ def process_request(http_method, url, data, headers)
273
+ if headers.empty?
274
+ send "#{http_method}", url, data || {}
275
+ else
276
+ send "#{http_method}", url, data || {}, headers
277
+ end
278
+ end
279
+
280
+ def response_location
281
+ response.headers["Location"]
282
+ end
283
+
284
+ def current_host
285
+ URI.parse(current_url).host || @custom_headers["Host"] || "www.example.com"
286
+ end
287
+
288
+ def response_location_host
289
+ URI.parse(response_location).host || "www.example.com"
290
+ end
291
+
292
+ def reset
293
+ @elements = {}
294
+ @_scopes = nil
295
+ @_page_scope = nil
296
+ end
297
+
298
+ end
299
+ end
@@ -0,0 +1,19 @@
1
+ module Webrat
2
+
3
+ def self.hpricot_document(stringlike)
4
+ return stringlike.dom if stringlike.respond_to?(:dom)
5
+
6
+ if Hpricot::Doc === stringlike
7
+ stringlike
8
+ elsif Hpricot::Elements === stringlike
9
+ stringlike
10
+ elsif StringIO === stringlike
11
+ Hpricot(stringlike.string)
12
+ elsif stringlike.respond_to?(:body)
13
+ Hpricot(stringlike.body.to_s)
14
+ else
15
+ Hpricot(stringlike.to_s)
16
+ end
17
+ end
18
+
19
+ end