polonium 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (34) hide show
  1. data/CHANGES +10 -0
  2. data/README +38 -0
  3. data/Rakefile +68 -0
  4. data/lib/polonium.rb +28 -0
  5. data/lib/polonium/configuration.rb +271 -0
  6. data/lib/polonium/driver.rb +155 -0
  7. data/lib/polonium/dsl/selenium_dsl.rb +33 -0
  8. data/lib/polonium/dsl/test_unit_dsl.rb +58 -0
  9. data/lib/polonium/element.rb +207 -0
  10. data/lib/polonium/extensions/module.rb +8 -0
  11. data/lib/polonium/extensions/testrunnermediator.rb +22 -0
  12. data/lib/polonium/mongrel_selenium_server_runner.rb +37 -0
  13. data/lib/polonium/page.rb +84 -0
  14. data/lib/polonium/selenium_helper.rb +5 -0
  15. data/lib/polonium/server_runner.rb +33 -0
  16. data/lib/polonium/tasks/selenium_test_task.rb +21 -0
  17. data/lib/polonium/test_case.rb +93 -0
  18. data/lib/polonium/wait_for.rb +40 -0
  19. data/lib/polonium/webrick_selenium_server_runner.rb +33 -0
  20. data/spec/polonium/extensions/module_spec.rb +29 -0
  21. data/spec/polonium/extensions/testrunnermediator_spec.rb +19 -0
  22. data/spec/polonium/mongrel_selenium_server_runner_spec.rb +35 -0
  23. data/spec/polonium/selenium_configuration_spec.rb +359 -0
  24. data/spec/polonium/selenium_driver_spec.rb +104 -0
  25. data/spec/polonium/selenium_element_spec.rb +551 -0
  26. data/spec/polonium/selenium_page_spec.rb +249 -0
  27. data/spec/polonium/selenium_server_runner_spec.rb +42 -0
  28. data/spec/polonium/selenium_test_case_class_method_spec.rb +41 -0
  29. data/spec/polonium/selenium_test_case_spec.rb +870 -0
  30. data/spec/polonium/selenium_test_case_spec_helper.rb +16 -0
  31. data/spec/polonium/webrick_selenium_server_runner_spec.rb +117 -0
  32. data/spec/spec_helper.rb +63 -0
  33. data/spec/spec_suite.rb +6 -0
  34. metadata +82 -0
@@ -0,0 +1,33 @@
1
+ module Polonium
2
+ module SeleniumDsl
3
+ # The Configuration object.
4
+ def configuration
5
+ @configuration ||= Configuration.instance
6
+ end
7
+ attr_writer :configuration
8
+ attr_accessor :selenium_driver
9
+ include WaitFor
10
+
11
+ # Download a file from the Application Server
12
+ def download(path)
13
+ uri = URI.parse(configuration.browser_url + path)
14
+ puts "downloading #{uri.to_s}"
15
+ Net::HTTP.get(uri)
16
+ end
17
+
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)
21
+ end
22
+
23
+ protected
24
+ Driver.public_instance_methods(false).each do |method_name|
25
+ delegate method_name, :to => :selenium_driver
26
+ end
27
+
28
+ def should_stop_driver?
29
+ return false unless configuration.test_browser_mode?
30
+ configuration.stop_driver?(passed?)
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,58 @@
1
+ module Polonium
2
+ module TestUnitDsl
3
+ include SeleniumDsl
4
+ class << self
5
+ def page_assertion(name)
6
+ module_eval(
7
+ "def assert_#{name}(value, params={})\n" +
8
+ " page.assert_#{name}(value, params)\n" +
9
+ "end",
10
+ __FILE__,
11
+ __LINE__ - 4
12
+ )
13
+ end
14
+
15
+ def element_assertion(name)
16
+ module_eval(
17
+ "def assert_#{name}(locator, *args)\n" +
18
+ " element(locator).assert_#{name}(*args)\n" +
19
+ "end",
20
+ __FILE__,
21
+ __LINE__ - 4
22
+ )
23
+ end
24
+ end
25
+
26
+ page_assertion :title
27
+ page_assertion :text_present
28
+ page_assertion :text_not_present
29
+ page_assertion :location_ends_with
30
+ deprecate :assert_location_ends_in, :assert_location_ends_with
31
+
32
+ element_assertion :value
33
+ element_assertion :attribute # yes, it's a little weird... in this case element is really an attribute
34
+ element_assertion :selected
35
+ element_assertion :checked
36
+ element_assertion :not_checked
37
+ element_assertion :text
38
+ element_assertion :element_present
39
+ element_assertion :element_not_present
40
+ element_assertion :next_sibling
41
+ element_assertion :contains_in_order
42
+ element_assertion :visible
43
+ element_assertion :not_visible
44
+
45
+ # Assert and wait for locator element to contain text.
46
+ def assert_element_contains(locator, text, options = {})
47
+ element(locator).assert_contains(text, options)
48
+ end
49
+
50
+ # Assert and wait for locator element to not contain text.
51
+ def assert_element_does_not_contain(locator, text, options={})
52
+ element(locator).assert_does_not_contain(text, options)
53
+ end
54
+ deprecate :assert_element_does_not_contain_text, :assert_element_does_not_contain
55
+ deprecate :wait_for_element_to_not_contain_text, :assert_element_does_not_contain
56
+ deprecate :wait_for_text_in_order, :assert_contains_in_order
57
+ end
58
+ end
@@ -0,0 +1,207 @@
1
+ module Polonium
2
+ class Element
3
+ include WaitFor
4
+ attr_reader :driver, :locator
5
+
6
+ def initialize(driver, locator)
7
+ @driver = driver
8
+ @locator = locator
9
+ end
10
+
11
+ def assert_element_present(params={})
12
+ driver.wait_for_is_element_present(locator, params)
13
+ end
14
+
15
+ def assert_element_not_present(params={})
16
+ driver.wait_for_is_element_not_present(locator, params)
17
+ end
18
+
19
+ def assert_value(expected_value)
20
+ assert_element_present
21
+ wait_for do |configuration|
22
+ actual_value = driver.get_value(locator)
23
+ configuration.message = "Expected '#{locator}' to be '#{expected_value}' but was '#{actual_value}'"
24
+ has_value? expected_value, actual_value
25
+ end
26
+ end
27
+
28
+ def assert_attribute(expected_value)
29
+ assert_element_present
30
+ wait_for do |configuration|
31
+ actual = driver.get_attribute(locator) #todo: actual value
32
+ configuration.message = "Expected attribute '#{locator}' to be '#{expected_value}' but was '#{actual}'"
33
+ expected_value == actual
34
+ end
35
+ end
36
+
37
+ def assert_selected(expected_value)
38
+ assert_element_present
39
+ wait_for do |configuration|
40
+ actual = driver.get_selected_label(locator)
41
+ configuration.message = "Expected '#{locator}' to be selected with '#{expected_value}' but was '#{actual}"
42
+ expected_value == actual
43
+ end
44
+ end
45
+
46
+ def assert_visible(options={})
47
+ assert_element_present
48
+ options = {
49
+ :message => "Expected '#{locator}' to be visible, but it wasn't"
50
+ }.merge(options)
51
+ wait_for(options) do
52
+ driver.is_visible(locator)
53
+ end
54
+ end
55
+
56
+ def assert_not_visible(options={})
57
+ assert_element_present
58
+ options = {
59
+ :message => "Expected '#{locator}' to be hidden, but it wasn't"
60
+ }.merge(options)
61
+ wait_for(options) do
62
+ !driver.is_visible(locator)
63
+ end
64
+ end
65
+
66
+ def assert_checked
67
+ assert_element_present
68
+ wait_for(:message => "Expected '#{locator}' to be checked") do
69
+ driver.is_checked(locator)
70
+ end
71
+ end
72
+
73
+ def assert_not_checked
74
+ assert_element_present
75
+ wait_for(:message => "Expected '#{locator}' to be checked") do
76
+ !driver.is_checked(locator)
77
+ end
78
+ end
79
+
80
+ def assert_text(expected_text, options={})
81
+ assert_element_present
82
+ wait_for(options) do |configuration|
83
+ actual = driver.get_text(locator)
84
+ configuration.message = "Expected text '#{expected_text}' to be full contents of #{locator} but was '#{actual}')"
85
+ expected_text == actual
86
+ end
87
+ end
88
+
89
+ def assert_contains(expected_text, options={})
90
+ return assert_contains_in_order(*expected_text) if expected_text.is_a? Array
91
+ assert_element_present
92
+ options = {
93
+ :message => "#{locator} should contain #{expected_text}"
94
+ }.merge(options)
95
+ wait_for(options) do
96
+ contains?(expected_text)
97
+ end
98
+ end
99
+
100
+ def assert_does_not_contain(expected_text, options={})
101
+ assert_element_present
102
+ wait_for(options) do
103
+ !inner_html.include?(expected_text)
104
+ end
105
+ end
106
+
107
+ def assert_next_sibling(expected_sibling_id, options = {})
108
+ assert_element_present
109
+ eval_js = "this.page().findElement('#{locator}').nextSibling.id"
110
+ wait_for(:message => "id '#{locator}' should be next to '#{expected_sibling_id}'") do
111
+ actual_sibling_id = driver.get_eval(eval_js)
112
+ expected_sibling_id == actual_sibling_id
113
+ end
114
+ end
115
+
116
+ def assert_contains_in_order(*text_fragments)
117
+ assert_element_present
118
+ wait_for do |configuration|
119
+ success = false
120
+
121
+ html = driver.get_text(locator)
122
+ results = find_text_order_error_fragments(html, text_fragments)
123
+ fragments_not_found = results[:fragments_not_found]
124
+ fragments_out_of_order = results[:fragments_out_of_order]
125
+
126
+ if !fragments_not_found.empty?
127
+ configuration.message = "Certain fragments weren't found:\n" <<
128
+ "#{fragments_not_found.join("\n")}\n" <<
129
+ "\nhtml follows:\n #{html}\n"
130
+ elsif !fragments_out_of_order.empty?
131
+ configuration.message = "Certain fragments were out of order:\n" <<
132
+ "#{fragments_out_of_order.join("\n")}\n" <<
133
+ "\nhtml follows:\n #{html}\n"
134
+ else
135
+ success = true
136
+ end
137
+
138
+ success
139
+ end
140
+ end
141
+
142
+
143
+ def is_present?
144
+ driver.is_element_present(locator)
145
+ end
146
+
147
+ def is_not_present?
148
+ !driver.is_element_present(locator)
149
+ end
150
+
151
+ def has_value?(expected_value, actual_value=driver.get_value(locator))
152
+ expected_value == actual_value
153
+ end
154
+
155
+ def inner_html
156
+ driver.get_inner_html(locator)
157
+ end
158
+
159
+ def contains?(text)
160
+ inner_html.include?(text)
161
+ end
162
+
163
+ def ==(other)
164
+ return false unless other.is_a?(Element)
165
+ return false unless self.driver == other.driver
166
+ return false unless self.locator == other.locator
167
+ true
168
+ end
169
+
170
+ protected
171
+ def method_missing(method_name, *args, &blk)
172
+ if driver.respond_to?(method_name)
173
+ driver_args = [locator] + args
174
+ driver.__send__(method_name, *driver_args, &blk)
175
+ else
176
+ super
177
+ end
178
+ end
179
+
180
+ def find_text_order_error_fragments(html, text_fragments)
181
+ fragments_not_found = []
182
+ fragments_out_of_order = []
183
+
184
+ previous_index = -1
185
+ previous_fragment = ''
186
+ text_fragments.each do |current_fragment|
187
+ current_index = html.index(current_fragment)
188
+ if current_index
189
+ if current_index < previous_index
190
+ message = "Fragment #{current_fragment} out of order:\n" <<
191
+ "\texpected '#{previous_fragment}'\n" <<
192
+ "\tto come before '#{current_fragment}'\n"
193
+ fragments_out_of_order << message
194
+ end
195
+ else
196
+ fragments_not_found << "Fragment #{current_fragment} was not found\n"
197
+ end
198
+ previous_index = current_index
199
+ previous_fragment = current_fragment
200
+ end
201
+ {
202
+ :fragments_not_found => fragments_not_found,
203
+ :fragments_out_of_order => fragments_out_of_order
204
+ }
205
+ end
206
+ end
207
+ end
@@ -0,0 +1,8 @@
1
+ class Module
2
+ def deprecate(old_method_name, new_method_name)
3
+ define_method old_method_name do |*args|
4
+ warn "#{old_method_name} is deprecated. Use #{new_method_name} instead."
5
+ __send__(new_method_name, *args)
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,22 @@
1
+ class Test::Unit::UI::TestRunnerMediator
2
+ alias_method :run_suite_without_seleniumrc, :run_suite
3
+ def run_suite_with_seleniumrc
4
+ start_app_server
5
+ result = run_suite_without_seleniumrc
6
+ stop_app_server(result)
7
+ result
8
+ end
9
+ alias_method :run_suite, :run_suite_with_seleniumrc
10
+
11
+ protected
12
+ def start_app_server
13
+ @selenium_driver = Polonium::Configuration.instance
14
+ @app_runner = @selenium_driver.create_server_runner
15
+ @app_runner.start
16
+ end
17
+
18
+ def stop_app_server(result)
19
+ @app_runner.stop
20
+ @selenium_driver.stop_driver_if_necessary(result.passed?)
21
+ end
22
+ end
@@ -0,0 +1,37 @@
1
+ module Polonium
2
+ class MongrelSeleniumServerRunner < ServerRunner
3
+ def start
4
+ mongrel_configurator = configuration.create_mongrel_configurator
5
+ initialize_server(mongrel_configurator)
6
+
7
+ @thread_class.start do
8
+ start_server(mongrel_configurator)
9
+ end
10
+ @started = true
11
+ end
12
+
13
+ protected
14
+ def start_server(mongrel_configurator)
15
+ mongrel_configurator.run
16
+ mongrel_configurator.log "Mongrel running at #{configuration.internal_app_server_host}:#{configuration.internal_app_server_port}"
17
+ mongrel_configurator.join
18
+ end
19
+
20
+ def initialize_server(config)
21
+ configuration = self.configuration
22
+ config.listener do |*args|
23
+ mongrel = (args.first || self)
24
+ mongrel.log "Starting Rails in environment #{defaults[:environment]} ..."
25
+ mongrel.uri "/", :handler => mongrel.rails
26
+ mongrel.log "Rails loaded."
27
+
28
+ mongrel.log "Loading any Rails specific GemPlugins"
29
+ mongrel.load_plugins
30
+ configuration.app_server_initialization.call(mongrel)
31
+ end
32
+ end
33
+
34
+ def stop_server
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,84 @@
1
+ module Polonium
2
+ class Page
3
+ include WaitFor
4
+ attr_reader :driver
5
+ PAGE_LOADED_COMMAND = "this.browserbot.getDocument().body ? true : false"
6
+
7
+ def initialize(driver)
8
+ @driver = driver
9
+ end
10
+
11
+ def open(url)
12
+ driver.open(url)
13
+ end
14
+ alias_method :open_and_wait, :open
15
+
16
+ def assert_title(expected_title, params = {})
17
+ wait_for(params) do |configuration|
18
+ actual_title = title
19
+ configuration.message = "Expected title '#{expected_title}' but was '#{actual_title}'"
20
+ expected_title == actual_title
21
+ end
22
+ end
23
+ def title
24
+ driver.get_title
25
+ end
26
+
27
+ def assert_text_present(expected_text, options = {})
28
+ options = {
29
+ :message => "Expected '#{expected_text}' to be present, but it wasn't"
30
+ }.merge(options)
31
+ wait_for(options) do
32
+ is_text_present? expected_text
33
+ end
34
+ end
35
+ def is_text_present?(expected_text)
36
+ page_loaded? && driver.is_text_present(expected_text)
37
+ end
38
+
39
+ def assert_text_not_present(unexpected_text, options = {})
40
+ options = {
41
+ :message => "Expected '#{unexpected_text}' to be absent, but it wasn't"
42
+ }.merge(options)
43
+ wait_for(options) do
44
+ is_text_not_present? unexpected_text
45
+ end
46
+ end
47
+ def is_text_not_present?(unexpected_text)
48
+ page_loaded? && !driver.is_text_present(unexpected_text)
49
+ end
50
+
51
+ def page_loaded?
52
+ driver.get_eval(PAGE_LOADED_COMMAND) == true.to_s
53
+ end
54
+
55
+ def assert_location_ends_with(ends_with, options ={})
56
+ options = {
57
+ :message => "Expected '#{driver.get_location}' to end with '#{ends_with}'"
58
+ }.merge(options)
59
+ wait_for(options) do
60
+ location_ends_with? ends_with
61
+ end
62
+ end
63
+ def location_ends_with?(ends_with)
64
+ if driver.get_location =~ Regexp.new("#{Regexp.escape(ends_with)}$")
65
+ true
66
+ else
67
+ false
68
+ end
69
+ end
70
+
71
+ def ==(other)
72
+ return false unless other.is_a?(Page)
73
+ self.driver == other.driver
74
+ end
75
+
76
+ def method_missing(method_name, *args, &blk)
77
+ if driver.respond_to?(method_name)
78
+ driver.__send__(method_name, *args, &blk)
79
+ else
80
+ super
81
+ end
82
+ end
83
+ end
84
+ end