polonium 0.1.1 → 0.2.0

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 (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,