aslakhellesoy-webrat 0.3.2.2 → 0.4.4.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 (70) hide show
  1. data/History.txt +158 -19
  2. data/Rakefile +36 -11
  3. data/lib/webrat.rb +8 -11
  4. data/lib/webrat/core/configuration.rb +67 -25
  5. data/lib/webrat/core/elements/area.rb +7 -7
  6. data/lib/webrat/core/elements/element.rb +11 -11
  7. data/lib/webrat/core/elements/field.rb +70 -51
  8. data/lib/webrat/core/elements/form.rb +17 -17
  9. data/lib/webrat/core/elements/label.rb +8 -8
  10. data/lib/webrat/core/elements/link.rb +13 -11
  11. data/lib/webrat/core/elements/select_option.rb +9 -9
  12. data/lib/webrat/core/locators.rb +2 -2
  13. data/lib/webrat/core/locators/area_locator.rb +10 -10
  14. data/lib/webrat/core/locators/button_locator.rb +13 -13
  15. data/lib/webrat/core/locators/field_by_id_locator.rb +8 -8
  16. data/lib/webrat/core/locators/field_labeled_locator.rb +19 -13
  17. data/lib/webrat/core/locators/field_locator.rb +7 -7
  18. data/lib/webrat/core/locators/field_named_locator.rb +10 -10
  19. data/lib/webrat/core/locators/form_locator.rb +6 -6
  20. data/lib/webrat/core/locators/label_locator.rb +9 -9
  21. data/lib/webrat/core/locators/link_locator.rb +12 -12
  22. data/lib/webrat/core/locators/locator.rb +5 -5
  23. data/lib/webrat/core/locators/select_option_locator.rb +11 -11
  24. data/lib/webrat/core/logging.rb +7 -4
  25. data/lib/webrat/core/matchers/have_content.rb +19 -15
  26. data/lib/webrat/core/matchers/have_selector.rb +44 -22
  27. data/lib/webrat/core/matchers/have_tag.rb +11 -61
  28. data/lib/webrat/core/matchers/have_xpath.rb +89 -35
  29. data/lib/webrat/core/methods.rb +13 -11
  30. data/lib/webrat/core/mime.rb +3 -3
  31. data/lib/webrat/core/save_and_open_page.rb +9 -9
  32. data/lib/webrat/core/scope.rb +82 -62
  33. data/lib/webrat/core/session.rb +61 -18
  34. data/lib/webrat/core/xml.rb +16 -16
  35. data/lib/webrat/core/xml/hpricot.rb +3 -3
  36. data/lib/webrat/core/xml/nokogiri.rb +14 -14
  37. data/lib/webrat/core/xml/rexml.rb +3 -3
  38. data/lib/webrat/core_extensions/blank.rb +1 -1
  39. data/lib/webrat/core_extensions/deprecate.rb +1 -1
  40. data/lib/webrat/core_extensions/detect_mapped.rb +4 -4
  41. data/lib/webrat/core_extensions/meta_class.rb +1 -1
  42. data/lib/webrat/core_extensions/tcp_socket.rb +27 -0
  43. data/lib/webrat/mechanize.rb +9 -9
  44. data/lib/webrat/merb.rb +5 -61
  45. data/lib/webrat/merb_session.rb +67 -0
  46. data/lib/webrat/rack.rb +45 -14
  47. data/lib/webrat/rails.rb +31 -11
  48. data/lib/webrat/rspec-rails.rb +2 -2
  49. data/lib/webrat/selenium.rb +27 -39
  50. data/lib/webrat/selenium/application_server_factory.rb +40 -0
  51. data/lib/webrat/selenium/application_servers.rb +5 -0
  52. data/lib/webrat/selenium/application_servers/base.rb +44 -0
  53. data/lib/webrat/selenium/application_servers/external.rb +24 -0
  54. data/lib/webrat/selenium/application_servers/merb.rb +48 -0
  55. data/lib/webrat/selenium/application_servers/rails.rb +42 -0
  56. data/lib/webrat/selenium/application_servers/sinatra.rb +35 -0
  57. data/lib/webrat/selenium/location_strategy_javascript/button.js +14 -7
  58. data/lib/webrat/selenium/location_strategy_javascript/label.js +1 -2
  59. data/lib/webrat/selenium/location_strategy_javascript/webratlink.js +4 -1
  60. data/lib/webrat/selenium/matchers.rb +4 -108
  61. data/lib/webrat/selenium/matchers/have_content.rb +66 -0
  62. data/lib/webrat/selenium/matchers/have_selector.rb +49 -0
  63. data/lib/webrat/selenium/matchers/have_tag.rb +72 -0
  64. data/lib/webrat/selenium/matchers/have_xpath.rb +45 -0
  65. data/lib/webrat/selenium/selenium_rc_server.rb +84 -0
  66. data/lib/webrat/selenium/selenium_session.rb +86 -68
  67. data/lib/webrat/selenium/silence_stream.rb +18 -0
  68. metadata +21 -16
  69. data/lib/webrat/core_extensions/hash_with_indifferent_access.rb +0 -131
  70. data/lib/webrat/sinatra.rb +0 -29
@@ -0,0 +1,49 @@
1
+ module Webrat
2
+ module Selenium
3
+ module Matchers
4
+ class HaveSelector
5
+ def initialize(expected)
6
+ @expected = expected
7
+ end
8
+
9
+ def matches?(response)
10
+ response.session.wait_for do
11
+ response.selenium.is_element_present("css=#{@expected}")
12
+ end
13
+ rescue Webrat::TimeoutError
14
+ false
15
+ end
16
+
17
+ # ==== Returns
18
+ # String:: The failure message.
19
+ def failure_message
20
+ "expected following text to match selector #{@expected}:\n#{@document}"
21
+ end
22
+
23
+ # ==== Returns
24
+ # String:: The failure message to be displayed in negative matches.
25
+ def negative_failure_message
26
+ "expected following text to not match selector #{@expected}:\n#{@document}"
27
+ end
28
+ end
29
+
30
+ def have_selector(content)
31
+ HaveSelector.new(content)
32
+ end
33
+
34
+ # Asserts that the body of the response contains
35
+ # the supplied selector
36
+ def assert_have_selector(expected)
37
+ hs = HaveSelector.new(expected)
38
+ assert hs.matches?(response), hs.failure_message
39
+ end
40
+
41
+ # Asserts that the body of the response
42
+ # does not contain the supplied string or regepx
43
+ def assert_have_no_selector(expected)
44
+ hs = HaveSelector.new(expected)
45
+ assert !hs.matches?(response), hs.negative_failure_message
46
+ end
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,72 @@
1
+ module Webrat
2
+ module Selenium
3
+ module Matchers
4
+
5
+ class HaveTag < HaveSelector #:nodoc:
6
+ # ==== Returns
7
+ # String:: The failure message.
8
+ def failure_message
9
+ "expected following output to contain a #{tag_inspect} tag:\n#{@document}"
10
+ end
11
+
12
+ # ==== Returns
13
+ # String:: The failure message to be displayed in negative matches.
14
+ def negative_failure_message
15
+ "expected following output to omit a #{tag_inspect}:\n#{@document}"
16
+ end
17
+
18
+ def tag_inspect
19
+ options = @expected.last.dup
20
+ content = options.delete(:content)
21
+
22
+ html = "<#{@expected.first}"
23
+ options.each do |k,v|
24
+ html << " #{k}='#{v}'"
25
+ end
26
+
27
+ if content
28
+ html << ">#{content}</#{@expected.first}>"
29
+ else
30
+ html << "/>"
31
+ end
32
+
33
+ html
34
+ end
35
+
36
+ def query
37
+ options = @expected.last.dup
38
+ selector = @expected.first.to_s
39
+
40
+ selector << ":contains('#{options.delete(:content)}')" if options[:content]
41
+
42
+ options.each do |key, value|
43
+ selector << "[#{key}='#{value}']"
44
+ end
45
+
46
+ Nokogiri::CSS.parse(selector).map { |ast| ast.to_xpath }
47
+ end
48
+ end
49
+
50
+ def have_tag(name, attributes = {}, &block)
51
+ HaveTag.new([name, attributes], &block)
52
+ end
53
+
54
+ alias_method :match_tag, :have_tag
55
+
56
+ # Asserts that the body of the response contains
57
+ # the supplied tag with the associated selectors
58
+ def assert_have_tag(name, attributes = {})
59
+ ht = HaveTag.new([name, attributes])
60
+ assert ht.matches?(response), ht.failure_message
61
+ end
62
+
63
+ # Asserts that the body of the response
64
+ # does not contain the supplied string or regepx
65
+ def assert_have_no_tag(name, attributes = {})
66
+ ht = HaveTag.new([name, attributes])
67
+ assert !ht.matches?(response), ht.negative_failure_message
68
+ end
69
+
70
+ end
71
+ end
72
+ end
@@ -0,0 +1,45 @@
1
+ module Webrat
2
+ module Selenium
3
+ module Matchers
4
+ class HaveXpath
5
+ def initialize(expected)
6
+ @expected = expected
7
+ end
8
+
9
+ def matches?(response)
10
+ response.session.wait_for do
11
+ response.selenium.is_element_present("xpath=#{@expected}")
12
+ end
13
+ rescue Webrat::TimeoutError
14
+ false
15
+ end
16
+
17
+ # ==== Returns
18
+ # String:: The failure message.
19
+ def failure_message
20
+ "expected following text to match xpath #{@expected}:\n#{@document}"
21
+ end
22
+
23
+ # ==== Returns
24
+ # String:: The failure message to be displayed in negative matches.
25
+ def negative_failure_message
26
+ "expected following text to not match xpath #{@expected}:\n#{@document}"
27
+ end
28
+ end
29
+
30
+ def have_xpath(xpath)
31
+ HaveXpath.new(xpath)
32
+ end
33
+
34
+ def assert_have_xpath(expected)
35
+ hs = HaveXpath.new(expected)
36
+ assert hs.matches?(response), hs.failure_message
37
+ end
38
+
39
+ def assert_have_no_xpath(expected)
40
+ hs = HaveXpath.new(expected)
41
+ assert !hs.matches?(response), hs.negative_failure_message
42
+ end
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,84 @@
1
+ module Webrat
2
+ module Selenium
3
+
4
+ class SeleniumRCServer
5
+
6
+ include Webrat::Selenium::SilenceStream
7
+
8
+ def self.boot
9
+ new.boot
10
+ end
11
+
12
+ def boot
13
+ return if selenium_grid?
14
+
15
+ start
16
+ wait
17
+ stop_at_exit
18
+ end
19
+
20
+ def start
21
+ silence_stream(STDOUT) do
22
+ remote_control.start :background => true
23
+ end
24
+ end
25
+
26
+ def stop_at_exit
27
+ at_exit do
28
+ stop
29
+ end
30
+ end
31
+
32
+ def remote_control
33
+ return @remote_control if @remote_control
34
+
35
+ @remote_control = ::Selenium::RemoteControl::RemoteControl.new("0.0.0.0",
36
+ Webrat.configuration.selenium_server_port,
37
+ Webrat.configuration.selenium_browser_startup_timeout)
38
+ @remote_control.jar_file = jar_path
39
+
40
+ return @remote_control
41
+ end
42
+
43
+ def jar_path
44
+ File.expand_path(__FILE__ + "../../../../../vendor/selenium-server.jar")
45
+ end
46
+
47
+ def selenium_grid?
48
+ Webrat.configuration.selenium_server_address
49
+ end
50
+
51
+ def wait
52
+ $stderr.print "==> Waiting for Selenium RC server on port #{Webrat.configuration.selenium_server_port}... "
53
+ wait_for_socket
54
+ $stderr.print "Ready!\n"
55
+ rescue SocketError
56
+ fail
57
+ end
58
+
59
+ def wait_for_socket
60
+ silence_stream(STDOUT) do
61
+ TCPSocket.wait_for_service_with_timeout \
62
+ :host => (Webrat.configuration.selenium_server_address || "0.0.0.0"),
63
+ :port => Webrat.configuration.selenium_server_port,
64
+ :timeout => 15 # seconds
65
+ end
66
+ end
67
+
68
+ def fail
69
+ $stderr.puts
70
+ $stderr.puts
71
+ $stderr.puts "==> Failed to boot the Selenium RC server... exiting!"
72
+ exit
73
+ end
74
+
75
+ def stop
76
+ silence_stream(STDOUT) do
77
+ ::Selenium::RemoteControl::RemoteControl.new("0.0.0.0", Webrat.configuration.selenium_server_port, 5).stop
78
+ end
79
+ end
80
+
81
+ end
82
+
83
+ end
84
+ end
@@ -1,58 +1,66 @@
1
1
  require "webrat/core/save_and_open_page"
2
+ require "webrat/selenium/selenium_rc_server"
3
+ require "webrat/selenium/application_server_factory"
4
+ require "webrat/selenium/application_servers/base"
2
5
 
3
6
  module Webrat
4
7
  class TimeoutError < WebratError
5
8
  end
6
-
9
+
7
10
  class SeleniumResponse
8
11
  attr_reader :body
9
12
  attr_reader :session
10
-
13
+
11
14
  def initialize(session, body)
12
15
  @session = session
13
16
  @body = body
14
17
  end
15
-
18
+
16
19
  def selenium
17
20
  session.selenium
18
21
  end
19
22
  end
20
-
23
+
21
24
  class SeleniumSession
22
25
  include Webrat::SaveAndOpenPage
23
-
26
+ include Webrat::Selenium::SilenceStream
27
+
24
28
  def initialize(*args) # :nodoc:
25
29
  end
26
-
30
+
27
31
  def simulate
28
32
  end
29
-
33
+
30
34
  def automate
31
35
  yield
32
36
  end
33
-
37
+
34
38
  def visit(url)
35
39
  selenium.open(url)
36
40
  end
37
-
41
+
38
42
  webrat_deprecate :visits, :visit
39
-
43
+
40
44
  def fill_in(field_identifier, options)
41
- locator = "webrat=#{Regexp.escape(field_identifier)}"
42
- selenium.wait_for_element locator, 5
45
+ locator = "webrat=#{field_identifier}"
46
+ selenium.wait_for_element locator, :timeout_in_seconds => 5
43
47
  selenium.type(locator, "#{options[:with]}")
44
48
  end
45
-
49
+
46
50
  webrat_deprecate :fills_in, :fill_in
47
-
51
+
48
52
  def response
49
53
  SeleniumResponse.new(self, response_body)
50
54
  end
51
-
55
+
52
56
  def response_body #:nodoc:
53
57
  selenium.get_html_source
54
58
  end
55
-
59
+
60
+ def current_url
61
+ selenium.location
62
+ end
63
+
56
64
  def click_button(button_text_or_regexp = nil, options = {})
57
65
  if button_text_or_regexp.is_a?(Hash) && options == {}
58
66
  pattern, options = nil, button_text_or_regexp
@@ -61,66 +69,67 @@ module Webrat
61
69
  end
62
70
  pattern ||= '*'
63
71
  locator = "button=#{pattern}"
64
-
65
- selenium.wait_for_element locator, 5
72
+
73
+ selenium.wait_for_element locator, :timeout_in_seconds => 5
66
74
  selenium.click locator
67
75
  end
68
-
76
+
69
77
  webrat_deprecate :clicks_button, :click_button
70
78
 
71
79
  def click_link(link_text_or_regexp, options = {})
72
80
  pattern = adjust_if_regexp(link_text_or_regexp)
73
81
  locator = "webratlink=#{pattern}"
74
- selenium.wait_for_element locator, 5
82
+ selenium.wait_for_element locator, :timeout_in_seconds => 5
75
83
  selenium.click locator
76
84
  end
77
-
85
+
78
86
  webrat_deprecate :clicks_link, :click_link
79
-
87
+
80
88
  def click_link_within(selector, link_text, options = {})
81
89
  locator = "webratlinkwithin=#{selector}|#{link_text}"
82
- selenium.wait_for_element locator, 5
90
+ selenium.wait_for_element locator, :timeout_in_seconds => 5
83
91
  selenium.click locator
84
92
  end
85
-
93
+
86
94
  webrat_deprecate :clicks_link_within, :click_link_within
87
-
95
+
88
96
  def select(option_text, options = {})
89
97
  id_or_name_or_label = options[:from]
90
-
98
+
91
99
  if id_or_name_or_label
92
100
  select_locator = "webrat=#{id_or_name_or_label}"
93
101
  else
94
102
  select_locator = "webratselectwithoption=#{option_text}"
95
103
  end
96
-
97
- selenium.wait_for_element select_locator, 5
104
+
105
+ selenium.wait_for_element select_locator, :timeout_in_seconds => 5
98
106
  selenium.select(select_locator, option_text)
99
107
  end
100
-
108
+
101
109
  webrat_deprecate :selects, :select
102
-
110
+
103
111
  def choose(label_text)
104
112
  locator = "webrat=#{label_text}"
105
- selenium.wait_for_element locator, 5
113
+ selenium.wait_for_element locator, :timeout_in_seconds => 5
106
114
  selenium.click locator
107
115
  end
108
-
116
+
109
117
  webrat_deprecate :chooses, :choose
110
-
118
+
111
119
  def check(label_text)
112
120
  locator = "webrat=#{label_text}"
113
- selenium.wait_for_element locator, 5
114
- selenium.check locator
121
+ selenium.wait_for_element locator, :timeout_in_seconds => 5
122
+ selenium.click locator
115
123
  end
116
-
124
+ alias_method :uncheck, :check
125
+
117
126
  webrat_deprecate :checks, :check
118
127
 
119
128
  def fire_event(field_identifier, event)
120
129
  locator = "webrat=#{Regexp.escape(field_identifier)}"
121
130
  selenium.fire_event(locator, "#{event}")
122
131
  end
123
-
132
+
124
133
  def key_down(field_identifier, key_code)
125
134
  locator = "webrat=#{Regexp.escape(field_identifier)}"
126
135
  selenium.key_down(locator, key_code)
@@ -130,7 +139,7 @@ module Webrat
130
139
  locator = "webrat=#{Regexp.escape(field_identifier)}"
131
140
  selenium.key_up(locator, key_code)
132
141
  end
133
-
142
+
134
143
  def wait_for(params={})
135
144
  timeout = params[:timeout] || 5
136
145
  message = params[:message] || "Timeout exceeded"
@@ -142,8 +151,10 @@ module Webrat
142
151
 
143
152
  begin
144
153
  value = yield
145
- rescue ::Spec::Expectations::ExpectationNotMetError, ::Selenium::CommandError, Webrat::WebratError
146
- value = nil
154
+ rescue Exception => e
155
+ unless is_ignorable_wait_for_exception?(e)
156
+ raise e
157
+ end
147
158
  end
148
159
 
149
160
  return value if value
@@ -154,71 +165,78 @@ module Webrat
154
165
  raise Webrat::TimeoutError.new(message + " (after #{timeout} sec)")
155
166
  true
156
167
  end
157
-
168
+
158
169
  def selenium
159
170
  return $browser if $browser
160
171
  setup
161
172
  $browser
162
173
  end
163
-
174
+
164
175
  webrat_deprecate :browser, :selenium
165
-
166
-
176
+
177
+
167
178
  def save_and_open_screengrab
168
179
  return unless File.exist?(saved_page_dir)
169
-
180
+
170
181
  filename = "#{saved_page_dir}/webrat-#{Time.now.to_i}.png"
171
-
182
+
172
183
  if $browser.chrome_backend?
173
184
  $browser.capture_entire_page_screenshot(filename, '')
174
185
  else
175
186
  $browser.capture_screenshot(filename)
176
187
  end
177
- open_in_browser(filename)
188
+ open_in_browser(filename)
189
+
178
190
  end
179
-
180
- protected
181
-
182
- def setup #:nodoc:
183
- silence_stream(STDOUT) do
184
- Webrat.start_selenium_server
185
- Webrat.start_app_server
191
+
192
+ protected
193
+ def is_ignorable_wait_for_exception?(exception) #:nodoc:
194
+ if defined?(::Spec::Expectations::ExpectationNotMetError)
195
+ return true if exception.class == ::Spec::Expectations::ExpectationNotMetError
186
196
  end
187
-
188
- $browser = ::Selenium::Client::Driver.new("localhost", 4444, "*firefox", "http://0.0.0.0:3001")
189
- $browser.set_speed(0)
197
+ return true if [::Selenium::CommandError, Webrat::WebratError].include?(exception.class)
198
+ return false
199
+ end
200
+
201
+ def setup #:nodoc:
202
+ Webrat::Selenium::SeleniumRCServer.boot
203
+ Webrat::Selenium::ApplicationServerFactory.app_server_instance.boot
204
+
205
+ create_browser
190
206
  $browser.start
191
- teardown_at_exit
192
-
207
+
193
208
  extend_selenium
194
209
  define_location_strategies
195
210
  $browser.window_maximize
196
211
  end
197
-
198
- def teardown_at_exit #:nodoc:
212
+
213
+
214
+ def create_browser
215
+ $browser = ::Selenium::Client::Driver.new(Webrat.configuration.selenium_server_address || "localhost",
216
+ Webrat.configuration.selenium_server_port, Webrat.configuration.selenium_browser_key, "http://#{Webrat.configuration.application_address}:#{Webrat.configuration.application_port}")
217
+ $browser.set_speed(0) unless Webrat.configuration.selenium_server_address
218
+
199
219
  at_exit do
200
220
  silence_stream(STDOUT) do
201
221
  $browser.stop
202
- Webrat.stop_app_server
203
- Webrat.stop_selenium_server
204
222
  end
205
223
  end
206
224
  end
207
-
225
+
208
226
  def adjust_if_regexp(text_or_regexp) #:nodoc:
209
227
  if text_or_regexp.is_a?(Regexp)
210
228
  "evalregex:#{text_or_regexp.inspect}"
211
229
  else
212
230
  "evalregex:/#{text_or_regexp}/"
213
- end
231
+ end
214
232
  end
215
-
233
+
216
234
  def extend_selenium #:nodoc:
217
235
  extensions_file = File.join(File.dirname(__FILE__), "selenium_extensions.js")
218
236
  extenions_js = File.read(extensions_file)
219
237
  selenium.get_eval(extenions_js)
220
238
  end
221
-
239
+
222
240
  def define_location_strategies #:nodoc:
223
241
  Dir[File.join(File.dirname(__FILE__), "location_strategy_javascript", "*.js")].sort.each do |file|
224
242
  strategy_js = File.read(file)
@@ -227,4 +245,4 @@ module Webrat
227
245
  end
228
246
  end
229
247
  end
230
- end
248
+ end