warnold-selenium-client 1.2.19

Sign up to get free protection for your applications and to get access to all the features.
Files changed (33) hide show
  1. data/README.markdown +338 -0
  2. data/examples/rspec/google_spec.rb +41 -0
  3. data/examples/script/google.rb +25 -0
  4. data/examples/testunit/google_test.rb +39 -0
  5. data/lib/nautilus/shell.rb +34 -0
  6. data/lib/selenium.rb +14 -0
  7. data/lib/selenium/client.rb +27 -0
  8. data/lib/selenium/client/base.rb +118 -0
  9. data/lib/selenium/client/driver.rb +11 -0
  10. data/lib/selenium/client/extensions.rb +118 -0
  11. data/lib/selenium/client/idiomatic.rb +488 -0
  12. data/lib/selenium/client/javascript_expression_builder.rb +116 -0
  13. data/lib/selenium/client/javascript_frameworks/jquery.rb +13 -0
  14. data/lib/selenium/client/javascript_frameworks/prototype.rb +13 -0
  15. data/lib/selenium/client/legacy_driver.rb +1711 -0
  16. data/lib/selenium/client/protocol.rb +104 -0
  17. data/lib/selenium/client/selenium_helper.rb +34 -0
  18. data/lib/selenium/command_error.rb +4 -0
  19. data/lib/selenium/protocol_error.rb +4 -0
  20. data/lib/selenium/rake/default_tasks.rb +17 -0
  21. data/lib/selenium/rake/remote_control_start_task.rb +71 -0
  22. data/lib/selenium/rake/remote_control_stop_task.rb +44 -0
  23. data/lib/selenium/rake/tasks.rb +6 -0
  24. data/lib/selenium/remote_control/remote_control.rb +35 -0
  25. data/lib/selenium/rspec/reporting/file_path_strategy.rb +78 -0
  26. data/lib/selenium/rspec/reporting/html_report.rb +155 -0
  27. data/lib/selenium/rspec/reporting/selenium_test_report_formatter.rb +88 -0
  28. data/lib/selenium/rspec/reporting/system_capture.rb +72 -0
  29. data/lib/selenium/rspec/rspec_extensions.rb +104 -0
  30. data/lib/selenium/rspec/spec_helper.rb +34 -0
  31. data/lib/tcp_socket_extension.rb +32 -0
  32. data/test/all_unit_tests.rb +3 -0
  33. metadata +102 -0
@@ -0,0 +1,338 @@
1
+ Welcome to the official Ruby driver for [Selenium Remote Control](http://selenium-rc.openqa.org)
2
+
3
+ Mission
4
+ =======
5
+
6
+ Provide a **lightweight, simple and idiomatic API to write
7
+ Selenium tests in Ruby**. Focus is also on improving test
8
+ feedback -- especially on failures -- by providing
9
+ out-of-the-box **state-of-the-art reporting capabilities**.
10
+ With screenshots, HTML snapshopts and log captures,
11
+ investigating test failures becomes a breeze.
12
+
13
+
14
+ Install It
15
+ ==========
16
+
17
+ The easiest way to install the install selenium-client using RubyGems:
18
+
19
+ sudo gem install selenium-client
20
+
21
+ Features
22
+ ========
23
+
24
+ * Backward compatible with the old-fashioned, XSL generated Selenium Ruby API.
25
+ See [the generated driver](http://selenium-client.rubyforge.org/classes/Selenium/Client/GeneratedDriver.html) to get an extensive reference.
26
+
27
+ * Idiomatic interface to the Selenium API.
28
+ See [the Idiomatic module](http://selenium-client.rubyforge.org/classes/Selenium/Client/Idiomatic.html)
29
+ for more details.
30
+
31
+ * Convenience methods for AJAX.
32
+ See the [Extensions](http://selenium-client.rubyforge.org/classes/Selenium/Client/Extensions.html)
33
+ for more details.
34
+
35
+ * Flexible wait semantics inline with the trigerring action. e.g.
36
+
37
+ * `click 'the_button_id', :wait_for => :page`
38
+ * `click 'the_button_id', :wait_for => :ajax`
39
+ * `click 'the_button_id', :wait_for => :element, :element => 'new_element_id'`
40
+ * `click 'the_button_id', :wait_for => :no_element, :element => 'disappearing_element_id'`
41
+ * `click 'the_button_id', :wait_for => :text, :text => 'New Text'`
42
+ * `click 'the_button_id', :wait_for => :text, :text => /A Regexp/`
43
+ * `click 'the_button_id', :wait_for => :text, :element => 'notification_box', :text => 'New Text'`
44
+ * `click 'the_button_id', :wait_for => :no_text, :text => 'Disappearing Text'`
45
+ * `click 'the_button_id', :wait_for => :no_text, :text => /A Regexp/`
46
+ * `click 'the_button_id', :wait_for => :no_text, :element => 'notification_box', :text => 'Disappearing Text'`
47
+ * `click 'the_button_id', :wait_for => :effects`
48
+ * `click 'the_button_id', :wait_for => :value, :element => 'a_locator', :value => 'some value'`
49
+ * `click 'the_button_id', :wait_for => :no_value, :element => 'a_locator', :value => 'some value'`
50
+ * `click 'the_button_id', :wait_for => :visible, :element => 'a_locator'`
51
+ * `click 'the_button_id', :wait_for => :not_visible, :element => 'a_locator'`
52
+ * `click 'the_button_id', :wait_for => :condition, :javascript => "some arbitrary javascript expression"`
53
+
54
+ Check out the `click`, `go_back` and `wait_for` methods of the [Idiomatic Module](http://selenium-client.rubyforge.org/classes/Selenium/Client/Idiomatic.html)
55
+
56
+ * Leveraging latest innovations in Selenium Remote Control (screenshots, log captures, ...)
57
+
58
+ * Robust Rake task to start/stop the Selenium Remote Control server. More details in the next section.
59
+
60
+ * State-of-the-art reporting for RSpec.
61
+
62
+ Plain API
63
+ =========
64
+
65
+ Selenium client is just a plain Ruby API, so you can use it wherever you can use Ruby.
66
+
67
+ To used the new API just require the client driver:
68
+
69
+ require "rubygems"
70
+ require "selenium/client"
71
+
72
+ For a fully backward compatible API you can start with:
73
+
74
+ require "rubygems"
75
+ gem "selenium-client"
76
+ require "selenium"
77
+
78
+ For instance
79
+ to write a little Ruby script using selenium-client you could write something like:
80
+
81
+ #!/usr/bin/env ruby
82
+ #
83
+ # Sample Ruby script using the Selenium client API
84
+ #
85
+ require "rubygems"
86
+ gem "selenium-client", ">=1.2.16"
87
+ require "selenium/client"
88
+
89
+ begin
90
+ @browser = Selenium::Client::Driver.new \
91
+ :host => "localhost",
92
+ :port => 4444,
93
+ :browser => "*firefox",
94
+ :url => "http://www.google.com",
95
+ :timeout_in_second => 60
96
+
97
+ @browser.start_new_browser_session
98
+ @browser.open "/"
99
+ @browser.type "q", "Selenium seleniumhq.org"
100
+ @browser.click "btnG", :wait_for => :page
101
+ puts @browser.text?("seleniumhq.org")
102
+ ensure
103
+ @browser.close_current_browser_session
104
+ end
105
+
106
+
107
+ Writing Tests
108
+ =============
109
+
110
+ Most likely you will be writing functional and acceptance tests using selenium-client. If you are a
111
+ `Test::Unit` fan your tests will look like:
112
+
113
+ #!/usr/bin/env ruby
114
+ #
115
+ # Sample Test:Unit based test case using the selenium-client API
116
+ #
117
+ require "test/unit"
118
+ require "rubygems"
119
+ gem "selenium-client", ">=1.2.16"
120
+ require "selenium/client"
121
+
122
+ class ExampleTest < Test::Unit::TestCase
123
+ attr_reader :browser
124
+
125
+ def setup
126
+ @browser = Selenium::Client::Driver.new \
127
+ :host => "localhost",
128
+ :port => 4444,
129
+ :browser => "*firefox",
130
+ :url => "http://www.google.com",
131
+ :timeout_in_second => 60
132
+
133
+ browser.start_new_browser_session
134
+ end
135
+
136
+ def teardown
137
+ browser.close_current_browser_session
138
+ end
139
+
140
+ def test_page_search
141
+ browser.open "/"
142
+ assert_equal "Google", browser.title
143
+ browser.type "q", "Selenium seleniumhq"
144
+ browser.click "btnG", :wait_for => :page
145
+ assert_equal "Selenium seleniumhq - Google Search", browser.title
146
+ assert_equal "Selenium seleniumhq", browser.field("q")
147
+ assert browser.text?("seleniumhq.org")
148
+ assert browser.element?("link=Cached")
149
+ end
150
+
151
+ end
152
+
153
+ If BDD is more your style, here is how you can achieve the same thing using RSpec:
154
+
155
+ require 'rubygems'
156
+ gem "rspec", ">=1.2.8"
157
+ gem "selenium-client", ">=1.2.16"
158
+ require "selenium/client"
159
+ require "selenium/rspec/spec_helper"
160
+
161
+ describe "Google Search" do
162
+ attr_reader :selenium_driver
163
+ alias :page :selenium_driver
164
+
165
+ before(:all) do
166
+ @selenium_driver = Selenium::Client::Driver.new \
167
+ :host => "localhost",
168
+ :port => 4444,
169
+ :browser => "*firefox",
170
+ :url => "http://www.google.com",
171
+ :timeout_in_second => 60
172
+ end
173
+
174
+ before(:each) do
175
+ selenium_driver.start_new_browser_session
176
+ end
177
+
178
+ # The system capture need to happen BEFORE closing the Selenium session
179
+ append_after(:each) do
180
+ @selenium_driver.close_current_browser_session
181
+ end
182
+
183
+ it "can find Selenium" do
184
+ page.open "/"
185
+ page.title.should eql("Google")
186
+ page.type "q", "Selenium seleniumhq"
187
+ page.click "btnG", :wait_for => :page
188
+ page.value("q").should eql("Selenium seleniumhq")
189
+ page.text?("seleniumhq.org").should be_true
190
+ page.title.should eql("Selenium seleniumhq - Google Search")
191
+ page.text?("seleniumhq.org").should be_true
192
+ page.element?("link=Cached").should be_true
193
+ end
194
+
195
+ end
196
+
197
+ Start/Stop a Selenium Remote Control Server
198
+ ===========================================
199
+
200
+ Selenium client comes with some convenient Rake tasks to start/stop a Remote Control server.
201
+ To leverage the latest selenium-client capabilities, you may need to download
202
+ a recent nightly build of a standalone packaging of Selenium Remote
203
+ Control. You will find the nightly build at
204
+ http://nexus.openqa.org/content/repositories/snapshots/org/seleniumhq/selenium/server/selenium-server/
205
+
206
+ You typically "freeze" the Selenium Remote Control jar in your `vendor`
207
+ directory.
208
+
209
+ require 'selenium/rake/tasks'
210
+
211
+ Selenium::Rake::RemoteControlStartTask.new do |rc|
212
+ rc.port = 4444
213
+ rc.timeout_in_seconds = 3 * 60
214
+ rc.background = true
215
+ rc.wait_until_up_and_running = true
216
+ rc.jar_file = "/path/to/where/selenium-rc-standalone-jar-is-installed"
217
+ rc.additional_args << "-singleWindow"
218
+ end
219
+
220
+ Selenium::Rake::RemoteControlStopTask.new do |rc|
221
+ rc.host = "localhost"
222
+ rc.port = 4444
223
+ rc.timeout_in_seconds = 3 * 60
224
+ end
225
+
226
+ If you do not explicitly specify the path to selenium remote control jar
227
+ it will be "auto-discovered" in `vendor` directory using the following
228
+ path : `vendor/selenium-remote-control/selenium-server*-standalone.jar`
229
+
230
+ Check out [RemoteControlStartTask](http://selenium-client.rubyforge.org/classes/Selenium/Rake/RemoteControlStartTask.html) and [RemoteControlStopTask](http://selenium-client.rubyforge.org/classes/Selenium/Rake/RemoteControlStopTask.html) for more
231
+ details.
232
+
233
+ State-of-the-Art RSpec Reporting
234
+ ================================
235
+
236
+ Selenium Client comes with out-of-the-box RSpec reporting that include HTML snapshots, O.S. screenshots, in-browser page
237
+ screenshots (not limited to current viewport), and a capture of the latest remote controls for all failing tests. And all
238
+ course all this works even if your infrastructure is distributed (In particular in makes wonders with [Selenium
239
+ Grid](http://selenium-grid.openqa.org))
240
+
241
+ Using selenium-client RSpec reporting is as simple as using `SeleniumTestReportFormatter` as one of you RSpec formatters. For instance:
242
+
243
+ require 'spec/rake/spectask'
244
+ desc 'Run acceptance tests for web application'
245
+ Spec::Rake::SpecTask.new(:'test:acceptance:web') do |t|
246
+ t.libs << "test"
247
+ t.pattern = "test/*_spec.rb"
248
+ t.spec_opts << '--color'
249
+ t.spec_opts << "--require 'rubygems,selenium/rspec/reporting/selenium_test_report_formatter'"
250
+ t.spec_opts << "--format=Selenium::RSpec::SeleniumTestReportFormatter:./tmp/acceptance_tests_report.html"
251
+ t.spec_opts << "--format=progress"
252
+ t.verbose = true
253
+ end
254
+
255
+ You can then get cool reports like [this one](http://ph7spot.com/examples/selenium_rspec_report.html)
256
+
257
+ To capture screenshots and logs on failures, also make sure you
258
+ require the following files in your `spec_helper`:
259
+
260
+ require "rubygems"
261
+ require "spec"
262
+ require "selenium/client"
263
+ require "selenium/rspec/spec_helper"
264
+
265
+ Other Resources
266
+ ===============
267
+
268
+ * Report bugs at http://github.com/ph7/selenium-client/issues
269
+ * Browse API at http://selenium-client.rubyforge.org
270
+
271
+
272
+ Contribute and Join the Fun!
273
+ ============================
274
+
275
+ We welcome new features, add-ons, bug fixes, example, documentation,
276
+ etc. Make the gem work the way you envision!
277
+
278
+ * Report bugs at http://github.com/ph7/selenium-client/issues
279
+
280
+ * I recommend cloning the selenium-client
281
+ [reference repository](http://github.com/ph7/selenium-client/tree/master)
282
+
283
+ * You can also check out the [RubyForge page](http://rubyforge.org/projects/selenium-client)
284
+ and the [RDoc](http://selenium-client.rubyforge.org)
285
+
286
+ * We also have a [continuous integration server](http://xserve.openqa.org:8080/view/Ruby%20Client)
287
+
288
+ * Stories live in [Pivotal Tracker](https://www.pivotaltracker.com/projects/6280)
289
+ * To build, run `rake clean default package`. You can then install the
290
+ generated gem with `sudo gem install pkg/*.gem`
291
+ * You can also run all integration tests with `rake ci:integration`
292
+
293
+
294
+ Core Team
295
+ =========
296
+
297
+ * Philippe Hanrigou (`ph7`): Current Maintainer and main contributor
298
+ * Aslak Hellesoy and Darren Hobbs : Original version of the Selenium Ruby driver
299
+
300
+ Contributors
301
+ ============
302
+
303
+ * Aaron Tinio (`aptinio`):
304
+ - More robust Selenium RC shutdown
305
+ - Support for locator including single quotes in `wait_for_...` methods
306
+ - Do not capture system state on execution errors for pending examples
307
+ (ExamplePendingError, NotYetImplementedError)
308
+ - Auto-highlighting support
309
+
310
+ * Rick Lee-Morlang (`rleemorlang`):
311
+ - Fix for incremental calls to `wait_for_text`
312
+ - Regex support in `wait_for_text`
313
+
314
+ * [Paul Boone](http://www.mindbucket.com) (`paulboone`)
315
+ - Fixed method_missing in selenium_helper to only delegate to methods
316
+ that @selenium responds to
317
+
318
+ * [Adam Greene](http://blog.sweetspot.dm) (`skippy`)
319
+ - Added the ability to redirect output to a log file, when
320
+ launching Selenium Remote Control with the Rake task
321
+
322
+ * [Eliot Sykes](http://blog.eliotsykes.com) (`eliotsykes`)
323
+ - wait_for_visibility [patch](http://github.com/eliotsykes/selenium-client/commit/4c7f3d01aa75a6b1917fbf71335b0069392ed546)
324
+
325
+ * [Frederik Fix](http://github.com/derfred)(`derfred`)
326
+ - Fix escaping bug when dealing with embedded regexes such as
327
+ "webratlink=evalregex:/Pastry Lovers \\(Organizer\\)/"
328
+ [patch](http://github.com/derfred/selenium-client/commit/4342cbb39d1a92b8db8f26ee0dc6c1a8f3287737)
329
+
330
+ * [Alex Chaffe](http://alexch.github.com)
331
+ - Better error reporting and fixed bug where if the response
332
+ doesn't start with "OK" it swallows the first three
333
+ chars (leading to annoying "ed out after 5000 msec" messages)
334
+
335
+ * [Jeffrey ODell](http://github.com/jodell)
336
+ - [nohup support path](http://github.com/jodell/selenium-client/commit/66fdcb296f73b2f85d7e4bc38aa14cf0e2a27706)
337
+
338
+
@@ -0,0 +1,41 @@
1
+ require 'rubygems'
2
+ gem "rspec", ">=1.2.8"
3
+ gem "selenium-client", ">=1.2.18"
4
+ require "selenium/client"
5
+ require "selenium/rspec/spec_helper"
6
+
7
+ describe "Google Search" do
8
+ attr_reader :selenium_driver
9
+ alias :page :selenium_driver
10
+
11
+ before(:all) do
12
+ @selenium_driver = Selenium::Client::Driver.new \
13
+ :host => "localhost",
14
+ :port => 4444,
15
+ :browser => "*firefox",
16
+ :url => "http://www.google.com",
17
+ :timeout_in_second => 60
18
+ end
19
+
20
+ before(:each) do
21
+ selenium_driver.start_new_browser_session
22
+ end
23
+
24
+ # The system capture need to happen BEFORE closing the Selenium session
25
+ append_after(:each) do
26
+ @selenium_driver.close_current_browser_session
27
+ end
28
+
29
+ it "can find Selenium" do
30
+ page.open "/"
31
+ page.title.should eql("Google")
32
+ page.type "q", "Selenium seleniumhq"
33
+ page.click "btnG", :wait_for => :page
34
+ page.value("q").should eql("Selenium seleniumhq")
35
+ page.text?("seleniumhq.org").should be_true
36
+ page.title.should eql("Selenium seleniumhq - Google Search")
37
+ page.text?("seleniumhq.org").should be_true
38
+ page.element?("link=Cached").should be_true
39
+ end
40
+
41
+ end
@@ -0,0 +1,25 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # Sample Ruby script using the Selenium client API
4
+ #
5
+ require "rubygems"
6
+ gem "selenium-client", ">=1.2.18"
7
+ require "selenium/client"
8
+
9
+ begin
10
+ @browser = Selenium::Client::Driver.new \
11
+ :host => "localhost",
12
+ :port => 4444,
13
+ :browser => "*firefox",
14
+ :url => "http://www.google.com",
15
+ :timeout_in_second => 60
16
+
17
+ @browser.start_new_browser_session
18
+ @browser.open "/"
19
+ @browser.type "q", "Selenium seleniumhq.org"
20
+ @browser.click "btnG", :wait_for => :page
21
+ puts @browser.text?("seleniumhq.org")
22
+ ensure
23
+ @browser.close_current_browser_session
24
+ end
25
+
@@ -0,0 +1,39 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # Sample Test:Unit based test case using the selenium-client API
4
+ #
5
+ require "test/unit"
6
+ require "rubygems"
7
+ gem "selenium-client", ">=1.2.18"
8
+ require "selenium/client"
9
+
10
+ class ExampleTest < Test::Unit::TestCase
11
+ attr_reader :browser
12
+
13
+ def setup
14
+ @browser = Selenium::Client::Driver.new \
15
+ :host => "localhost",
16
+ :port => 4444,
17
+ :browser => "*firefox",
18
+ :url => "http://www.google.com",
19
+ :timeout_in_second => 60
20
+
21
+ browser.start_new_browser_session
22
+ end
23
+
24
+ def teardown
25
+ browser.close_current_browser_session
26
+ end
27
+
28
+ def test_page_search
29
+ browser.open "/"
30
+ assert_equal "Google", browser.title
31
+ browser.type "q", "Selenium seleniumhq"
32
+ browser.click "btnG", :wait_for => :page
33
+ assert_equal "Selenium seleniumhq - Google Search", browser.title
34
+ assert_equal "Selenium seleniumhq", browser.field("q")
35
+ assert browser.text?("seleniumhq.org")
36
+ assert browser.element?("link=Cached")
37
+ end
38
+
39
+ end
@@ -0,0 +1,34 @@
1
+ module Nautilus
2
+
3
+ class Shell
4
+
5
+ def run(command, options = {})
6
+ sh build_command(command, options)
7
+ end
8
+
9
+ def build_command(command, options = {})
10
+ actual_command = command.kind_of?(Array) ? command.join(" ") : command
11
+ if options[:background]
12
+ actual_command = if windows?
13
+ "start /wait /b #{actual_command}"
14
+ elsif options[:nohup]
15
+ "nohup #{actual_command} &"
16
+ else
17
+ "#{actual_command} &"
18
+ end
19
+ end
20
+ actual_command
21
+ end
22
+
23
+ def windows?
24
+ RUBY_PLATFORM =~ /mswin/
25
+ end
26
+
27
+ def sh(command)
28
+ successful = system(command)
29
+ raise "Error while running >>#{command}<<" unless successful
30
+ end
31
+
32
+ end
33
+
34
+ end