honkster-webrat 0.6.0.10 → 0.7.1.1

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 (53) hide show
  1. data/Gemfile +0 -6
  2. data/History.txt +34 -0
  3. data/Rakefile +7 -8
  4. data/Thorfile +1 -0
  5. data/honkster-webrat.gemspec +9 -5
  6. data/lib/webrat.rb +1 -1
  7. data/lib/webrat/adapters/mechanize.rb +22 -6
  8. data/lib/webrat/adapters/rack.rb +4 -0
  9. data/lib/webrat/adapters/rails.rb +4 -8
  10. data/lib/webrat/core/configuration.rb +23 -4
  11. data/lib/webrat/core/elements/field.rb +40 -89
  12. data/lib/webrat/core/elements/form.rb +55 -31
  13. data/lib/webrat/core/locators/form_locator.rb +1 -1
  14. data/lib/webrat/core/locators/select_option_locator.rb +1 -1
  15. data/lib/webrat/core/matchers/have_content.rb +1 -1
  16. data/lib/webrat/core/matchers/have_xpath.rb +4 -2
  17. data/lib/webrat/core/methods.rb +1 -1
  18. data/lib/webrat/core/mime.rb +2 -2
  19. data/lib/webrat/core/save_and_open_page.rb +3 -23
  20. data/lib/webrat/core/scope.rb +1 -0
  21. data/lib/webrat/core/session.rb +4 -7
  22. data/lib/webrat/core_extensions/{nil_to_param.rb → nil_to_query_string.rb} +1 -1
  23. data/lib/webrat/selenium/location_strategy_javascript/label.js +8 -2
  24. data/lib/webrat/selenium/matchers/have_content.rb +22 -10
  25. data/lib/webrat/selenium/matchers/have_selector.rb +8 -0
  26. data/lib/webrat/selenium/matchers/have_xpath.rb +8 -0
  27. data/lib/webrat/selenium/selenium_rc_server.rb +5 -2
  28. data/lib/webrat/selenium/selenium_session.rb +12 -12
  29. data/spec/fakes/test_adapter.rb +1 -5
  30. data/spec/integration/mechanize/sample_app.rb +16 -1
  31. data/spec/integration/mechanize/spec/mechanize_spec.rb +9 -1
  32. data/spec/integration/rack/app.rb +2 -2
  33. data/spec/integration/rack/test/helper.rb +0 -1
  34. data/spec/integration/rack/test/webrat_rack_test.rb +3 -2
  35. data/spec/integration/sinatra/classic_app.rb +0 -1
  36. data/spec/integration/sinatra/modular_app.rb +0 -1
  37. data/spec/integration/sinatra/test/classic_app_test.rb +1 -0
  38. data/spec/integration/sinatra/test/test_helper.rb +0 -1
  39. data/spec/private/core/field_spec.rb +1 -1
  40. data/spec/private/core/form_spec.rb +51 -0
  41. data/spec/private/core/session_spec.rb +5 -23
  42. data/spec/private/mechanize/mechanize_adapter_spec.rb +24 -1
  43. data/spec/private/rails/attaches_file_spec.rb +33 -0
  44. data/spec/private/rails/rails_adapter_spec.rb +0 -7
  45. data/spec/public/matchers/contain_spec.rb +8 -15
  46. data/spec/public/matchers/have_xpath_spec.rb +6 -0
  47. data/spec/public/save_and_open_spec.rb +4 -25
  48. data/spec/public/select_spec.rb +19 -0
  49. data/spec/public/submit_form_spec.rb +52 -1
  50. data/spec/spec_helper.rb +0 -1
  51. data/vendor/selenium-server.jar +0 -0
  52. metadata +56 -15
  53. data/pkg/honkster-webrat-0.6.0.9.gem +0 -0
@@ -38,15 +38,24 @@ module Webrat
38
38
  end
39
39
  end
40
40
 
41
+ # iterate over all form fields to build a request querystring to get params from it,
42
+ # for file_field we made a work around to pass a digest as value to later replace it
43
+ # in params hash with the real file.
41
44
  def params
42
- all_params = {}
45
+ query_string = []
46
+ replaces = {}
43
47
 
44
48
  fields.each do |field|
45
- next if field.to_param.nil?
46
- merge(all_params, field.to_param)
49
+ next if field.to_query_string.nil?
50
+ replaces.merge!({field.digest_value => field.test_uploaded_file}) if field.is_a?(FileField)
51
+ query_string << field.to_query_string
47
52
  end
48
53
 
49
- all_params
54
+ query_params = self.class.query_string_to_params(query_string.join('&'))
55
+
56
+ query_params = self.class.replace_params_values(query_params, replaces)
57
+
58
+ self.class.unescape_params(query_params)
50
59
  end
51
60
 
52
61
  def form_method
@@ -57,47 +66,62 @@ module Webrat
57
66
  @element["action"].blank? ? @session.current_url : @element["action"]
58
67
  end
59
68
 
60
- def merge(all_params, new_param)
61
- new_param.each do |key, value|
62
- case all_params[key]
63
- when *hash_classes
64
- merge_hash_values(all_params[key], value)
69
+ def self.replace_param_value(params, oval, nval)
70
+ output = Hash.new
71
+ params.each do |key, value|
72
+ case value
73
+ when Hash
74
+ value = replace_param_value(value, oval, nval)
65
75
  when Array
66
- all_params[key] += value
67
- else
68
- all_params[key] = value
76
+ value = value.map { |o| o == oval ? nval : ( o.is_a?(Hash) ? replace_param_value(o, oval, nval) : o) }
77
+ when oval
78
+ value = nval
69
79
  end
80
+ output[key] = value
70
81
  end
82
+ output
71
83
  end
72
84
 
73
- def merge_hash_values(a, b) # :nodoc:
74
- a.keys.each do |k|
75
- if b.has_key?(k)
76
- case [a[k], b[k]].map{|value| value.class}
77
- when *hash_classes.zip(hash_classes)
78
- a[k] = merge_hash_values(a[k], b[k])
79
- b.delete(k)
80
- when [Array, Array]
81
- a[k] += b[k]
82
- b.delete(k)
83
- end
84
- end
85
+ def self.replace_params_values(params, values)
86
+ values.each do |key, value|
87
+ params = replace_param_value(params, key, value)
85
88
  end
86
- a.merge!(b)
89
+ params
87
90
  end
88
91
 
89
- def hash_classes
90
- klasses = [Hash]
92
+ def self.unescape_params(params)
93
+ case params.class.name
94
+ when 'Hash', 'Mash'
95
+ params.each { |key,value| params[key] = unescape_params(value) }
96
+ params
97
+ when 'Array'
98
+ params.collect { |value| unescape_params(value) }
99
+ else
100
+ params.is_a?(String) ? CGI.unescapeHTML(params) : params
101
+ end
102
+ end
91
103
 
104
+ def self.query_string_to_params(query_string)
92
105
  case Webrat.configuration.mode
93
106
  when :rails
94
- klasses << HashWithIndifferentAccess
107
+ parse_rails_request_params(query_string)
95
108
  when :merb
96
- klasses << Mash
109
+ ::Merb::Parse.query(query_string)
110
+ when :rack, :sinatra
111
+ Rack::Utils.parse_nested_query(query_string)
112
+ else
113
+ query_string.split('&').map {|query| { query.split('=').first => query.split('=').last }}
97
114
  end
98
-
99
- klasses
100
115
  end
101
116
 
117
+ def self.parse_rails_request_params(query_string)
118
+ if defined?(ActionController::AbstractRequest)
119
+ ActionController::AbstractRequest.parse_query_parameters(query_string)
120
+ elsif defined?(ActionController::UrlEncodedPairParser)
121
+ ActionController::UrlEncodedPairParser.parse_query_parameters(query_string)
122
+ else
123
+ Rack::Utils.parse_nested_query(query_string)
124
+ end
125
+ end
102
126
  end
103
127
  end
@@ -10,7 +10,7 @@ module Webrat
10
10
  end
11
11
 
12
12
  def form_element
13
- @dom.css("#" + @value).first
13
+ @dom.css("#" + @value).first || @dom.css(@value).first
14
14
  end
15
15
 
16
16
  end
@@ -15,7 +15,7 @@ module Webrat
15
15
 
16
16
  def locate
17
17
  if @id_or_name_or_label
18
- field = FieldLocator.new(@session, @dom, @id_or_name_or_label, SelectField).locate!
18
+ field = FieldLocator.new(@session, @dom, @id_or_name_or_label, SelectField, MultipleSelectField).locate!
19
19
 
20
20
  field.options.detect do |o|
21
21
  if @option_text.is_a?(Regexp)
@@ -12,7 +12,7 @@ module Webrat
12
12
 
13
13
  case @content
14
14
  when String
15
- @element.include?(@content)
15
+ @element.gsub(/\s+/, ' ').include?(@content)
16
16
  when Regexp
17
17
  @element.match(@content)
18
18
  end
@@ -14,10 +14,12 @@ module Webrat
14
14
  @block ||= block
15
15
  matched = matches(stringlike)
16
16
 
17
+ @block.call(matched) if @block
18
+
17
19
  if @options[:count]
18
- matched.size == @options[:count].to_i && (!@block || @block.call(matched))
20
+ matched.size == @options[:count].to_i
19
21
  else
20
- matched.any? && (!@block || @block.call(matched))
22
+ matched.any?
21
23
  end
22
24
  end
23
25
 
@@ -3,7 +3,7 @@ module Webrat
3
3
 
4
4
  def self.delegate_to_session(*meths)
5
5
  meths.each do |meth|
6
- self.class_eval <<-RUBY
6
+ self.class_eval(<<-RUBY, __FILE__, __LINE__)
7
7
  def #{meth}(*args, &blk)
8
8
  webrat_session.#{meth}(*args, &blk)
9
9
  end
@@ -8,8 +8,8 @@ module Webrat #:nodoc:
8
8
  def mime_type(type)
9
9
  return type if type.nil? || type.to_s.include?("/")
10
10
  type = ".#{type}" unless type.to_s[0] == ?.
11
- MIME_TYPES.fetch(type) { |type|
12
- raise ArgumentError.new("Invalid Mime type: #{type}")
11
+ MIME_TYPES.fetch(type) { |invalid_type|
12
+ raise ArgumentError.new("Invalid Mime type: #{invalid_type}")
13
13
  }
14
14
  end
15
15
 
@@ -6,12 +6,12 @@ module Webrat
6
6
  # Example:
7
7
  # save_and_open_page
8
8
  def save_and_open_page
9
- return unless File.exist?(saved_page_dir)
9
+ return unless File.exist?(Webrat.configuration.saved_pages_dir)
10
10
 
11
- filename = "#{saved_page_dir}/webrat-#{Time.now.to_i}.html"
11
+ filename = "#{Webrat.configuration.saved_pages_dir}/webrat-#{Time.now.to_i}.html"
12
12
 
13
13
  File.open(filename, "w") do |f|
14
- f.write rewrite_css_and_image_references(response_body)
14
+ f.write response_body
15
15
  end
16
16
 
17
17
  open_in_browser(filename)
@@ -24,25 +24,5 @@ module Webrat
24
24
  warn "Sorry, you need to install launchy to open pages: `gem install launchy`"
25
25
  end
26
26
 
27
- def rewrite_css_and_image_references(response_html) # :nodoc:
28
- return response_html unless doc_root
29
- response_html.gsub(/("|')\/(stylesheets|images)/, '\1' + doc_root + '/\2')
30
- end
31
-
32
- def saved_page_dir #:nodoc:
33
- File.expand_path(".")
34
- end
35
-
36
- def doc_root #:nodoc:
37
- nil
38
- end
39
-
40
- private
41
-
42
- # accessor for testing
43
- def ruby_platform
44
- RUBY_PLATFORM
45
- end
46
-
47
27
  end
48
28
  end
@@ -28,6 +28,7 @@ module Webrat
28
28
  attr_reader :session
29
29
 
30
30
  def initialize(session, &block) #:nodoc:
31
+ @selector, @dom = nil
31
32
  @session = session
32
33
  instance_eval(&block) if block_given?
33
34
 
@@ -65,7 +65,7 @@ For example:
65
65
  attr_reader :current_url
66
66
  attr_reader :elements
67
67
 
68
- def_delegators :@adapter, :response, :response_code, :response_body,
68
+ def_delegators :@adapter, :response, :response_code, :response_body, :response_headers,
69
69
  :response_body=, :response_code=,
70
70
  :get, :post, :put, :delete
71
71
 
@@ -75,6 +75,7 @@ For example:
75
75
  @data = {}
76
76
  @default_headers = {}
77
77
  @custom_headers = {}
78
+ @current_url = nil
78
79
  reset
79
80
  end
80
81
 
@@ -92,10 +93,6 @@ For example:
92
93
  page
93
94
  end
94
95
 
95
- def doc_root #:nodoc:
96
- nil
97
- end
98
-
99
96
  def header(key, value)
100
97
  @custom_headers[key] = value
101
98
  end
@@ -159,7 +156,7 @@ For example:
159
156
  end
160
157
 
161
158
  def redirect? #:nodoc:
162
- (response_code / 100).to_i == 3
159
+ [301, 302, 303, 307].include?(response_code)
163
160
  end
164
161
 
165
162
  def internal_redirect?
@@ -286,7 +283,7 @@ For example:
286
283
  end
287
284
 
288
285
  def response_location
289
- response.headers["Location"]
286
+ response_headers['Location']
290
287
  end
291
288
 
292
289
  def current_host
@@ -1,5 +1,5 @@
1
1
  class NilClass #:nodoc:
2
- def to_param
2
+ def to_query_string
3
3
  nil
4
4
  end
5
5
  end
@@ -10,7 +10,7 @@ RegExp.escape = function(text) {
10
10
  );
11
11
  }
12
12
  return text.replace(arguments.callee.sRE, '\\$1');
13
- }
13
+ };
14
14
 
15
15
  var allLabels = inDocument.getElementsByTagName("label");
16
16
  var regExp = new RegExp('^\\W*' + RegExp.escape(locator) + '(\\b|$)', 'i');
@@ -30,7 +30,13 @@ candidateLabels = candidateLabels.sortBy(function(s) {
30
30
  });
31
31
 
32
32
  var locatedLabel = candidateLabels.first();
33
- var labelFor = locatedLabel.getAttribute('for');
33
+ var labelFor = null;
34
+
35
+ if (locatedLabel.getAttribute('for')) {
36
+ labelFor = locatedLabel.getAttribute('for');
37
+ } else if (locatedLabel.attributes['for']) { // IE
38
+ labelFor = locatedLabel.attributes['for'].nodeValue;
39
+ }
34
40
 
35
41
  if ((labelFor == null) && (locatedLabel.hasChildNodes())) {
36
42
  return locatedLabel.getElementsByTagName('button')[0]
@@ -7,29 +7,33 @@ module Webrat
7
7
  end
8
8
 
9
9
  def matches?(response)
10
- if @content.is_a?(Regexp)
11
- text_finder = "regexp:#{@content.source}"
12
- else
13
- text_finder = @content
10
+ response.session.wait_for do
11
+ response.selenium.is_text_present(text_finder)
14
12
  end
13
+ rescue Webrat::TimeoutError => e
14
+ @error_message = e.message
15
+ false
16
+ end
15
17
 
18
+ def does_not_match?(response)
16
19
  response.session.wait_for do
17
- response.selenium.is_text_present(text_finder)
20
+ !response.selenium.is_text_present(text_finder)
18
21
  end
19
- rescue Webrat::TimeoutError
20
- false
22
+ rescue Webrat::TimeoutError => e
23
+ @error_message = e.message
24
+ false
21
25
  end
22
26
 
23
27
  # ==== Returns
24
28
  # String:: The failure message.
25
29
  def failure_message
26
- "expected the following element's content to #{content_message}:\n#{@element}"
30
+ "expected the response to #{content_message}:\n#{@error_message}"
27
31
  end
28
32
 
29
33
  # ==== Returns
30
34
  # String:: The failure message to be displayed in negative matches.
31
35
  def negative_failure_message
32
- "expected the following element's content to not #{content_message}:\n#{@element}"
36
+ "expected the response to not #{content_message}"
33
37
  end
34
38
 
35
39
  def content_message
@@ -40,6 +44,14 @@ module Webrat
40
44
  "match #{@content.inspect}"
41
45
  end
42
46
  end
47
+
48
+ def text_finder
49
+ if @content.is_a?(Regexp)
50
+ "regexp:#{@content.source}"
51
+ else
52
+ @content
53
+ end
54
+ end
43
55
  end
44
56
 
45
57
  # Matches the contents of an HTML document with
@@ -52,7 +64,7 @@ module Webrat
52
64
  # the supplied string or regexp
53
65
  def assert_contain(content)
54
66
  hc = HasContent.new(content)
55
- assert hc.matches?(response), hc.failure_message
67
+ assert hc.matches?(response), hc.failure_message
56
68
  end
57
69
 
58
70
  # Asserts that the body of the response
@@ -14,6 +14,14 @@ module Webrat
14
14
  false
15
15
  end
16
16
 
17
+ def does_not_match?(response)
18
+ response.session.wait_for do
19
+ !response.selenium.is_element_present("css=#{@expected}")
20
+ end
21
+ rescue Webrat::TimeoutError
22
+ false
23
+ end
24
+
17
25
  # ==== Returns
18
26
  # String:: The failure message.
19
27
  def failure_message
@@ -14,6 +14,14 @@ module Webrat
14
14
  false
15
15
  end
16
16
 
17
+ def does_not_match?(response)
18
+ response.session.wait_for do
19
+ !response.selenium.is_element_present("xpath=#{@expected}")
20
+ end
21
+ rescue Webrat::TimeoutError
22
+ false
23
+ end
24
+
17
25
  # ==== Returns
18
26
  # String:: The failure message.
19
27
  def failure_message
@@ -31,10 +31,13 @@ module Webrat
31
31
 
32
32
  def remote_control
33
33
  return @remote_control if @remote_control
34
+ server_options = { :timeout => Webrat.configuration.selenium_browser_startup_timeout }
35
+ server_options[:firefox_profile] = Webrat.configuration.selenium_firefox_profile if Webrat.configuration.selenium_firefox_profile
34
36
 
35
37
  @remote_control = ::Selenium::RemoteControl::RemoteControl.new("0.0.0.0",
36
38
  Webrat.configuration.selenium_server_port,
37
- :timeout => Webrat.configuration.selenium_browser_startup_timeout)
39
+ server_options)
40
+
38
41
  @remote_control.jar_file = jar_path
39
42
 
40
43
  return @remote_control
@@ -61,7 +64,7 @@ module Webrat
61
64
  TCPSocket.wait_for_service_with_timeout \
62
65
  :host => (Webrat.configuration.selenium_server_address || "0.0.0.0"),
63
66
  :port => Webrat.configuration.selenium_server_port,
64
- :timeout => 15 # seconds
67
+ :timeout => 45 # seconds
65
68
  end
66
69
  end
67
70
 
@@ -3,7 +3,12 @@ require "webrat/selenium/selenium_rc_server"
3
3
  require "webrat/selenium/application_server_factory"
4
4
  require "webrat/selenium/application_servers/base"
5
5
 
6
- require "selenium"
6
+ begin
7
+ require "selenium"
8
+ rescue LoadError => e
9
+ e.message << " (You may need to install the selenium-rc gem)"
10
+ raise e
11
+ end
7
12
 
8
13
  module Webrat
9
14
  class TimeoutError < WebratError
@@ -175,8 +180,8 @@ module Webrat
175
180
  end
176
181
 
177
182
  error_message = "#{message} (after #{timeout} sec)"
178
-
179
- if $browser
183
+
184
+ if $browser && Webrat.configuration.selenium_verbose_output
180
185
  error_message += <<-EOS
181
186
 
182
187
 
@@ -200,9 +205,9 @@ HTML of the page was:
200
205
 
201
206
 
202
207
  def save_and_open_screengrab
203
- return unless File.exist?(saved_page_dir)
208
+ return unless File.exist?(Webrat.configuration.saved_pages_dir)
204
209
 
205
- filename = "#{saved_page_dir}/webrat-#{Time.now.to_i}.png"
210
+ filename = "#{Webrat.configuration.saved_pages_dir}/webrat-#{Time.now.to_i}.png"
206
211
 
207
212
  if $browser.chrome_backend?
208
213
  $browser.capture_entire_page_screenshot(filename, '')
@@ -236,13 +241,8 @@ HTML of the page was:
236
241
 
237
242
 
238
243
  def create_browser
239
- $browser = ::Selenium::Client::Driver.new(
240
- Webrat.configuration.selenium_server_address || "localhost",
241
- Webrat.configuration.selenium_server_port,
242
- Webrat.configuration.selenium_browser_key,
243
- "http://#{Webrat.configuration.application_address}:#{Webrat.configuration.application_port}",
244
- Webrat.configuration.default_timeout_in_seconds || 10
245
- )
244
+ $browser = ::Selenium::Client::Driver.new(Webrat.configuration.selenium_server_address || "localhost",
245
+ Webrat.configuration.selenium_server_port, Webrat.configuration.selenium_browser_key, "http://#{Webrat.configuration.application_address}:#{Webrat.configuration.application_port_for_selenium}")
246
246
  $browser.set_speed(0) unless Webrat.configuration.selenium_server_address
247
247
 
248
248
  at_exit do