polonium 0.1.1 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (38) hide show
  1. data/CHANGES +7 -0
  2. data/README +27 -12
  3. data/Rakefile +2 -2
  4. data/init.rb +9 -0
  5. data/lib/polonium/adapters/rspec.rb +19 -13
  6. data/lib/polonium/adapters/test_unit.rb +1 -1
  7. data/lib/polonium/configuration.rb +32 -97
  8. data/lib/polonium/driver.rb +25 -28
  9. data/lib/polonium/dsl/selenium_dsl.rb +67 -8
  10. data/lib/polonium/element.rb +60 -30
  11. data/lib/polonium/page.rb +13 -2
  12. data/lib/polonium/server_runners/external_server_runner.rb +20 -0
  13. data/lib/polonium/server_runners/mongrel_server_runner.rb +63 -0
  14. data/lib/polonium/server_runners/server_runner.rb +36 -0
  15. data/lib/polonium/server_runners/webrick_server_runner.rb +49 -0
  16. data/lib/polonium/test_case.rb +1 -19
  17. data/lib/polonium/wait_for.rb +4 -1
  18. data/lib/polonium.rb +6 -4
  19. data/spec/polonium/configuration_spec.rb +41 -99
  20. data/spec/polonium/driver_spec.rb +112 -62
  21. data/spec/polonium/element_spec.rb +69 -24
  22. data/spec/polonium/server_runners/external_server_runner_spec.rb +33 -0
  23. data/spec/polonium/server_runners/mongrel_server_runner_spec.rb +69 -0
  24. data/spec/polonium/server_runners/server_runner_spec.rb +36 -0
  25. data/spec/polonium/server_runners/webrick_server_runner_spec.rb +121 -0
  26. data/spec/polonium/test_case_spec.rb +538 -649
  27. data/spec/rspec/options_spec.rb +23 -22
  28. data/spec/spec_helper.rb +0 -18
  29. data/spec/spec_suite.rb +1 -1
  30. data/spec/test_unit/testrunnermediator_spec.rb +2 -2
  31. metadata +50 -41
  32. data/lib/polonium/dsl/test_unit_dsl.rb +0 -61
  33. data/lib/polonium/mongrel_selenium_server_runner.rb +0 -37
  34. data/lib/polonium/server_runner.rb +0 -33
  35. data/lib/polonium/webrick_selenium_server_runner.rb +0 -33
  36. data/spec/polonium/mongrel_selenium_server_runner_spec.rb +0 -35
  37. data/spec/polonium/server_runner_spec.rb +0 -42
  38. data/spec/polonium/webrick_selenium_server_runner_spec.rb +0 -117
data/CHANGES CHANGED
@@ -1,3 +1,10 @@
1
+ 0.2.0
2
+ * Added ExternalServerRunner.
3
+ * Removed mysql specific setup logic.
4
+
5
+ 0.1.1
6
+ * Rspec support
7
+
1
8
  0.1.0
2
9
  * Renamed to Polonium
3
10
  * Methods renamed to match Test::Unit assertions
data/README CHANGED
@@ -2,10 +2,12 @@
2
2
 
3
3
  Welcome to Polonium!
4
4
 
5
- This plugin is designed to let you use Polonium to write Selenium tests in Ruby, using a simple series of
6
- Rake tasks.
5
+ Polonium is a wrapper for Selenium that lets your write cleaner Selenium tests
6
+ in ruby, and run them with a simple set of rake tasks.
7
7
 
8
8
  == Installation
9
+ Polonium depends on the Selenium gem. To install this dependency, run:
10
+ sudo gem install Selenium
9
11
 
10
12
  The current version of this plugin can be found at: http://rubyforge.org/var/svn/pivotalrb/polonium/trunk
11
13
 
@@ -13,17 +15,30 @@ You may install the plugin with the following command:
13
15
 
14
16
  script/plugin install svn://rubyforge.org/var/svn/pivotalrb/polonium/trunk
15
17
 
16
- == Usage
17
- The polonium plugin assumes you have a test/selenium directory with a selenium_suite.rb file in
18
- it. A sample selenium_suite.rb and selenium_helper.rb can be copied into your test/selenium directory.
18
+ You may also use Polonium as a gem:
19
19
 
20
- You'll get the following tasks:
21
- - selenium:test - starts a Selenium RC server, runs selenium tests, and shuts the server down
22
- when they're done
20
+ sudo gem install polonium
23
21
 
24
- and lower level tasks as well:
25
- - selenium:server starts up a Selenium RC server
26
- - selenium:test_with_server_started runs Selenium tests off of an existing server
22
+ == Getting Started
23
+ The polonium plugin rake tasks assumes you have a test/selenium directory with a selenium_suite.rb file in
24
+ it. To get started, copy examples/selenium_suite.rb, examples/selenium_helper.rb, and examples/example_test.rb
25
+ into your test/selenium directory.
26
+
27
+ To start the selenium server, run the command:
28
+ selenium
29
+ The selenium command was installed with the Selenium Gem.
30
+
31
+ You can run Polonium tests using rspec or test/unit through the rake tasks.
32
+ rake selenium:test
33
+ # or
34
+ rake selenium:spec
35
+
36
+ [TODO: this doesn't seem to work on a vanilla project that is using Polonium as a gem & the code in
37
+ the examples directory; @selenium_driver is nil. Is there an extra step necessary to get this working?]
38
+
39
+ You can also run individual tests straight ruby:
40
+
41
+ ruby test/selenium/any_selenium_test.rb
27
42
 
28
43
  == Future Enhancements
29
44
 
@@ -31,7 +46,7 @@ There are a few things we'd like to improve, but we wanted to get this out now.
31
46
 
32
47
  == License
33
48
 
34
- Polonium is distributed under the MIT license. Copyright © 2007 Pivotal Labs, Inc.
49
+ Polonium is distributed under the MIT license. Copyright © 2007-2008 Pivotal Labs, Inc.
35
50
 
36
51
  == Contributing
37
52
 
data/Rakefile CHANGED
@@ -26,7 +26,7 @@ def run_suite
26
26
  end
27
27
 
28
28
  PKG_NAME = "polonium"
29
- PKG_VERSION = "0.1.1"
29
+ PKG_VERSION = "0.2.0"
30
30
  PKG_FILES = FileList[
31
31
  '[A-Z]*',
32
32
  '*.rb',
@@ -37,7 +37,7 @@ PKG_FILES = FileList[
37
37
  spec = Gem::Specification.new do |s|
38
38
  s.name = PKG_NAME
39
39
  s.version = PKG_VERSION
40
- s.summary = "Selenium RC with enhanced assertions that also runs your rails app."
40
+ s.summary = "Selenium RC with Rails integration and enhanced assertions."
41
41
  s.test_files = "spec/spec_suite.rb"
42
42
  s.description = s.summary
43
43
 
data/init.rb ADDED
@@ -0,0 +1,9 @@
1
+ # Placeholder to satisfy Rails.
2
+ #
3
+ # Do NOT add any require statements to this file. Doing
4
+ # so will cause Rails to load this plugin all of the time.
5
+ #
6
+ # Running 'ruby script/generate rspec' will
7
+ # generate spec/spec_helper.rb, which includes the necessary
8
+ # require statements and configuration. This file should
9
+ # be required by all of your spec files.
@@ -1,21 +1,27 @@
1
1
  class Spec::Runner::Options
2
- attr_accessor :selenium_configuration, :selenium_app_runner
3
-
4
- def run_examples_with_selenium_runner(*args)
5
- success = run_examples_without_selenium_runner(*args)
6
- selenium_app_runner.stop
7
- selenium_configuration.stop_driver_if_necessary(success)
2
+ def stop_selenium(success)
3
+ Polonium::Configuration.instance.app_server_runner.stop
4
+ Polonium::Configuration.instance.stop_driver_if_necessary(success)
8
5
  success
9
6
  end
10
- alias_method_chain :run_examples, :selenium_runner
11
- end
12
7
 
13
- rspec_options.selenium_configuration = Polonium::Configuration.instance
14
- rspec_options.selenium_app_runner = nil
8
+ if instance_methods.include?('after_suite_parts')
9
+ Spec::Example::ExampleGroup.after(:suite) do |success|
10
+ rspec_options.stop_selenium success
11
+ end
12
+ else
13
+ def run_examples_with_selenium_runner(*args)
14
+ success = run_examples_without_selenium_runner(*args)
15
+ stop_selenium success
16
+ success
17
+ end
18
+ alias_method_chain :run_examples, :selenium_runner
19
+ end
20
+ end
15
21
 
16
22
  Spec::Example::ExampleMethods.before(:all) do
17
- unless rspec_options.selenium_app_runner
18
- rspec_options.selenium_app_runner = rspec_options.selenium_configuration.create_server_runner
19
- rspec_options.selenium_app_runner.start
23
+ unless Polonium::Configuration.instance.app_server_runner
24
+ app_server_runner = Polonium::Configuration.instance.create_app_server_runner
25
+ app_server_runner.start
20
26
  end
21
27
  end
@@ -11,7 +11,7 @@ class Test::Unit::UI::TestRunnerMediator
11
11
  protected
12
12
  def start_app_server
13
13
  @selenium_driver = Polonium::Configuration.instance
14
- @app_runner = @selenium_driver.create_server_runner
14
+ @app_runner = @selenium_driver.create_app_server_runner
15
15
  @app_runner.start
16
16
  end
17
17
 
@@ -9,6 +9,11 @@ module Polonium
9
9
  end
10
10
  FIREFOX = "firefox" unless const_defined? :FIREFOX
11
11
  IEXPLORE = "iexplore" unless const_defined? :IEXPLORE
12
+ SERVER_RUNNERS = {
13
+ :webrick => ServerRunners::WebrickServerRunner,
14
+ :mongrel => ServerRunners::MongrelServerRunner,
15
+ :external => ServerRunners::ExternalServerRunner
16
+ } unless const_defined? :SERVER_RUNNERS
12
17
 
13
18
  class << self
14
19
  # The instance of the Singleton Configuration. On its initial call, the initial configuration is set.
@@ -17,33 +22,34 @@ module Polonium
17
22
  # * RAILS_ENV - The Rails environment (defaults: test)
18
23
  # * selenium_server_host - The host name for the Selenium RC server (default: localhost)
19
24
  # * selenium_server_port - The port for the Selenium RC server (default: 4444)
20
- # * webrick_host - The host name that the application server will start under (default: localhost)
21
- # * webrick_port - The port that the application server will start under (default: 4000)
25
+ # * external_app_server_host - The host name that the Rails application server will start under (default: localhost)
26
+ # * external_app_server_port - The port that the Rails application server will start under (default: 4000)
22
27
  # * app_server_engine - The type of server the application will be run with (webrick or mongrel)
23
28
  # * internal_app_server_host - The host name for the Application server that the Browser will access (default: localhost)
24
29
  # * internal_app_server_host - The port for the Application server that the Browser will access (default: 4000)
25
30
  # * keep_browser_open_on_failure - If there is a failure in the test suite, keep the browser window open (default: false)
26
31
  # * verify_remote_app_server_is_running - Raise an exception if the Application Server is not running (default: true)
27
32
  def instance
28
- return @instance if @instance
29
- @instance = new
30
- @instance.env = ENV
31
-
32
- @instance.browser = FIREFOX
33
- @instance.selenium_server_host = "localhost" # address of selenium RC server (java)
34
- @instance.selenium_server_port = 4444
35
- @instance.app_server_engine = :webrick
36
- @instance.internal_app_server_host = "0.0.0.0" # internal address of app server (webrick or mongrel)
37
- @instance.internal_app_server_port = 4000
38
- @instance.external_app_server_host = "localhost" # external address of app server (webrick or mongrel)
39
- @instance.external_app_server_port = 4000
40
- @instance.server_engine = :webrick
41
- @instance.keep_browser_open_on_failure = false
42
- @instance.browser_mode = BrowserMode::Suite
43
- @instance.verify_remote_app_server_is_running = true
44
-
45
- establish_environment
46
- @instance
33
+ @instance ||= begin
34
+ @instance = new
35
+ @instance.env = ENV
36
+
37
+ @instance.browser = FIREFOX
38
+ @instance.selenium_server_host = "localhost" # address of selenium RC server (java)
39
+ @instance.selenium_server_port = 4444
40
+ @instance.app_server_engine = :webrick
41
+ @instance.internal_app_server_host = "0.0.0.0" # internal address of app server (webrick or mongrel)
42
+ @instance.internal_app_server_port = 4000
43
+ @instance.external_app_server_host = "localhost" # external address of app server (webrick or mongrel)
44
+ @instance.external_app_server_port = 4000
45
+ @instance.server_engine = :webrick
46
+ @instance.keep_browser_open_on_failure = false
47
+ @instance.browser_mode = BrowserMode::Suite
48
+ @instance.verify_remote_app_server_is_running = true
49
+
50
+ establish_environment
51
+ @instance
52
+ end
47
53
  end
48
54
  attr_writer :instance
49
55
 
@@ -81,7 +87,6 @@ module Polonium
81
87
  end
82
88
 
83
89
  attr_accessor(
84
- :configuration,
85
90
  :env,
86
91
  :rails_env,
87
92
  :rails_root,
@@ -105,7 +110,6 @@ module Polonium
105
110
  self.verify_remote_app_server_is_running = true
106
111
  @after_driver_started_listeners = []
107
112
  @app_server_initialization = proc {}
108
- @failure_has_occurred = false
109
113
  end
110
114
 
111
115
  # A callback hook that gets run after the Selenese Interpreter is started.
@@ -125,11 +129,6 @@ module Polonium
125
129
  return "*#{@browser}"
126
130
  end
127
131
 
128
- # Has a failure occurred in the tests?
129
- def failure_has_occurred?
130
- @failure_has_occurred = true
131
- end
132
-
133
132
  # The http host name and port to be entered into the browser address bar
134
133
  def browser_url
135
134
  "http://#{external_app_server_host}:#{external_app_server_port}"
@@ -167,7 +166,6 @@ module Polonium
167
166
  end
168
167
 
169
168
  def stop_driver_if_necessary(suite_passed) #:nodoc:
170
- failure_has_occurred unless suite_passed
171
169
  if @driver && stop_driver?(suite_passed)
172
170
  @driver.stop
173
171
  @driver = nil
@@ -196,78 +194,15 @@ module Polonium
196
194
  )
197
195
  end
198
196
 
199
- def create_server_runner #:nodoc:
200
- case @app_server_engine.to_sym
201
- when :mongrel
202
- create_mongrel_runner
203
- when :webrick
204
- create_webrick_runner
205
- else
206
- raise "Invalid server type: #{selenium_configuration.app_server_type}"
207
- end
208
- end
209
-
210
- def create_webrick_runner #:nodoc:
211
- require 'webrick_server'
212
- runner = WebrickSeleniumServerRunner.new
213
- runner.configuration = self
214
- runner.thread_class = Thread
215
- runner.socket = Socket
216
- runner.dispatch_servlet = DispatchServlet
217
- runner.environment_path = File.expand_path("#{@rails_root}/config/environment")
218
- runner
219
- end
220
-
221
- def create_webrick_server #:nodoc:
222
- WEBrick::HTTPServer.new({
223
- :Port => @internal_app_server_port,
224
- :BindAddress => @internal_app_server_host,
225
- :ServerType => WEBrick::SimpleServer,
226
- :MimeTypes => WEBrick::HTTPUtils::DefaultMimeTypes,
227
- :Logger => new_logger,
228
- :AccessLog => []
229
- })
197
+ attr_reader :app_server_runner
198
+ def create_app_server_runner #:nodoc:
199
+ app_server_type = SERVER_RUNNERS[@app_server_engine.to_sym]
200
+ raise "Invalid server engine #{@app_server_engine}" unless app_server_type
201
+ @app_server_runner = app_server_type.new(self)
230
202
  end
231
203
 
232
204
  def new_logger
233
205
  Logger.new(StringIO.new)
234
206
  end
235
-
236
- def create_mongrel_runner #:nodoc:
237
- runner = MongrelSeleniumServerRunner.new
238
- runner.configuration = self
239
- runner.thread_class = Thread
240
- runner
241
- end
242
-
243
- def create_mongrel_configurator #:nodoc:
244
- dir = File.dirname(__FILE__)
245
- require 'mongrel/rails'
246
- settings = {
247
- :host => internal_app_server_host,
248
- :port => internal_app_server_port,
249
- :cwd => @rails_root,
250
- :log_file => "#{@rails_root}/log/mongrel.log",
251
- :pid_file => "#{@rails_root}/log/mongrel.pid",
252
- :environment => @rails_env,
253
- :docroot => "#{@rails_root}/public",
254
- :mime_map => nil,
255
- :daemon => false,
256
- :debug => false,
257
- :includes => ["mongrel"],
258
- :config_script => nil
259
- }
260
-
261
- configurator = Mongrel::Rails::RailsConfigurator.new(settings) do
262
- log "Starting Mongrel in #{defaults[:environment]} mode at #{defaults[:host]}:#{defaults[:port]}"
263
- end
264
- configurator
265
- end
266
-
267
- protected
268
- # Sets the failure state to true
269
- def failure_has_occurred
270
- @failure_has_occurred = true
271
- end
272
207
  end
273
208
  end
@@ -3,6 +3,11 @@ module Polonium
3
3
  include WaitFor
4
4
  attr_reader :server_host, :server_port
5
5
 
6
+ # The Configuration object.
7
+ def configuration
8
+ Configuration.instance
9
+ end
10
+
6
11
  def browser_start_command
7
12
  @browserStartCommand
8
13
  end
@@ -37,48 +42,51 @@ module Polonium
37
42
  Page.new(self)
38
43
  end
39
44
 
45
+ # Open the home page of the Application and wait for the page to load.
46
+ def open_home_page
47
+ open(configuration.browser_url)
48
+ end
49
+
40
50
  #--------- Commands
41
51
  alias_method :confirm, :get_confirmation
42
52
 
43
53
  # Type text into a page element
44
54
  def type(locator, value)
45
- wait_for_is_element_present(locator)
55
+ assert_element_present(locator)
46
56
  super
47
57
  end
48
58
 
49
- # Reload the current page that the browser is on.
50
- def reload
51
- get_eval("selenium.browserbot.getCurrentWindow().location.reload()")
52
- end
53
-
54
59
  def click(locator)
55
- wait_for_is_element_present(locator)
60
+ assert_element_present locator
56
61
  super
57
62
  end
58
- alias_method :wait_for_and_click, :click
59
63
 
60
64
  def select(select_locator, option_locator)
61
- wait_for_is_element_present(select_locator)
65
+ assert_element_present select_locator
62
66
  super
63
67
  end
64
-
68
+
69
+ # Reload the current page that the browser is on.
70
+ def reload
71
+ get_eval("selenium.browserbot.getCurrentWindow().location.reload()")
72
+ end
73
+
65
74
  # Click a link and wait for the page to load.
66
75
  def click_and_wait(locator, wait_for = default_timeout)
67
76
  click locator
68
- wait_for_page_to_load(wait_for)
77
+ assert_page_loaded(wait_for)
69
78
  end
70
- alias_method :click_and_wait_for_page_to_load, :click_and_wait
71
79
 
72
80
  # Click the back button and wait for the page to load.
73
81
  def go_back_and_wait
74
82
  go_back
75
- wait_for_page_to_load
83
+ assert_page_loaded
76
84
  end
77
85
 
78
86
  # Open the home page of the Application and wait for the page to load.
79
87
  def open(url)
80
88
  super
81
- wait_for_page_to_load
89
+ assert_page_loaded
82
90
  end
83
91
  alias_method :open_and_wait, :open
84
92
 
@@ -87,11 +95,6 @@ module Polonium
87
95
  get_eval(inner_html_js(locator))
88
96
  end
89
97
 
90
- # Does the element at locator contain the text?
91
- def element_contains_text(locator, text)
92
- is_element_present(locator) && element(locator).contains?(text)
93
- end
94
-
95
98
  # Does the element at locator not contain the text?
96
99
  def element_does_not_contain_text(locator, text)
97
100
  return true unless is_element_present(locator)
@@ -99,7 +102,7 @@ module Polonium
99
102
  end
100
103
 
101
104
  #----- Waiting for conditions
102
- def wait_for_is_element_present(locator, params={})
105
+ def assert_element_present(locator, params={})
103
106
  params = {
104
107
  :message => "Expected element '#{locator}' to be present, but it was not"
105
108
  }.merge(params)
@@ -108,7 +111,7 @@ module Polonium
108
111
  end
109
112
  end
110
113
 
111
- def wait_for_is_element_not_present(locator, params={})
114
+ def assert_element_not_present(locator, params={})
112
115
  params = {
113
116
  :message => "Expected element '#{locator}' to be absent, but it was not"
114
117
  }.merge(params)
@@ -123,13 +126,7 @@ module Polonium
123
126
  flunk "We got a new page, but it was an application exception page.\n\n#{get_html_source}"
124
127
  end
125
128
  end
126
-
127
- def wait_for_element_to_contain(locator, text, message=nil, timeout=default_wait_for_time)
128
- wait_for(:message => message, :timeout => timeout) do
129
- element_contains_text(locator, text)
130
- end
131
- end
132
- alias_method :wait_for_element_to_contain_text, :wait_for_element_to_contain
129
+ alias_method :assert_page_loaded, :wait_for_page_to_load
133
130
 
134
131
  # Open the log window on the browser. This is useful to diagnose issues with Selenium Core.
135
132
  def show_log(log_level = "debug")
@@ -1,10 +1,66 @@
1
1
  module Polonium
2
2
  module SeleniumDsl
3
- # The Configuration object.
4
- def configuration
5
- @configuration ||= Configuration.instance
3
+ class << self
4
+ def page_assertion(name)
5
+ module_eval(
6
+ "def assert_#{name}(value, params={})\n" +
7
+ " page.assert_#{name}(value, params)\n" +
8
+ "end",
9
+ __FILE__,
10
+ __LINE__ - 4
11
+ )
12
+ end
13
+
14
+ def element_assertion(name)
15
+ module_eval(
16
+ "def assert_#{name}(locator, *args)\n" +
17
+ " element(locator).assert_#{name}(*args)\n" +
18
+ "end",
19
+ __FILE__,
20
+ __LINE__ - 4
21
+ )
22
+ end
23
+ end
24
+
25
+ page_assertion :title
26
+ page_assertion :text_present
27
+ page_assertion :text_not_present
28
+ page_assertion :location_ends_with
29
+ deprecate :assert_location_ends_in, :assert_location_ends_with
30
+
31
+ element_assertion :value
32
+ element_assertion :selected
33
+ element_assertion :checked
34
+ element_assertion :not_checked
35
+ element_assertion :text
36
+ element_assertion :element_present
37
+ element_assertion :element_not_present
38
+ element_assertion :next_sibling
39
+ element_assertion :contains_in_order
40
+ element_assertion :visible
41
+ element_assertion :not_visible
42
+
43
+ def assert_attribute(element_locator, attribute_name, expected_value)
44
+ element(element_locator).assert_attribute(attribute_name, expected_value)
45
+ end
46
+
47
+ # Assert and wait for locator element to contain text.
48
+ def assert_element_contains(locator, text, options = {})
49
+ element(locator).assert_contains(text, options)
50
+ end
51
+ alias_method :assert_element_contains_text, :assert_element_contains
52
+
53
+ # Assert and wait for locator element to not contain text.
54
+ def assert_element_does_not_contain(locator, text, options={})
55
+ element(locator).assert_does_not_contain(text, options)
56
+ end
57
+ deprecate :assert_element_does_not_contain_text, :assert_element_does_not_contain
58
+
59
+ # Does the element at locator contain the text?
60
+ def element_contains_text(locator, text)
61
+ element(locator).assert_contains(text)
6
62
  end
7
- attr_writer :configuration
63
+
8
64
  attr_accessor :selenium_driver
9
65
  include WaitFor
10
66
 
@@ -15,14 +71,17 @@ module Polonium
15
71
  Net::HTTP.get(uri)
16
72
  end
17
73
 
18
- # Open the home page of the Application and wait for the page to load.
19
- def open_home_page
20
- selenium_driver.open(configuration.browser_url)
74
+ def configuration
75
+ Polonium::Configuration.instance
21
76
  end
22
77
 
23
78
  protected
24
79
  def method_missing(method_name, *args, &block)
25
- selenium_driver.__send__(method_name, *args, &block)
80
+ if selenium_driver.respond_to?(method_name)
81
+ selenium_driver.__send__(method_name, *args, &block)
82
+ else
83
+ super
84
+ end
26
85
  end
27
86
  delegate :open,
28
87
  :type,