webrat 0.4.3 → 0.4.4

Sign up to get free protection for your applications and to get access to all the features.
data/History.txt CHANGED
@@ -1,3 +1,21 @@
1
+ == 0.4.4 / 2009-04-06
2
+
3
+ * Major enhancements
4
+
5
+ * Make selenium process management code more robust and informative
6
+
7
+ * Minor enhancements
8
+
9
+ * Add support for Rails javascript post links (Mark Menard)
10
+ * Upgrade selenium-client dependency to 1.2.14, and update for new waiting
11
+ API (Balint Erdi)
12
+ * Change default app environment from "selenium" to "test"
13
+
14
+ * Bug fixes
15
+
16
+ * Don't create a new instance of WWW::Mechanize for each request
17
+ (Mark Menard)
18
+
1
19
  == 0.4.3 / 2009-03-17
2
20
 
3
21
  * Minor enhancements
data/lib/webrat.rb CHANGED
@@ -7,7 +7,7 @@ module Webrat
7
7
  class WebratError < StandardError
8
8
  end
9
9
 
10
- VERSION = '0.4.3'
10
+ VERSION = '0.4.4'
11
11
 
12
12
  def self.require_xml
13
13
  gem "nokogiri", ">= 1.0.6"
@@ -61,10 +61,10 @@ module Webrat
61
61
  def initialize # :nodoc:
62
62
  self.open_error_files = true
63
63
  self.parse_with_nokogiri = !Webrat.on_java?
64
- self.application_environment = :selenium
64
+ self.application_environment = :test
65
65
  self.application_port = 3001
66
66
  self.application_address = 'localhost'
67
- self.application_framework = 'rails'
67
+ self.application_framework = :rails
68
68
  self.selenium_server_port = 4444
69
69
  self.infinite_redirect_limit = 10
70
70
  self.selenium_browser_key = '*firefox'
@@ -81,6 +81,8 @@ module Webrat
81
81
  :delete
82
82
  elsif onclick.include?("m.setAttribute('value', 'put')")
83
83
  :put
84
+ elsif onclick.include?("m.setAttribute('value', 'post')")
85
+ :post
84
86
  else
85
87
  raise Webrat::WebratError.new("No HTTP method for _method param in #{onclick.inspect}")
86
88
  end
@@ -0,0 +1,27 @@
1
+ class TCPSocket
2
+
3
+ def self.wait_for_service_with_timeout(options)
4
+ start_time = Time.now
5
+
6
+ until listening_service?(options)
7
+ verbose_wait
8
+
9
+ if options[:timeout] && (Time.now > start_time + options[:timeout])
10
+ raise SocketError.new("Socket did not open within #{options[:timeout]} seconds")
11
+ end
12
+ end
13
+ end
14
+
15
+ def self.wait_for_service_termination_with_timeout(options)
16
+ start_time = Time.now
17
+
18
+ while listening_service?(options)
19
+ verbose_wait
20
+
21
+ if options[:timeout] && (Time.now > start_time + options[:timeout])
22
+ raise SocketError.new("Socket did not terminate within #{options[:timeout]} seconds")
23
+ end
24
+ end
25
+ end
26
+
27
+ end
@@ -36,7 +36,7 @@ module Webrat #:nodoc:
36
36
  end
37
37
 
38
38
  def mechanize
39
- @mechanize = WWW::Mechanize.new
39
+ @mechanize ||= WWW::Mechanize.new
40
40
  end
41
41
 
42
42
  def_delegators :mechanize, :basic_auth
@@ -1,86 +1,11 @@
1
1
  require "webrat"
2
- gem "selenium-client", ">=1.2.9"
2
+ gem "selenium-client", ">=1.2.14"
3
3
  require "selenium/client"
4
4
  require "webrat/selenium/selenium_session"
5
5
  require "webrat/selenium/matchers"
6
+ require "webrat/core_extensions/tcp_socket"
6
7
 
7
8
  module Webrat
8
-
9
- def self.with_selenium_server #:nodoc:
10
- start_selenium_server
11
- yield
12
- stop_selenium_server
13
- end
14
-
15
- def self.start_selenium_server #:nodoc:
16
- unless Webrat.configuration.selenium_server_address
17
- remote_control = ::Selenium::RemoteControl::RemoteControl.new("0.0.0.0", Webrat.configuration.selenium_server_port, 5)
18
- remote_control.jar_file = File.expand_path(__FILE__ + "../../../../vendor/selenium-server.jar")
19
- remote_control.start :background => true
20
- end
21
- TCPSocket.wait_for_service :host => (Webrat.configuration.selenium_server_address || "0.0.0.0"), :port => Webrat.configuration.selenium_server_port
22
- end
23
-
24
- def self.stop_selenium_server #:nodoc:
25
- ::Selenium::RemoteControl::RemoteControl.new("0.0.0.0", Webrat.configuration.selenium_server_port, 5).stop unless Webrat.configuration.selenium_server_address
26
- end
27
-
28
- def self.pid_file
29
- if File.exists?('config.ru')
30
- prepare_pid_file(Dir.pwd, 'rack.pid')
31
- else
32
- prepare_pid_file("#{RAILS_ROOT}/tmp/pids", "mongrel_selenium.pid")
33
- end
34
- end
35
- # Start the appserver for the underlying framework to test
36
- #
37
- # Sinatra: requires a config.ru in the root of your sinatra app to use this
38
- # Merb: Attempts to use bin/merb and falls back to the system merb
39
- # Rails: Calls mongrel_rails to startup the appserver
40
- def self.start_app_server
41
- case Webrat.configuration.application_framework
42
- when :sinatra
43
- fork do
44
- File.open('rack.pid', 'w') { |fp| fp.write Process.pid }
45
- exec 'rackup', File.expand_path(Dir.pwd + '/config.ru'), '-p', Webrat.configuration.application_port.to_s
46
- end
47
- when :merb
48
- cmd = 'merb'
49
- if File.exist?('bin/merb')
50
- cmd = 'bin/merb'
51
- end
52
- system("#{cmd} -d -p #{Webrat.configuration.application_port} -e #{Webrat.configuration.application_environment}")
53
- else # rails
54
- system("mongrel_rails start -d --chdir='#{RAILS_ROOT}' --port=#{Webrat.configuration.application_port} --environment=#{Webrat.configuration.application_environment} --pid #{pid_file} &")
55
- end
56
- TCPSocket.wait_for_service :host => Webrat.configuration.application_address, :port => Webrat.configuration.application_port.to_i
57
- end
58
-
59
- # Stop the appserver for the underlying framework under test
60
- #
61
- # Sinatra: Reads and kills the pid from the pid file created on startup
62
- # Merb: Reads and kills the pid from the pid file created on startup
63
- # Rails: Calls mongrel_rails stop to kill the appserver
64
- def self.stop_app_server
65
- case Webrat.configuration.application_framework
66
- when :sinatra
67
- pid = File.read('rack.pid')
68
- system("kill -9 #{pid}")
69
- FileUtils.rm_f 'rack.pid'
70
- when :merb
71
- pid = File.read("log/merb.#{Webrat.configuration.application_port}.pid")
72
- system("kill -9 #{pid}")
73
- FileUtils.rm_f "log/merb.#{Webrat.configuration.application_port}.pid"
74
- else # rails
75
- system "mongrel_rails stop -c #{RAILS_ROOT} --pid #{pid_file}"
76
- end
77
- end
78
-
79
- def self.prepare_pid_file(file_path, pid_file_name)
80
- FileUtils.mkdir_p File.expand_path(file_path)
81
- File.expand_path("#{file_path}/#{pid_file_name}")
82
- end
83
-
84
9
  # To use Webrat's Selenium support, you'll need the selenium-client gem installed.
85
10
  # Activate it with (for example, in your <tt>env.rb</tt>):
86
11
  #
@@ -143,6 +68,7 @@ module Webrat
143
68
  end
144
69
  end
145
70
  end
71
+
146
72
  if defined?(ActionController::IntegrationTest)
147
73
  module ActionController #:nodoc:
148
74
  IntegrationTest.class_eval do
@@ -0,0 +1,71 @@
1
+ module Webrat
2
+ module Selenium
3
+
4
+ class ApplicationServer
5
+
6
+ def self.boot
7
+ case Webrat.configuration.application_framework
8
+ when :sinatra
9
+ require "webrat/selenium/sinatra_application_server"
10
+ SinatraApplicationServer.new.boot
11
+ when :merb
12
+ require "webrat/selenium/merb_application_server"
13
+ MerbApplicationServer.new.boot
14
+ when :rails
15
+ require "webrat/selenium/rails_application_server"
16
+ RailsApplicationServer.new.boot
17
+ else
18
+ raise WebratError.new(<<-STR)
19
+ Unknown Webrat application_framework: #{Webrat.configuration.application_framework.inspect}
20
+
21
+ Please ensure you have a Webrat configuration block that specifies an application_framework
22
+ in your test_helper.rb, spec_helper.rb, or env.rb (for Cucumber).
23
+
24
+ For example:
25
+
26
+ Webrat.configure do |config|
27
+ # ...
28
+ config.application_framework = :rails
29
+ end
30
+ STR
31
+ end
32
+ end
33
+
34
+ def boot
35
+ start
36
+ wait
37
+ stop_at_exit
38
+ end
39
+
40
+ def stop_at_exit
41
+ at_exit do
42
+ stop
43
+ end
44
+ end
45
+
46
+ def wait
47
+ $stderr.print "==> Waiting for #{Webrat.configuration.application_framework} application server on port #{Webrat.configuration.application_port}... "
48
+ wait_for_socket
49
+ $stderr.print "Ready!\n"
50
+ end
51
+
52
+ def wait_for_socket
53
+ silence_stream(STDOUT) do
54
+ TCPSocket.wait_for_service_with_timeout \
55
+ :host => Webrat.configuration.application_address,
56
+ :port => Webrat.configuration.application_port.to_i,
57
+ :timeout => 30 # seconds
58
+ end
59
+ rescue SocketError
60
+ fail
61
+ end
62
+
63
+ def prepare_pid_file(file_path, pid_file_name)
64
+ FileUtils.mkdir_p File.expand_path(file_path)
65
+ File.expand_path("#{file_path}/#{pid_file_name}")
66
+ end
67
+
68
+ end
69
+
70
+ end
71
+ end
@@ -0,0 +1,48 @@
1
+ module Webrat
2
+ module Selenium
3
+
4
+ class MerbApplicationServer < ApplicationServer
5
+
6
+ def start
7
+ system start_command
8
+ end
9
+
10
+ def stop
11
+ silence_stream(STDOUT) do
12
+ pid = File.read(pid_file)
13
+ system("kill -9 #{pid}")
14
+ FileUtils.rm_f pid_file
15
+ end
16
+ end
17
+
18
+ def fail
19
+ $stderr.puts
20
+ $stderr.puts
21
+ $stderr.puts "==> Failed to boot the Merb application server... exiting!"
22
+ $stderr.puts
23
+ $stderr.puts "Verify you can start a Merb server on port #{Webrat.configuration.application_port} with the following command:"
24
+ $stderr.puts
25
+ $stderr.puts " #{start_command}"
26
+ exit
27
+ end
28
+
29
+ def pid_file
30
+ "log/merb.#{Webrat.configuration.application_port}.pid"
31
+ end
32
+
33
+ def start_command
34
+ "#{merb_command} -d -p #{Webrat.configuration.application_port} -e #{Webrat.configuration.application_environment}"
35
+ end
36
+
37
+ def merb_command
38
+ if File.exist?('bin/merb')
39
+ merb_cmd = 'bin/merb'
40
+ else
41
+ merb_cmd = 'merb'
42
+ end
43
+ end
44
+
45
+ end
46
+
47
+ end
48
+ end
@@ -0,0 +1,42 @@
1
+ module Webrat
2
+ module Selenium
3
+
4
+ class RailsApplicationServer < ApplicationServer
5
+
6
+ def start
7
+ system start_command
8
+ end
9
+
10
+ def stop
11
+ silence_stream(STDOUT) do
12
+ system stop_command
13
+ end
14
+ end
15
+
16
+ def fail
17
+ $stderr.puts
18
+ $stderr.puts
19
+ $stderr.puts "==> Failed to boot the Rails application server... exiting!"
20
+ $stderr.puts
21
+ $stderr.puts "Verify you can start a Rails server on port #{Webrat.configuration.application_port} with the following command:"
22
+ $stderr.puts
23
+ $stderr.puts " #{start_command}"
24
+ exit
25
+ end
26
+
27
+ def pid_file
28
+ prepare_pid_file("#{RAILS_ROOT}/tmp/pids", "mongrel_selenium.pid")
29
+ end
30
+
31
+ def start_command
32
+ "mongrel_rails start -d --chdir='#{RAILS_ROOT}' --port=#{Webrat.configuration.application_port} --environment=#{Webrat.configuration.application_environment} --pid #{pid_file} &"
33
+ end
34
+
35
+ def stop_command
36
+ "mongrel_rails stop -c #{RAILS_ROOT} --pid #{pid_file}"
37
+ end
38
+
39
+ end
40
+
41
+ end
42
+ end
@@ -0,0 +1,80 @@
1
+ module Webrat
2
+ module Selenium
3
+
4
+ class SeleniumRCServer
5
+
6
+ def self.boot
7
+ new.boot
8
+ end
9
+
10
+ def boot
11
+ return if selenium_grid?
12
+
13
+ start
14
+ wait
15
+ stop_at_exit
16
+ end
17
+
18
+ def start
19
+ silence_stream(STDOUT) do
20
+ remote_control.start :background => true
21
+ end
22
+ end
23
+
24
+ def stop_at_exit
25
+ at_exit do
26
+ stop
27
+ end
28
+ end
29
+
30
+ def remote_control
31
+ return @remote_control if @remote_control
32
+
33
+ @remote_control = ::Selenium::RemoteControl::RemoteControl.new("0.0.0.0", Webrat.configuration.selenium_server_port, 5)
34
+ @remote_control.jar_file = jar_path
35
+
36
+ return @remote_control
37
+ end
38
+
39
+ def jar_path
40
+ File.expand_path(__FILE__ + "../../../../../vendor/selenium-server.jar")
41
+ end
42
+
43
+ def selenium_grid?
44
+ Webrat.configuration.selenium_server_address
45
+ end
46
+
47
+ def wait
48
+ $stderr.print "==> Waiting for Selenium RC server on port #{Webrat.configuration.selenium_server_port}... "
49
+ wait_for_socket
50
+ $stderr.print "Ready!\n"
51
+ rescue SocketError
52
+ fail
53
+ end
54
+
55
+ def wait_for_socket
56
+ silence_stream(STDOUT) do
57
+ TCPSocket.wait_for_service_with_timeout \
58
+ :host => (Webrat.configuration.selenium_server_address || "0.0.0.0"),
59
+ :port => Webrat.configuration.selenium_server_port,
60
+ :timeout => 15 # seconds
61
+ end
62
+ end
63
+
64
+ def fail
65
+ $stderr.puts
66
+ $stderr.puts
67
+ $stderr.puts "==> Failed to boot the Selenium RC server... exiting!"
68
+ exit
69
+ end
70
+
71
+ def stop
72
+ silence_stream(STDOUT) do
73
+ ::Selenium::RemoteControl::RemoteControl.new("0.0.0.0", Webrat.configuration.selenium_server_port, 5).stop
74
+ end
75
+ end
76
+
77
+ end
78
+
79
+ end
80
+ end
@@ -1,4 +1,6 @@
1
1
  require "webrat/core/save_and_open_page"
2
+ require "webrat/selenium/selenium_rc_server"
3
+ require "webrat/selenium/application_server"
2
4
 
3
5
  module Webrat
4
6
  class TimeoutError < WebratError
@@ -39,7 +41,7 @@ module Webrat
39
41
 
40
42
  def fill_in(field_identifier, options)
41
43
  locator = "webrat=#{Regexp.escape(field_identifier)}"
42
- selenium.wait_for_element locator, 5
44
+ selenium.wait_for_element locator, :timeout_in_seconds => 5
43
45
  selenium.type(locator, "#{options[:with]}")
44
46
  end
45
47
 
@@ -62,7 +64,7 @@ module Webrat
62
64
  pattern ||= '*'
63
65
  locator = "button=#{pattern}"
64
66
 
65
- selenium.wait_for_element locator, 5
67
+ selenium.wait_for_element locator, :timeout_in_seconds => 5
66
68
  selenium.click locator
67
69
  end
68
70
 
@@ -71,7 +73,7 @@ module Webrat
71
73
  def click_link(link_text_or_regexp, options = {})
72
74
  pattern = adjust_if_regexp(link_text_or_regexp)
73
75
  locator = "webratlink=#{pattern}"
74
- selenium.wait_for_element locator, 5
76
+ selenium.wait_for_element locator, :timeout_in_seconds => 5
75
77
  selenium.click locator
76
78
  end
77
79
 
@@ -79,7 +81,7 @@ module Webrat
79
81
 
80
82
  def click_link_within(selector, link_text, options = {})
81
83
  locator = "webratlinkwithin=#{selector}|#{link_text}"
82
- selenium.wait_for_element locator, 5
84
+ selenium.wait_for_element locator, :timeout_in_seconds => 5
83
85
  selenium.click locator
84
86
  end
85
87
 
@@ -94,7 +96,7 @@ module Webrat
94
96
  select_locator = "webratselectwithoption=#{option_text}"
95
97
  end
96
98
 
97
- selenium.wait_for_element select_locator, 5
99
+ selenium.wait_for_element select_locator, :timeout_in_seconds => 5
98
100
  selenium.select(select_locator, option_text)
99
101
  end
100
102
 
@@ -102,7 +104,7 @@ module Webrat
102
104
 
103
105
  def choose(label_text)
104
106
  locator = "webrat=#{label_text}"
105
- selenium.wait_for_element locator, 5
107
+ selenium.wait_for_element locator, :timeout_in_seconds => 5
106
108
  selenium.click locator
107
109
  end
108
110
 
@@ -110,7 +112,7 @@ module Webrat
110
112
 
111
113
  def check(label_text)
112
114
  locator = "webrat=#{label_text}"
113
- selenium.wait_for_element locator, 5
115
+ selenium.wait_for_element locator, :timeout_in_seconds => 5
114
116
  selenium.click locator
115
117
  end
116
118
  alias_method :uncheck, :check
@@ -179,6 +181,7 @@ module Webrat
179
181
  end
180
182
 
181
183
  protected
184
+
182
185
  def silence_stream(stream)
183
186
  old_stream = stream.dup
184
187
  stream.reopen(RUBY_PLATFORM =~ /mswin/ ? 'NUL:' : '/dev/null')
@@ -189,16 +192,11 @@ module Webrat
189
192
  end
190
193
 
191
194
  def setup #:nodoc:
192
- silence_stream(STDOUT) do
193
- silence_stream(STDERR) do
194
- Webrat.start_selenium_server
195
- Webrat.start_app_server
196
- end
197
- end
195
+ Webrat::Selenium::SeleniumRCServer.boot
196
+ Webrat::Selenium::ApplicationServer.boot
198
197
 
199
198
  create_browser
200
199
  $browser.start
201
- teardown_at_exit
202
200
 
203
201
  extend_selenium
204
202
  define_location_strategies
@@ -210,14 +208,10 @@ module Webrat
210
208
  $browser = ::Selenium::Client::Driver.new(Webrat.configuration.selenium_server_address || "localhost",
211
209
  Webrat.configuration.selenium_server_port, Webrat.configuration.selenium_browser_key, "http://#{Webrat.configuration.application_address}:#{Webrat.configuration.application_port}")
212
210
  $browser.set_speed(0) unless Webrat.configuration.selenium_server_address
213
- end
214
-
215
- def teardown_at_exit #:nodoc:
211
+
216
212
  at_exit do
217
213
  silence_stream(STDOUT) do
218
214
  $browser.stop
219
- Webrat.stop_app_server
220
- Webrat.stop_selenium_server
221
215
  end
222
216
  end
223
217
  end
@@ -0,0 +1,35 @@
1
+ module Webrat
2
+ module Selenium
3
+
4
+ class SinatraApplicationServer < ApplicationServer
5
+
6
+ def start
7
+ fork do
8
+ File.open('rack.pid', 'w') { |fp| fp.write Process.pid }
9
+ exec 'rackup', File.expand_path(Dir.pwd + '/config.ru'), '-p', Webrat.configuration.application_port.to_s
10
+ end
11
+ end
12
+
13
+ def stop
14
+ silence_stream(STDOUT) do
15
+ pid = File.read(pid_file)
16
+ system("kill -9 #{pid}")
17
+ FileUtils.rm_f pid_file
18
+ end
19
+ end
20
+
21
+ def fail
22
+ $stderr.puts
23
+ $stderr.puts
24
+ $stderr.puts "==> Failed to boot the Sinatra application server... exiting!"
25
+ exit
26
+ end
27
+
28
+ def pid_file
29
+ prepare_pid_file(Dir.pwd, 'rack.pid')
30
+ end
31
+
32
+ end
33
+
34
+ end
35
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: webrat
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.3
4
+ version: 0.4.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Bryan Helmkamp
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-03-17 00:00:00 -04:00
12
+ date: 2009-04-06 00:00:00 -04:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -85,6 +85,7 @@ files:
85
85
  - lib/webrat/core_extensions/detect_mapped.rb
86
86
  - lib/webrat/core_extensions/meta_class.rb
87
87
  - lib/webrat/core_extensions/nil_to_param.rb
88
+ - lib/webrat/core_extensions/tcp_socket.rb
88
89
  - lib/webrat/mechanize.rb
89
90
  - lib/webrat/merb.rb
90
91
  - lib/webrat/merb_session.rb
@@ -92,6 +93,7 @@ files:
92
93
  - lib/webrat/rails.rb
93
94
  - lib/webrat/rspec-rails.rb
94
95
  - lib/webrat/selenium
96
+ - lib/webrat/selenium/application_server.rb
95
97
  - lib/webrat/selenium/location_strategy_javascript
96
98
  - lib/webrat/selenium/location_strategy_javascript/button.js
97
99
  - lib/webrat/selenium/location_strategy_javascript/label.js
@@ -105,8 +107,12 @@ files:
105
107
  - lib/webrat/selenium/matchers/have_tag.rb
106
108
  - lib/webrat/selenium/matchers/have_xpath.rb
107
109
  - lib/webrat/selenium/matchers.rb
110
+ - lib/webrat/selenium/merb_application_server.rb
111
+ - lib/webrat/selenium/rails_application_server.rb
108
112
  - lib/webrat/selenium/selenium_extensions.js
113
+ - lib/webrat/selenium/selenium_rc_server.rb
109
114
  - lib/webrat/selenium/selenium_session.rb
115
+ - lib/webrat/selenium/sinatra_application_server.rb
110
116
  - lib/webrat/selenium.rb
111
117
  - lib/webrat/sinatra.rb
112
118
  - lib/webrat.rb