jtzemp-tourbus 0.0.9 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -75,60 +75,54 @@ particular order.
75
75
 
76
76
  Right. Let's look test_home first, because it's simpler:
77
77
 
78
- def test_home
79
- open_site_page "/"
80
- click_link :text => /Enter Contact/
81
- assert_page_uri_matches "/contacts"
82
- end
78
+ def test_home
79
+ visit "/"
80
+ assert_contain "If you click this"
83
81
 
84
- +open_site_page+ is defined in Tour.rb, it opens the given path on the
82
+ click_link "Enter Contact"
83
+ assert_match /\/contacts/, current_page.url
84
+ end
85
+
86
+ +visit+ is a webrat method that you can call inside of your tours. It opens the given path on the
85
87
  host that tourbus is testing.
86
88
 
89
+ +assert_contain+ is also a webrat method that confirms the given string is on the page.
90
+
87
91
  +click_link+ does what you'd expect. It takes a hash that identifies
88
- the link to click. In this case I chose to identify the link with a
89
- regexp describing its text label. +click_link+ will raise an exception
92
+ the link to click. +click_link+ will raise an exception
90
93
  if it cannot find the link to click.
91
94
 
92
- +assert_page_uri_matches+ will raise an exception unless the uri
93
- matches the given string or regexp. If I had passed in a regexp, it
94
- would have passed if the regexp matched. *Note:* Strings only match at
95
- the /end/ of the uri; simple containment is not enough. Passing
96
- "/contacts" works the same as passing %r{/contacts$}.
97
-
98
- Clear as mud? "/contacts" would match
99
- http://localhost:4567/users/42/contacts but not
100
- http://localhost:4567/contacts/42.
95
+ +assert_match+ comes from Test::Unit which is used internally to webrat. It will raise an exception unless the uri
96
+ matches the given regexp.
101
97
 
98
+ So you should be able to use any Webrat locator or matcher, and any of the Test::Unit assertions.
102
99
 
103
100
  === test_contacts
104
101
 
105
102
  Okay, let's actually submit a form.
106
103
 
107
- def test_contacts
108
- open_site_page "contacts"
109
- submit_form(
110
- :identified_by => { :action => %r{/contacts} },
111
- :values => {
112
- 'first_name' => "Joe",
113
- 'last_name' => "Tester"
114
- }
115
- )
116
- assert_page_uri_matches "/contacts"
117
- assert_page_body_contains "Tester, Joe"
118
- end
104
+ def test_contacts
105
+ visit "/contacts"
106
+
107
+ fill_in "first_name", :with => "Joe"
108
+ fill_in "last_name", :with => "Tester"
109
+ click_button
110
+
111
+ assert_contain "Tester, Joe"
112
+ end
119
113
 
120
114
  test_contacts starts by going directly to the contacts app. Note that
121
- the leading "/" is optional.
115
+ the leading "/" isn't optional.
116
+
117
+ +fill_in+ is a Webrat method that will look for form fields based on ids, label text, and other things.
118
+ It's matchers are pretty good. Check out Webrat's documentation for more info. In the examples above,
119
+ we're finding the fields for the first name and last name and putting in "Joe" and "Tester" respectively.
120
+ +fill_in+ asserts that the fields actually exist and will raise an exception if they don't.
122
121
 
123
- +submit_form+ does what its name implies. It finds the correct form to
124
- submit by matching the action to a regexp, then it sets the form
125
- values and submits the form. *Note:* Like +click_link+, +submit_form+
126
- contains some implicit assertions. It actually reads the form looking
127
- for the named inputs and will raise an exception if any are missing.
128
- This means you cannot use submit_form to do a blind post to a
129
- webserver.
122
+ +click_button+ does what its name implies. It finds the correct form to
123
+ submit Webrat is smart like that. *Note:* Like +click_link+, +click_button+
124
+ contains some implicit assertions and will raise an exception if the button doesn't exist.
130
125
 
131
- +assert_page_uri_matches+ we've already seen;
132
- +assert_page_body_contains+ searches the page body for the given text
133
- or regexp.
126
+ +assert_contain+ we've already seen.
134
127
 
128
+ Good luck, and happy touring!
@@ -9,7 +9,7 @@ require 'rubygems'
9
9
  require 'sinatra'
10
10
 
11
11
  get '/' do
12
- '<a href="/contacts">Enter Contact</a>'
12
+ %{If you click this, I'll take you to a page where you can enter your contact info: <a href="/contacts">Enter Contact</a>}
13
13
  end
14
14
 
15
15
  get '/contacts' do
@@ -23,7 +23,7 @@ get '/contacts' do
23
23
  <form action="/contacts" method="POST">
24
24
  <p><label for="first_name"><b>First Name:</b></label> <input name="first_name" size="30"></p>
25
25
  <p><label for="last_name"><b>Last Name:</b></label> <input name="last_name" size="30"></p>
26
- <input type="submit">
26
+ <input type="submit" value="Submit">
27
27
  </form>
28
28
  </body>
29
29
  </html>
@@ -1,20 +1,19 @@
1
1
  class Simple < Tour
2
2
  def test_home
3
- open_site_page "/"
4
- click_link :text => /Enter Contact/
5
- assert_page_uri_matches "/contacts"
3
+ visit "/"
4
+ assert_contain "If you click this"
5
+
6
+ click_link "Enter Contact"
7
+ assert_match /\/contacts/, current_page.url
6
8
  end
7
9
 
8
10
  def test_contacts
9
- open_site_page "contacts"
10
- submit_form(
11
- :identified_by => { :action => %r{/contacts} },
12
- :values => {
13
- 'first_name' => "Joe",
14
- 'last_name' => "Tester"
15
- }
16
- )
17
- assert_page_uri_matches "/contacts"
18
- assert_page_body_contains "Tester, Joe"
11
+ visit "/contacts"
12
+
13
+ fill_in "first_name", :with => "Joe"
14
+ fill_in "last_name", :with => "Tester"
15
+ click_button
16
+
17
+ assert_contain "Tester, Joe"
19
18
  end
20
19
  end
@@ -1,2 +1,2 @@
1
1
  ---
2
- host: localhost
2
+ host: http://localhost:4567
data/lib/common.rb CHANGED
@@ -16,7 +16,6 @@ require 'activesupport'
16
16
 
17
17
  require 'monitor'
18
18
  require 'faker'
19
- require 'web-sickle/init'
20
19
  require 'tour_bus'
21
20
  require 'runner'
22
21
  require 'tour'
data/lib/runner.rb CHANGED
@@ -1,6 +1,9 @@
1
1
  require 'monitor'
2
2
  require 'common'
3
3
 
4
+ # The common base class for all exceptions raised by Webrat.
5
+ class WebratError < StandardError ; end
6
+
4
7
  class Runner
5
8
  attr_reader :host, :tours, :number, :runner_type, :runner_id
6
9
 
@@ -31,7 +34,7 @@ class Runner
31
34
  tests += 1
32
35
  tour.run_test test
33
36
  passes += 1
34
- rescue TourBusException, WebsickleException => e
37
+ rescue TourBusException, WebratError => e
35
38
  log("********** FAILURE IN RUN! **********")
36
39
  log e.message
37
40
  e.backtrace.each do |trace|
data/lib/tour.rb CHANGED
@@ -31,6 +31,7 @@ class Tour
31
31
  :unchecks,
32
32
  :choose,
33
33
  :chooses,
34
+ :current_page,
34
35
  :select,
35
36
  :selects,
36
37
  :select_datetime,
@@ -62,7 +63,7 @@ class Tour
62
63
  :internal_redirect?,
63
64
  :redirected_to,
64
65
  :reload,
65
- :response_body,
66
+ :response_body,
66
67
  :simulate,
67
68
  :visit,
68
69
  :within,
@@ -72,6 +73,7 @@ class Tour
72
73
  @host, @tours, @number, @tour_id = host, tours, number, tour_id
73
74
  @tour_type = self.send(:class).to_s
74
75
  @webrat_session = Webrat::MechanizeSession.new
76
+ visit @host if @host
75
77
  end
76
78
 
77
79
  # before_tour runs once per tour, before any tests get run
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: jtzemp-tourbus
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.9
4
+ version: 0.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - David Brady
@@ -10,7 +10,7 @@ autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
12
 
13
- date: 2009-04-17 00:00:00 -07:00
13
+ date: 2009-07-25 00:00:00 -07:00
14
14
  default_executable:
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
@@ -76,18 +76,6 @@ files:
76
76
  - lib/tour.rb
77
77
  - lib/tour_bus.rb
78
78
  - lib/tour_watch.rb
79
- - lib/web_sickle_webrat_adapter.rb
80
- - lib/web-sickle/init.rb
81
- - lib/web-sickle/lib/assertions.rb
82
- - lib/web-sickle/lib/hash_proxy.rb
83
- - lib/web-sickle/lib/helpers/asp_net.rb
84
- - lib/web-sickle/lib/helpers/table_reader.rb
85
- - lib/web-sickle/lib/make_nokigiri_output_useful.rb
86
- - lib/web-sickle/lib/web_sickle.rb
87
- - lib/web-sickle/spec/lib/helpers/table_reader_spec.rb
88
- - lib/web-sickle/spec/spec_helper.rb
89
- - lib/web-sickle/spec/spec_helpers/mechanize_mock_helper.rb
90
- - lib/web-sickle/spec/web_sickle_spec.rb
91
79
  - README.rdoc
92
80
  - MIT-LICENSE
93
81
  has_rdoc: true
@@ -1,17 +0,0 @@
1
- require 'rubygems'
2
- gem 'mechanize', ">= 0.7.6"
3
- gem "hpricot", ">= 0.6"
4
- $: << File.join(File.dirname(__FILE__), 'lib')
5
-
6
- require 'hpricot'
7
- require 'mechanize'
8
-
9
- WWW::Mechanize.html_parser = Hpricot
10
-
11
- require 'web_sickle'
12
- require "assertions"
13
- require "hash_proxy"
14
- require "helpers/asp_net"
15
- require "helpers/table_reader"
16
-
17
- Hpricot.buffer_size = 524288
@@ -1,51 +0,0 @@
1
- class WebSickleAssertionException < Exception; end
2
-
3
- module WebSickle::Assertions
4
- def assert_equals(expected, actual, message = nil)
5
- unless(expected == actual)
6
- report_error <<-EOF
7
- Error: Expected
8
- #{expected.inspect}, but got
9
- #{actual.inspect}
10
- #{message}
11
- EOF
12
- end
13
- end
14
-
15
- def assert_select(selector, message)
16
- assert_select_in(@page, selector, message)
17
- end
18
-
19
- def assert_no_select(selector, message)
20
- assert_no_select_in(@page, selector, message)
21
- end
22
-
23
- def assert_select_in(content, selector, message)
24
- report_error("Error: Expected selector #{selector.inspect} to find a page element, but didn't. #{message}") if (content / selector).blank?
25
- end
26
-
27
- def assert_no_select_in(content, selector, message)
28
- report_error("Error: Expected selector #{selector.inspect} to not find a page element, but did. #{message}") unless (content / selector).blank?
29
- end
30
-
31
- def assert_contains(left, right, message = nil)
32
- (right.is_a?(Array) ? right : [right]).each do | item |
33
- report_error("Error: Expected #{left.inspect} to contain #{right.inspect}, but didn't. #{message}") unless left.include?(item)
34
- end
35
- end
36
-
37
- def assert(passes, message = nil)
38
- report_error("Error: expected true, got false. #{message}") unless passes
39
- end
40
-
41
- def assert_link_text(link, text)
42
- case text
43
- when String
44
- assert_equals(link.text, text)
45
- when Regexp
46
- assert(link.text.match(text))
47
- else
48
- raise ArgumentError, "Don't know how to assert an object like #{text.inspect} - expected: Regexp or String"
49
- end
50
- end
51
- end
@@ -1,9 +0,0 @@
1
- class HashProxy
2
- def initialize(options = {})
3
- @set = options[:set]
4
- @get = options[:get]
5
- end
6
-
7
- def [](key); @get && @get.call(key); end
8
- def []=(key, value); @set && @set.call(key, value); end
9
- end
@@ -1,16 +0,0 @@
1
- module WebSickle::Helpers
2
- module AspNet
3
- def asp_net_do_postback(options)
4
- target_element = case
5
- when options[:button]
6
- find_button(options[:button])
7
- when options[:field]
8
- find_field(options[:field])
9
- else
10
- nil
11
- end
12
- @form.fields << WWW::Mechanize::Form::Field.new("__EVENTTARGET", target_element ? target_element.name : "") if target_element
13
- submit_form_button
14
- end
15
- end
16
- end
@@ -1,39 +0,0 @@
1
- module WebSickle::Helpers
2
- class TableReader
3
- attr_reader :headers, :options, :body_rows, :header_row, :extra_rows
4
-
5
- def initialize(element, p_options = {})
6
- @options = {
7
- :row_selectors => [" > tr", "thead > tr", "tbody > tr"],
8
- :header_selector => " > th",
9
- :header_proc => lambda { |th| th.inner_text.gsub(/[\n\s]+/, ' ').strip },
10
- :body_selector => " > td",
11
- :body_proc => lambda { |header, td| td.inner_text.strip },
12
- :header_offset => 0,
13
- :body_offset => 1
14
- }.merge(p_options)
15
- @options[:body_range] ||= options[:body_offset]..-1
16
- raw_rows = options[:row_selectors].map{|row_selector| element / row_selector}.compact.flatten
17
-
18
- @header_row = raw_rows[options[:header_offset]]
19
- @body_rows = raw_rows[options[:body_range]]
20
- @extra_rows = (options[:body_range].last+1)==0 ? [] : raw_rows[(options[:body_range].last+1)..-1]
21
-
22
- @headers = (@header_row / options[:header_selector]).map(&options[:header_proc])
23
- end
24
-
25
- def rows
26
- @rows ||= @body_rows.map do |row|
27
- hash = {}
28
- data_array = (headers).zip(row / options[:body_selector]).each do |column_name, td|
29
- hash[column_name] = options[:body_proc].call(column_name, td)
30
- end
31
- hash
32
- end
33
- end
34
-
35
- def array_to_hash(data, column_names)
36
- column_names.inject({}) {|h,column_name| h[column_name] = data[column_names.index(column_name)]; h }
37
- end
38
- end
39
- end
@@ -1,15 +0,0 @@
1
- # Nokogiri::XML::Element.class_eval do
2
- # def inspect(indent = "")
3
- # breaker = "\n#{indent}"
4
- # if children.length == 0
5
- # %(#{indent}<#{name}#{breaker} #{attributes.map {|k,v| k + '=' + v.inspect} * "#{breaker} "}/>)
6
- # else
7
- # %(#{indent}<#{name} #{attributes.map {|k,v| k + '=' + v.inspect} * " "}>\n#{children.map {|c| c.inspect(indent + ' ') rescue c.class} * "\n"}#{breaker}</#{name}>)
8
- # end
9
- # end
10
- # end
11
- # Nokogiri::XML::Text.class_eval do
12
- # def inspect(indent = "")
13
- # "#{indent}#{text.inspect}"
14
- # end
15
- # end
@@ -1,227 +0,0 @@
1
- class WebsickleException < Exception; end
2
-
3
- module WebSickle
4
- # form_value is used to interface with the current select form
5
- attr_reader :form_value
6
- attr_accessor :page
7
-
8
- def initialize(options = {})
9
- @page = nil
10
- @form_value = HashProxy.new(
11
- :set => lambda { |identifier, value| set_form_value(identifier, value)},
12
- :get => lambda { |identifier| get_form_value(identifier)}
13
- )
14
- end
15
-
16
- def click_link(link)
17
- set_page(agent.click(find_link(link)))
18
- end
19
-
20
- def submit_form(options = {})
21
- options[:button] = :first unless options.has_key?(:button)
22
- options[:identified_by] ||= :first
23
- select_form(options[:identified_by])
24
- set_form_values(options[:values]) if options[:values]
25
- submit_form_button(options[:button])
26
- end
27
-
28
- # select the current form
29
- def select_form(identifier = {})
30
- identifier = make_identifier(identifier, [:name, :action, :method])
31
- @form = find_in_collection(@page.forms, identifier)
32
- unless @form
33
- valid_forms = @page.forms.map {|f| "name: #{f.name}, method: #{f.method}, action: #{f.action}"} * "\n"
34
- report_error("Couldn't find form on page at #{@page.uri} with attributes #{identifier.inspect}. Valid forms on this page are: \n#{valid_forms}")
35
- end
36
- @form
37
- end
38
-
39
- # submits the current form
40
- def submit_form_button(button_criteria = nil, options = {})
41
- button =
42
- case button_criteria
43
- when nil
44
- nil
45
- else
46
- find_button(button_criteria)
47
- end
48
- set_page(agent.submit(@form, button))
49
- end
50
-
51
- # sets the given path to the current page, then opens it using our agent
52
- def open_page(path, parameters = [], referer = nil)
53
- set_page(agent.get(path, parameters, referer))
54
- end
55
-
56
- # uses Hpricot style css selectors to find the elements in the current +page+.
57
- # Uses Hpricot#/ (or Hpricot#search)
58
- def select_element(match)
59
- select_element_in(@page, match)
60
- end
61
-
62
- # uses Hpricot style css selectors to find the element in the given container. Works with html pages, and file pages that happen to have xml-like content.
63
- # throws error if can't find a match
64
- def select_element_in(contents, match)
65
- result = (contents.respond_to?(:/) ? contents : Hpricot(contents.body)) / match
66
- if result.blank?
67
- report_error("Tried to find element matching #{match}, but couldn't")
68
- else
69
- result
70
- end
71
- end
72
-
73
- # uses Hpricot style css selectors to find the element. Works with html pages, and file pages that happen to have xml-like content.
74
- # throws error if can't find a match
75
- # Uses Hpricot#at
76
- def detect_element(match)
77
- result = (@page.respond_to?(:at) ? @page : Hpricot(@page.body)).at(match)
78
- if result.blank?
79
- report_error("Tried to find element matching #{match}, but couldn't")
80
- else
81
- result
82
- end
83
- end
84
-
85
- protected
86
- # our friendly mechinze agent
87
- def agent
88
- @agent ||= new_mechanize_agent
89
- end
90
-
91
- def make_identifier(identifier, valid_keys = nil, default_key = :name)
92
- identifier = {default_key => identifier} unless identifier.is_a?(Hash) || identifier.is_a?(Symbol)
93
- identifier.assert_valid_keys(valid_keys) if identifier.is_a?(Hash) && valid_keys
94
- identifier
95
- end
96
-
97
- def find_field(identifier)
98
- if @form.nil?
99
- report_error("No form is selected when trying to find field by #{identifier.inspect}")
100
- return
101
- end
102
- identifier = make_identifier(identifier, [:name, :value])
103
- find_in_collection(@form.radiobuttons + @form.fields + @form.checkboxes + @form.file_uploads, identifier) ||
104
- report_error("Tried to find field identified by #{identifier.inspect}, but failed.\nForm fields are: #{(@form.radiobuttons + @form.fields + @form.checkboxes + @form.file_uploads).map{|f| f.name} * ", \n "}")
105
- end
106
-
107
- def find_link(identifier)
108
- identifier = make_identifier(identifier, [:href, :text], :text)
109
- find_in_collection(page.links, identifier) ||
110
- report_error("Tried to find link identified by #{identifier.inspect}, but failed.\nValid links are: #{page.links.map{|f| f.inspect} * ", \n "}")
111
- end
112
-
113
- # finds a button by parameters. Throws error if not able to find.
114
- # example:
115
- # find_button("btnSubmit") - finds a button named "btnSubmit"
116
- # find_button(:name => "btnSubmit")
117
- # find_button(:name => "btnSubmit", :value => /Lucky/) - finds a button named btnSubmit with a value matching /Lucky/
118
- def find_button(identifier)
119
- identifier = make_identifier(identifier, [:value, :name])
120
- find_in_collection(@form.buttons, identifier) ||
121
- report_error("Tried to find button identified by #{identifier.inspect}, but failed. Buttons on selected form are: #{@form.buttons.map{|f| f.name} * ','}")
122
- end
123
-
124
- # the magic method that powers find_button, find_field. Does not throw an error if not found
125
- def find_in_collection(collection, identifier, via = :find)
126
- return collection.first if identifier == :first
127
- find_all_in_collection(collection, identifier, :find)
128
- end
129
-
130
- def find_all_in_collection(collection, identifier, via = :select)
131
- return [collection.first] if identifier == :first
132
- collection.send(via) do |item|
133
- identifier.all? { |k, criteria| is_a_match?(criteria, item.send(k)) }
134
- end
135
- end
136
-
137
- # sets a form-field's value by identifier. Throw's error if field does not exist
138
- def set_form_value(identifier, value)
139
- field = find_field(identifier)
140
- case field
141
- when WWW::Mechanize::Form::CheckBox
142
- field.checked = value
143
- when WWW::Mechanize::Form::RadioButton
144
- radio_collection = find_all_in_collection(@form.radiobuttons, :name => field.name)
145
- radio_collection.each { |f|; f.checked = false }
146
- finder = (value.is_a?(Hash) || value.is_a?(Symbol)) ? value : {:value => value}
147
- find_in_collection(radio_collection, finder).checked = true
148
- when WWW::Mechanize::Form::SelectList
149
- if value.is_a?(Hash) || value.is_a?(Symbol)
150
- field.value = find_in_collection(field.options, value).value
151
- else
152
- field.value = value
153
- end
154
- else
155
- field.value = value
156
- end
157
- end
158
-
159
- def set_form_values(set_pairs = {})
160
- flattened_value_hash(set_pairs).each do |identifier, value|
161
- set_form_value(identifier, value)
162
- end
163
- end
164
-
165
- def flattened_value_hash(hash, parents = [])
166
- new_hash = {}
167
- hash.each do |key, value|
168
- if value.is_a?(Hash) && value.keys.first.is_a?(String)
169
- new_hash.update(flattened_value_hash(value, [key] + parents))
170
- else
171
- parents.each { |parent| key = "#{parent}[#{key}]"}
172
- new_hash[key] = value
173
- end
174
- end
175
- new_hash
176
- end
177
-
178
- # sets a form-field's value by identifier. Throw's error if field does not exist
179
- def get_form_value(identifier)
180
- field = find_field(identifier)
181
- case field
182
- when WWW::Mechanize::Form::CheckBox
183
- field.checked
184
- else
185
- field.value
186
- end
187
- end
188
-
189
- def format_error(msg)
190
- error = "Error encountered: #{msg}."
191
- begin
192
- error << "\n\nPage URL:#{@page.uri.to_s}" if @page
193
- rescue
194
- end
195
- error
196
- end
197
-
198
- def report_error(msg)
199
- raise WebsickleException, format_error(msg)
200
- nil
201
- end
202
-
203
- private
204
- def set_page(p)
205
- @form = nil
206
- @page = p
207
- end
208
-
209
- def is_a_match?(criteria, value)
210
- case criteria
211
- when Regexp
212
- criteria.match(value)
213
- when String
214
- criteria == value
215
- when Array
216
- criteria.include?(value)
217
- else
218
- criteria.to_s == value.to_s
219
- end
220
- end
221
-
222
- def new_mechanize_agent
223
- a = WWW::Mechanize.new
224
- a.read_timeout = 600 # 10 minutes
225
- a
226
- end
227
- end
@@ -1,137 +0,0 @@
1
- require File.dirname(__FILE__) + '/../../spec_helper'
2
-
3
- describe WebSickle::Helpers::TableReader do
4
- describe "Simple example" do
5
- before(:each) do
6
- @content = <<-EOF
7
- <table>
8
- <tr>
9
- <th>Name</th>
10
- <th>Age</th>
11
- </tr>
12
- <tr>
13
- <td>Googly</td>
14
- <td>2</td>
15
- </tr>
16
- </table>
17
- EOF
18
- h = Hpricot(@content)
19
- @table = WebSickle::Helpers::TableReader.new(h / "table")
20
- end
21
-
22
- it "should extract headers" do
23
- @table.headers.should == ["Name", "Age"]
24
- end
25
-
26
- it "should extract rows" do
27
- @table.rows.should == [
28
- {"Name" => "Googly", "Age" => "2"}
29
- ]
30
- end
31
- end
32
-
33
-
34
-
35
- describe "Targetted example" do
36
- before(:each) do
37
- @content = <<-EOF
38
- <table>
39
- <thead>
40
- <tr>
41
- <td colspan='2'>----</td>
42
- </tr>
43
- <tr>
44
- <th><b>Name</b></th>
45
- <th><b>Age</b></th>
46
- </tr>
47
- </thead>
48
- <tbody>
49
- <tr>
50
- <td>Googly</td>
51
- <td>2</td>
52
- </tr>
53
- <tr>
54
- <td>Bear</td>
55
- <td>3</td>
56
- </tr>
57
- <tr>
58
- <td colspan='2'>Totals!</td>
59
- </tr>
60
- <tr>
61
- <td>---</td>
62
- <td>5</td>
63
- </tr>
64
- </tbody>
65
- </table>
66
- EOF
67
- h = Hpricot(@content)
68
- @table = WebSickle::Helpers::TableReader.new(h / " > table",
69
- :header_selector => " > th > b",
70
- :header_offset => 1,
71
- :body_range => 2..-3
72
- )
73
- end
74
-
75
- it "should extract the column headers" do
76
- @table.headers.should == ["Name", "Age"]
77
- end
78
-
79
- it "should extract the row data for the specified range" do
80
- @table.rows.should == [
81
- {"Name" => "Googly", "Age" => "2"},
82
- {"Name" => "Bear", "Age" => "3"},
83
- ]
84
- end
85
-
86
- it "should allow you to check extra rows to assert you didn't chop off too much" do
87
- (@table.extra_rows.first / "td").inner_text.should == "Totals!"
88
- end
89
- end
90
-
91
-
92
-
93
- describe "when using procs to extract data" do
94
- before(:each) do
95
- @content = <<-EOF
96
- <table>
97
- <tr>
98
- <th>Name</th>
99
- <th>Age</th>
100
- </tr>
101
- <tr>
102
- <td>Googly</td>
103
- <td>2</td>
104
- </tr>
105
- <tr>
106
- <td>Bear</td>
107
- <td>3</td>
108
- </tr>
109
- </table>
110
- EOF
111
- h = Hpricot(@content)
112
- @table = WebSickle::Helpers::TableReader.new(h / " > table",
113
- :header_proc => lambda {|th| th.inner_text.downcase.to_sym},
114
- :body_proc => lambda {|col_name, td|
115
- value = td.inner_text
116
- case col_name
117
- when :name
118
- value.upcase
119
- when :age
120
- value.to_i
121
- end
122
- }
123
- )
124
- end
125
-
126
- it "should use the header proc to extract column headers" do
127
- @table.headers.should == [:name, :age]
128
- end
129
-
130
- it "should use the body proc to format the data" do
131
- @table.rows.should == [
132
- {:name => "GOOGLY", :age => 2},
133
- {:name => "BEAR", :age => 3}
134
- ]
135
- end
136
- end
137
- end
@@ -1,7 +0,0 @@
1
- require File.dirname(__FILE__) + '/../init.rb'
2
- require 'rubygems'
3
- require 'hpricot'
4
- require 'test/unit'
5
- require 'spec'
6
- require 'active_support'
7
- require File.dirname(__FILE__) + '/spec_helpers/mechanize_mock_helper.rb'
@@ -1,12 +0,0 @@
1
- module MechanizeMockHelper
2
- def fixture_file(filename)
3
- File.read("#{File.dirname(__FILE__)}/../fixtures/#{filename}")
4
- end
5
-
6
- def mechanize_page(path_to_data, options = {})
7
- options[:uri] ||= URI.parse("http://url.com/#{path_to_data}")
8
- options[:response] ||= {'content-type' => 'text/html'}
9
-
10
- WWW::Mechanize::Page.new(options[:uri], options[:response], fixture_file("/#{path_to_data}"))
11
- end
12
- end
@@ -1,50 +0,0 @@
1
- require File.dirname(__FILE__) + '/spec_helper'
2
-
3
- class WebSickleHelper
4
- include WebSickle
5
- end
6
-
7
- describe WebSickle do
8
- include MechanizeMockHelper
9
-
10
- before(:all) do
11
- WebSickleHelper.protected_instance_methods.each do |method|
12
- WebSickleHelper.send(:public, method)
13
- end
14
- end
15
-
16
- before(:each) do
17
- @helper = WebSickleHelper.new
18
- end
19
-
20
- it "should flatten a value hash" do
21
- @helper.flattened_value_hash("contact" => {"first_name" => "bob"}).should == {"contact[first_name]" => "bob"}
22
- end
23
-
24
- describe "clicking links" do
25
- before(:each) do
26
- @helper.stub!(:page).and_return(mechanize_page("linkies.html"))
27
- end
28
-
29
- it "should click a link by matching the link text" do
30
- @helper.agent.should_receive(:click) do |link|
31
- link.text.should include("one")
32
- end
33
- @helper.click_link(:text => /one/)
34
- end
35
-
36
- it "should click a link by matching the link href" do
37
- @helper.agent.should_receive(:click) do |link|
38
- link.href.should include("/two")
39
- end
40
- @helper.click_link(:href => %r{/two})
41
- end
42
-
43
- it "should default matching the link text" do
44
- @helper.agent.should_receive(:click) do |link|
45
- link.text.should include("Link number one")
46
- end
47
- @helper.click_link("Link number one")
48
- end
49
- end
50
- end
@@ -1,40 +0,0 @@
1
- require 'webrat'
2
- require 'webrat/mechanize'
3
-
4
- module WebSickleWebratAdapter
5
-
6
- def open_page(url)
7
- session.visit(url)
8
- end
9
-
10
- def click_link(options)
11
- raise "This adapter only works with the :text option!" unless options[:text]
12
- session.click_link(options[:text])
13
- end
14
-
15
- def submit_form_with_options(options_hash)
16
- action = options_hash[:identified_by][:action]
17
- raise "You must provide an action!" unless action
18
- action_regexp = action.is_a?(Regexp) ? action : Regexp.new("#{action}$")
19
- form = page.forms.detect {|f| f.action =~ action_regexp }
20
- raise "Could not find form with matching action: #{action_regexp}" unless form
21
- method = options_hash[:method] || 'post'
22
- session.request_page(form.action, method, options_hash[:values])
23
- end
24
-
25
- def page
26
- session.response
27
- end
28
-
29
- # def visit(url)
30
- # session.visit(url)
31
- # end
32
-
33
- private
34
-
35
- def session
36
- @session ||= Webrat::MechanizeSession.new
37
- end
38
-
39
-
40
- end