honkster-webrat 0.6.0.10 → 0.7.1.1

Sign up to get free protection for your applications and to get access to all the features.
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