selenium-client 1.2.14 → 1.2.15
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.
- data/README.markdown +42 -15
- data/examples/rspec/google_spec.rb +3 -3
- data/examples/script/google.rb +1 -1
- data/examples/testunit/google_test.rb +1 -1
- data/lib/selenium/client.rb +2 -1
- data/lib/selenium/client/base.rb +10 -2
- data/lib/selenium/client/generated_driver.rb +4 -4
- data/lib/selenium/client/idiomatic.rb +32 -0
- data/lib/selenium/client/protocol.rb +1 -1
- data/lib/selenium/client/selenium_helper.rb +14 -16
- data/lib/selenium/rake/remote_control_start_task.rb +26 -2
- data/lib/selenium/rake/remote_control_stop_task.rb +8 -0
- data/lib/selenium/remote_control/remote_control.rb +2 -1
- data/lib/selenium/rspec/reporting/file_path_strategy.rb +19 -13
- data/lib/selenium/rspec/reporting/html_report.rb +2 -2
- data/lib/selenium/rspec/reporting/selenium_test_report_formatter.rb +12 -22
- data/lib/selenium/rspec/reporting/system_capture.rb +2 -2
- data/lib/selenium/rspec/rspec_extensions.rb +62 -12
- data/lib/selenium/rspec/spec_helper.rb +3 -1
- metadata +6 -4
data/README.markdown
CHANGED
@@ -10,6 +10,7 @@ Mission
|
|
10
10
|
With screenshots, HTML snapshopts and log captures,
|
11
11
|
investigating test failures becomes a breeze.
|
12
12
|
|
13
|
+
|
13
14
|
Install It
|
14
15
|
==========
|
15
16
|
|
@@ -80,7 +81,7 @@ Plain API
|
|
80
81
|
# Sample Ruby script using the Selenium client API
|
81
82
|
#
|
82
83
|
require "rubygems"
|
83
|
-
gem "selenium-client", ">=1.2.
|
84
|
+
gem "selenium-client", ">=1.2.15"
|
84
85
|
require "selenium/client"
|
85
86
|
|
86
87
|
begin
|
@@ -113,7 +114,7 @@ Writing Tests
|
|
113
114
|
#
|
114
115
|
require "test/unit"
|
115
116
|
require "rubygems"
|
116
|
-
gem "selenium-client", ">=1.2.
|
117
|
+
gem "selenium-client", ">=1.2.15"
|
117
118
|
require "selenium/client"
|
118
119
|
|
119
120
|
class ExampleTest < Test::Unit::TestCase
|
@@ -150,8 +151,8 @@ Writing Tests
|
|
150
151
|
If BDD is more your style, here is how you can achieve the same thing using RSpec:
|
151
152
|
|
152
153
|
require 'rubygems'
|
153
|
-
gem "rspec", "=1.
|
154
|
-
gem "selenium-client", ">=1.2.
|
154
|
+
gem "rspec", "=1.2.6"
|
155
|
+
gem "selenium-client", ">=1.2.15"
|
155
156
|
require "selenium/client"
|
156
157
|
require "selenium/rspec/spec_helper"
|
157
158
|
|
@@ -218,8 +219,12 @@ Start/Stop a Selenium Remote Control Server
|
|
218
219
|
rc.port = 4444
|
219
220
|
rc.timeout_in_seconds = 3 * 60
|
220
221
|
end
|
221
|
-
|
222
|
-
|
222
|
+
|
223
|
+
If you do not explicitly specify the path to selenium remote control jar
|
224
|
+
it will be "auto-discovered" in `vendor` directory using the following
|
225
|
+
path : `vendor/selenium-remote-control/selenium-server*-standalone.jar`
|
226
|
+
|
227
|
+
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
|
223
228
|
details.
|
224
229
|
|
225
230
|
State-of-the-Art RSpec Reporting
|
@@ -254,20 +259,34 @@ Grid](http://selenium-grid.openqa.org))
|
|
254
259
|
require "selenium/client"
|
255
260
|
require "selenium/rspec/spec_helper"
|
256
261
|
|
262
|
+
Other Resources
|
263
|
+
===============
|
264
|
+
|
265
|
+
* Report bugs at http://github.com/ph7/selenium-client/issues
|
266
|
+
* Browse API at http://selenium-client.rubyforge.org
|
267
|
+
|
257
268
|
|
258
269
|
Contribute and Join the Fun!
|
259
270
|
============================
|
260
271
|
|
261
|
-
We welcome new features, add-ons, bug fixes, example, documentation,
|
262
|
-
envision!
|
272
|
+
We welcome new features, add-ons, bug fixes, example, documentation,
|
273
|
+
etc. Make the gem work the way you envision!
|
274
|
+
|
275
|
+
* Report bugs at http://github.com/ph7/selenium-client/issues
|
263
276
|
|
264
|
-
* I recommend cloning the selenium-client
|
277
|
+
* I recommend cloning the selenium-client
|
278
|
+
[reference repository](http://github.com/ph7/selenium-client/tree/master)
|
265
279
|
|
266
|
-
* You can also check out the [RubyForge page](http://rubyforge.org/projects/selenium-client)
|
280
|
+
* You can also check out the [RubyForge page](http://rubyforge.org/projects/selenium-client)
|
281
|
+
and the [RDoc](http://selenium-client.rubyforge.org)
|
267
282
|
|
268
283
|
* We also have a [continuous integration server](http://xserve.openqa.org:8080/view/Ruby%20Client)
|
269
284
|
|
270
285
|
* Stories live in [Pivotal Tracker](https://www.pivotaltracker.com/projects/6280)
|
286
|
+
* To build, run `rake clean default package`. You can then install the
|
287
|
+
generated gem with `sudo gem install pkg/*.gem`
|
288
|
+
* You can also run all integration tests with `rake ci:integration`
|
289
|
+
|
271
290
|
|
272
291
|
Core Team
|
273
292
|
=========
|
@@ -279,12 +298,20 @@ Contributors
|
|
279
298
|
============
|
280
299
|
|
281
300
|
* Aaron Tinio (`aptinio`):
|
282
|
-
-
|
283
|
-
-
|
301
|
+
- More robust Selenium RC shutdown
|
302
|
+
- Support for locator including single quotes in `wait_for_...` methods
|
303
|
+
- Do not capture system state on execution errors for pending examples
|
304
|
+
(ExamplePendingError, NotYetImplementedError)
|
284
305
|
|
285
306
|
* Rick Lee-Morlang (`rleemorlang`):
|
286
|
-
-
|
307
|
+
- Fix for incremental calls to `wait_for_text`
|
287
308
|
- Regex support in `wait_for_text`
|
288
|
-
|
289
309
|
|
290
|
-
|
310
|
+
* [Paul Boone](http://www.mindbucket.com) (`paulboone`)
|
311
|
+
- Fixed method_missing in selenium_helper to only delegate to methods
|
312
|
+
that @selenium responds to
|
313
|
+
|
314
|
+
* [Adam Greene](http://blog.sweetspot.dm) (`skippy`)
|
315
|
+
- Added the ability to redirect output to a log file, when
|
316
|
+
launching Selenium Remote Control with the Rake task
|
317
|
+
|
@@ -1,6 +1,6 @@
|
|
1
1
|
require 'rubygems'
|
2
|
-
gem "rspec", "=1.
|
3
|
-
gem "selenium-client", ">=1.2.
|
2
|
+
gem "rspec", "=1.2.6"
|
3
|
+
gem "selenium-client", ">=1.2.15"
|
4
4
|
require "selenium/client"
|
5
5
|
require "selenium/rspec/spec_helper"
|
6
6
|
|
@@ -38,4 +38,4 @@ describe "Google Search" do
|
|
38
38
|
page.element?("link=Cached").should be_true
|
39
39
|
end
|
40
40
|
|
41
|
-
end
|
41
|
+
end
|
data/examples/script/google.rb
CHANGED
data/lib/selenium/client.rb
CHANGED
@@ -6,7 +6,8 @@ require 'net/http'
|
|
6
6
|
require 'uri'
|
7
7
|
require 'cgi'
|
8
8
|
require "digest/md5"
|
9
|
-
require
|
9
|
+
require 'fileutils'
|
10
|
+
require 'tmpdir'
|
10
11
|
require File.expand_path(File.dirname(__FILE__) + '/../tcp_socket_extension')
|
11
12
|
require File.expand_path(File.dirname(__FILE__) + '/../nautilus/shell')
|
12
13
|
require File.expand_path(File.dirname(__FILE__) + '/command_error')
|
data/lib/selenium/client/base.rb
CHANGED
@@ -60,8 +60,16 @@ module Selenium
|
|
60
60
|
not @session_id.nil?
|
61
61
|
end
|
62
62
|
|
63
|
-
|
64
|
-
|
63
|
+
# Starts a new browser session (launching a new browser matching
|
64
|
+
# configuration provided at driver creation time).
|
65
|
+
#
|
66
|
+
# Browser session specific option can also be provided. e.g.
|
67
|
+
#
|
68
|
+
# driver.start_new_browser_session(:captureNetworkTraffic => true)
|
69
|
+
#
|
70
|
+
def start_new_browser_session(options={})
|
71
|
+
options_as_string = options.collect {|key,value| "#{key.to_s}=#{value.to_s}"}.sort.join(";")
|
72
|
+
result = string_command "getNewBrowserSession", [@browser_string, @browser_url, @extension_js, options_as_string]
|
65
73
|
@session_id = result
|
66
74
|
# Consistent timeout on the remote control and driver side.
|
67
75
|
# Intuitive and this is what you want 90% of the time
|
@@ -1140,7 +1140,7 @@ module Selenium
|
|
1140
1140
|
end
|
1141
1141
|
|
1142
1142
|
|
1143
|
-
# Returns
|
1143
|
+
# Returns an array of JavaScript property values from all known windows having one.
|
1144
1144
|
#
|
1145
1145
|
# 'attributeName' is name of an attribute on the windows
|
1146
1146
|
def get_attribute_from_all_windows(attributeName)
|
@@ -1210,21 +1210,21 @@ module Selenium
|
|
1210
1210
|
end
|
1211
1211
|
|
1212
1212
|
|
1213
|
-
# Returns the IDs of all windows that the browser knows about.
|
1213
|
+
# Returns the IDs of all windows that the browser knows about in an array.
|
1214
1214
|
#
|
1215
1215
|
def get_all_window_ids()
|
1216
1216
|
return string_array_command("getAllWindowIds", [])
|
1217
1217
|
end
|
1218
1218
|
|
1219
1219
|
|
1220
|
-
# Returns the names of all windows that the browser knows about.
|
1220
|
+
# Returns the names of all windows that the browser knows about in an array.
|
1221
1221
|
#
|
1222
1222
|
def get_all_window_names()
|
1223
1223
|
return string_array_command("getAllWindowNames", [])
|
1224
1224
|
end
|
1225
1225
|
|
1226
1226
|
|
1227
|
-
# Returns the titles of all windows that the browser knows about.
|
1227
|
+
# Returns the titles of all windows that the browser knows about in an array.
|
1228
1228
|
#
|
1229
1229
|
def get_all_window_titles()
|
1230
1230
|
return string_array_command("getAllWindowTitles", [])
|
@@ -410,6 +410,38 @@ module Selenium
|
|
410
410
|
string_array_command "getAllWindowTitles"
|
411
411
|
end
|
412
412
|
|
413
|
+
# Returns a string representation of the network traffic seen by the
|
414
|
+
# browser, including headers, AJAX requests, status codes, and timings.
|
415
|
+
# When this function is called, the traffic log is cleared, so the
|
416
|
+
# returned content is only the traffic seen since the last call.
|
417
|
+
#
|
418
|
+
# The network traffic is returned in the format it was requested. Valid
|
419
|
+
# values are: :json, :xml, or :plain.
|
420
|
+
#
|
421
|
+
# Warning: For browser_network_traffic to work you need to start your
|
422
|
+
# browser session with the option "captureNetworkTraffic=true", which
|
423
|
+
# will force ALL traffic to go to the Remote Control proxy even for
|
424
|
+
# more efficient browser modes like `*firefox` and `*safari`.
|
425
|
+
def browser_network_traffic(format = :plain)
|
426
|
+
raise "format must be :plain, :json, or :xml" \
|
427
|
+
unless [:plain, :json, :xml].include?(format)
|
428
|
+
|
429
|
+
remote_control_command "captureNetworkTraffic", [format.to_s]
|
430
|
+
end
|
431
|
+
|
432
|
+
# Allows choice of a specific XPath libraries for Xpath evualuation
|
433
|
+
# in the browser (e.g. to resolve XPath locators).
|
434
|
+
#
|
435
|
+
# `library_name' can be:
|
436
|
+
# * :ajaxslt : Google's library
|
437
|
+
# * :javascript-xpath : Cybozu Labs' faster library
|
438
|
+
# * :default : Selenium default library.
|
439
|
+
def browser_xpath_library=(library_name)
|
440
|
+
raise "library name must be :ajaxslt, :javascript-xpath, or :default" \
|
441
|
+
unless [:ajaxslt, :'javascript-xpath', :default].include?(library_name)
|
442
|
+
remote_control_command "useXpathLibrary", [library_name.to_s]
|
443
|
+
end
|
444
|
+
|
413
445
|
end
|
414
446
|
|
415
447
|
end
|
@@ -86,7 +86,7 @@ module Selenium
|
|
86
86
|
http.open_timeout = default_timeout_in_seconds
|
87
87
|
http.read_timeout = default_timeout_in_seconds
|
88
88
|
response = http.post('/selenium-server/driver/', data, HTTP_HEADERS)
|
89
|
-
# puts "RESULT: #{response.inspect}\n"
|
89
|
+
# puts "RESULT: #{response.body.inspect}\n"
|
90
90
|
[ response.body[0..1], response.body[3..-1] ]
|
91
91
|
end
|
92
92
|
|
@@ -7,29 +7,27 @@ module Selenium
|
|
7
7
|
|
8
8
|
module SeleniumHelper
|
9
9
|
|
10
|
-
# Overrides
|
11
|
-
def open(
|
12
|
-
@selenium.open
|
10
|
+
# Overrides default open method to actually delegates to @selenium
|
11
|
+
def open(url)
|
12
|
+
@selenium.open url
|
13
13
|
end
|
14
14
|
|
15
|
-
# Overrides
|
16
|
-
def type(
|
17
|
-
@selenium.type
|
15
|
+
# Overrides default type method to actually delegates to @selenium
|
16
|
+
def type(locator, value)
|
17
|
+
@selenium.type locator, value
|
18
18
|
end
|
19
19
|
|
20
|
-
# Overrides
|
21
|
-
def select(
|
22
|
-
@selenium.select
|
20
|
+
# Overrides default select method to actually delegates to @selenium
|
21
|
+
def select(input_locator, option_locator)
|
22
|
+
@selenium.select input_locator, option_locator
|
23
23
|
end
|
24
24
|
|
25
|
-
#
|
25
|
+
# Delegates to @selenium on method missing
|
26
26
|
def method_missing(method_name, *args)
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
end
|
32
|
-
end
|
27
|
+
return super unless @selenium.respond_to?(method_name)
|
28
|
+
|
29
|
+
@selenium.send(method_name, *args)
|
30
|
+
end
|
33
31
|
end
|
34
32
|
|
35
33
|
end
|
@@ -1,16 +1,39 @@
|
|
1
1
|
module Selenium
|
2
2
|
module Rake
|
3
3
|
|
4
|
+
# Rake tasks to start a Remote Control server.
|
5
|
+
#
|
6
|
+
# require 'selenium/rake/tasks'
|
7
|
+
#
|
8
|
+
# Selenium::Rake::RemoteControlStartTask.new do |rc|
|
9
|
+
# rc.port = 4444
|
10
|
+
# rc.timeout_in_seconds = 3 * 60
|
11
|
+
# rc.background = true
|
12
|
+
# rc.wait_until_up_and_running = true
|
13
|
+
# rc.jar_file = "/path/to/where/selenium-rc-standalone-jar-is-installed"
|
14
|
+
# rc.additional_args << "-singleWindow"
|
15
|
+
# end
|
16
|
+
#
|
17
|
+
# If you do not explicitly specify the path to selenium remote control jar
|
18
|
+
# it will be "auto-discovered" in `vendor` directory using the following
|
19
|
+
# path : `vendor/selenium-remote-control/selenium-server*-standalone.jar`
|
20
|
+
#
|
21
|
+
# To leverage all selenium-client capabilities I recommend downloading
|
22
|
+
# a recent nightly build of a standalone packaging of Selenium Remote
|
23
|
+
# Control. You will find the mightly build at
|
24
|
+
# http://archiva.openqa.org/repository/snapshots/org/openqa/selenium/selenium-remote-control/1.0-SNAPSHOT/
|
4
25
|
class RemoteControlStartTask
|
5
26
|
attr_accessor :port, :timeout_in_seconds, :background,
|
6
|
-
:wait_until_up_and_running, :additional_args
|
27
|
+
:wait_until_up_and_running, :additional_args,
|
28
|
+
:log_to
|
7
29
|
attr_reader :jar_file
|
8
30
|
|
9
31
|
def initialize(name = :'selenium:rc:start')
|
10
32
|
@name = name
|
11
33
|
@port = 4444
|
12
34
|
@timeout_in_seconds = 5
|
13
|
-
|
35
|
+
project_specific_jar = Dir["vendor/selenium-remote-control/selenium-server*-standalone.jar"].first
|
36
|
+
@jar_file = project_specific_jar
|
14
37
|
@additional_args = []
|
15
38
|
@background = false
|
16
39
|
@wait_until_up_and_running = false
|
@@ -29,6 +52,7 @@ module Selenium
|
|
29
52
|
remote_control = Selenium::RemoteControl::RemoteControl.new("0.0.0.0", @port, @timeout_in_seconds)
|
30
53
|
remote_control.jar_file = @jar_file
|
31
54
|
remote_control.additional_args = @additional_args
|
55
|
+
remote_control.log_to = @log_to
|
32
56
|
remote_control.start :background => @background
|
33
57
|
if @background && @wait_until_up_and_running
|
34
58
|
puts "Waiting for Remote Control to be up and running..."
|
@@ -1,6 +1,14 @@
|
|
1
1
|
module Selenium
|
2
2
|
module Rake
|
3
3
|
|
4
|
+
# Rake task to stop a Selenium Remote Control Server
|
5
|
+
#
|
6
|
+
# Selenium::Rake::RemoteControlStopTask.new do |rc|
|
7
|
+
# rc.host = "localhost"
|
8
|
+
# rc.port = 4444
|
9
|
+
# rc.timeout_in_seconds = 3 * 60
|
10
|
+
# end
|
11
|
+
#
|
4
12
|
class RemoteControlStopTask
|
5
13
|
attr_accessor :host, :port, :timeout_in_seconds, :wait_until_stopped
|
6
14
|
|
@@ -3,7 +3,7 @@ module Selenium
|
|
3
3
|
|
4
4
|
class RemoteControl
|
5
5
|
attr_reader :host, :port, :timeout_in_seconds
|
6
|
-
attr_accessor :additional_args, :jar_file
|
6
|
+
attr_accessor :additional_args, :jar_file, :log_to
|
7
7
|
|
8
8
|
def initialize(host, port, timeout_in_seconds = 2 * 60)
|
9
9
|
@host, @port, @timeout_in_seconds = host, port, timeout_in_seconds
|
@@ -16,6 +16,7 @@ module Selenium
|
|
16
16
|
command << " -port #{@port}"
|
17
17
|
command << " -timeout #{@timeout_in_seconds}"
|
18
18
|
command << " #{additional_args.join(' ')}" unless additional_args.empty?
|
19
|
+
command << " > #{log_to}" if log_to
|
19
20
|
|
20
21
|
@shell.run command, {:background => options[:background]}
|
21
22
|
end
|
@@ -3,9 +3,12 @@ module Selenium
|
|
3
3
|
module Reporting
|
4
4
|
|
5
5
|
class FilePathStrategy
|
6
|
-
|
6
|
+
attr_reader :final_report_file_path
|
7
|
+
|
8
|
+
REPORT_DEFAULT_FILE_PATH = File.join(Dir::tmpdir, "selenium_test_report", "index.html")
|
9
|
+
|
7
10
|
def initialize(final_report_file_path)
|
8
|
-
@final_report_file_path = final_report_file_path
|
11
|
+
@final_report_file_path = final_report_file_path || REPORT_DEFAULT_FILE_PATH
|
9
12
|
@relative_dir = nil
|
10
13
|
end
|
11
14
|
|
@@ -21,19 +24,23 @@ module Selenium
|
|
21
24
|
end
|
22
25
|
|
23
26
|
def relative_file_path_for_html_capture(example)
|
24
|
-
"#{relative_dir}/example_#{
|
27
|
+
"#{relative_dir}/example_#{example.reporting_uid}.html"
|
25
28
|
end
|
26
29
|
|
27
30
|
def relative_file_path_for_system_screenshot(example)
|
28
|
-
"#{relative_dir}/example_#{
|
31
|
+
"#{relative_dir}/example_#{example.reporting_uid}_system_screenshot.png"
|
29
32
|
end
|
30
33
|
|
31
34
|
def relative_file_path_for_page_screenshot(example)
|
32
|
-
"#{relative_dir}/example_#{
|
35
|
+
"#{relative_dir}/example_#{example.reporting_uid}_page_screenshot.png"
|
33
36
|
end
|
34
37
|
|
35
38
|
def relative_file_path_for_remote_control_logs(example)
|
36
|
-
"#{relative_dir}/example_#{
|
39
|
+
"#{relative_dir}/example_#{example.reporting_uid}_remote_control.log"
|
40
|
+
end
|
41
|
+
|
42
|
+
def relative_file_path_for_browser_network_traffic(example)
|
43
|
+
"#{relative_dir}/example_#{example.reporting_uid}_browser_network_traffic.log"
|
37
44
|
end
|
38
45
|
|
39
46
|
def file_path_for_html_capture(example)
|
@@ -52,6 +59,10 @@ module Selenium
|
|
52
59
|
file_path relative_file_path_for_remote_control_logs(example)
|
53
60
|
end
|
54
61
|
|
62
|
+
def file_path_for_browser_network_traffic(example)
|
63
|
+
file_path relative_file_path_for_browser_network_traffic(example)
|
64
|
+
end
|
65
|
+
|
55
66
|
def file_path(relative_file_path)
|
56
67
|
the_file_path = base_report_dir + "/" + relative_file_path
|
57
68
|
parent_dir = File.dirname(the_file_path)
|
@@ -59,14 +70,9 @@ module Selenium
|
|
59
70
|
the_file_path
|
60
71
|
end
|
61
72
|
|
62
|
-
|
63
|
-
# backtrace is not reliable anymore using the implementation proc
|
64
|
-
implementation = example.instance_variable_get :'@_implementation'
|
65
|
-
Digest::MD5.hexdigest implementation.inspect
|
66
|
-
end
|
67
|
-
|
73
|
+
|
68
74
|
end
|
69
75
|
|
70
76
|
end
|
71
77
|
end
|
72
|
-
end
|
78
|
+
end
|
@@ -19,7 +19,7 @@ module Selenium
|
|
19
19
|
end
|
20
20
|
|
21
21
|
def logs_and_screenshot_sections(example)
|
22
|
-
dom_id = "example_" +
|
22
|
+
dom_id = "example_" + example.reporting_uid
|
23
23
|
system_screenshot_url = @file_path_strategy.relative_file_path_for_system_screenshot(example)
|
24
24
|
page_screenshot_url = @file_path_strategy.relative_file_path_for_page_screenshot(example)
|
25
25
|
snapshot_url = @file_path_strategy.relative_file_path_for_html_capture(example)
|
@@ -120,4 +120,4 @@ module Selenium
|
|
120
120
|
end
|
121
121
|
|
122
122
|
end
|
123
|
-
end
|
123
|
+
end
|
@@ -5,8 +5,9 @@
|
|
5
5
|
#
|
6
6
|
require "digest/md5"
|
7
7
|
require "base64"
|
8
|
+
require 'tmpdir'
|
8
9
|
require "rubygems"
|
9
|
-
gem "rspec", "1.
|
10
|
+
gem "rspec", "1.2.6"
|
10
11
|
require "spec"
|
11
12
|
require 'spec/runner/formatter/html_formatter'
|
12
13
|
require File.expand_path(File.dirname(__FILE__) + "/file_path_strategy")
|
@@ -18,14 +19,19 @@ module Selenium
|
|
18
19
|
|
19
20
|
class SeleniumTestReportFormatter < Spec::Runner::Formatter::HtmlFormatter
|
20
21
|
|
22
|
+
def initialize(options, output)
|
23
|
+
super
|
24
|
+
raise "Unexpected output type #{output.inspect}" unless output.kind_of?(String)
|
25
|
+
@@file_path_strategy = Selenium::RSpec::Reporting::FilePathStrategy.new(output)
|
26
|
+
end
|
27
|
+
|
21
28
|
def start(example_count)
|
22
29
|
super
|
23
30
|
# ensure there's at least 1 example group header (normally 0 with deep_test)
|
24
31
|
# prevents js and html validity errors
|
25
32
|
example_group = Object.new
|
26
33
|
def example_group.description; ""; end
|
27
|
-
|
28
|
-
@@file_path_strategy = Selenium::RSpec::Reporting::FilePathStrategy.new(@where)
|
34
|
+
example_group_started example_group
|
29
35
|
end
|
30
36
|
|
31
37
|
def move_progress
|
@@ -36,19 +42,11 @@ module Selenium
|
|
36
42
|
Selenium::RSpec::Reporting::HtmlReport.inject_placeholder(super)
|
37
43
|
end
|
38
44
|
|
39
|
-
def
|
40
|
-
include_example_group_description example
|
45
|
+
def example_pending(example_proxy, message, deprecated_pending_location=nil)
|
41
46
|
super
|
42
47
|
end
|
43
48
|
|
44
|
-
def
|
45
|
-
include_example_group_description example
|
46
|
-
super
|
47
|
-
end
|
48
|
-
|
49
|
-
def example_failed(example, counter, failure)
|
50
|
-
include_example_group_description example
|
51
|
-
|
49
|
+
def example_failed(example, counter, failure)
|
52
50
|
old_output = @output
|
53
51
|
@output = StringIO.new
|
54
52
|
super
|
@@ -83,15 +81,7 @@ module Selenium
|
|
83
81
|
# and RSpec reporting work for a proper fix.
|
84
82
|
@@file_path_strategy ||= Selenium::RSpec::Reporting::FilePathStrategy.new(ENV["SELENIUM_TEST_REPORT_FILE"])
|
85
83
|
end
|
86
|
-
|
87
|
-
protected
|
88
|
-
|
89
|
-
def include_example_group_description(example)
|
90
|
-
def example.description
|
91
|
-
self.class.description.to_s + " :: " + super
|
92
|
-
end
|
93
|
-
end
|
94
84
|
|
95
85
|
end
|
96
86
|
end
|
97
|
-
end
|
87
|
+
end
|
@@ -49,7 +49,7 @@ module Selenium
|
|
49
49
|
|
50
50
|
encodedImage = @selenium_driver.capture_screenshot_to_string
|
51
51
|
pngImage = Base64.decode64(encodedImage)
|
52
|
-
File.open(@file_path_strategy.file_path_for_system_screenshot(@example), "
|
52
|
+
File.open(@file_path_strategy.file_path_for_system_screenshot(@example), "wb") { |f| f.write pngImage }
|
53
53
|
end
|
54
54
|
|
55
55
|
def capture_page_screenshot
|
@@ -57,7 +57,7 @@ module Selenium
|
|
57
57
|
|
58
58
|
encodedImage = @selenium_driver.capture_entire_page_screenshot_to_string("")
|
59
59
|
pngImage = Base64.decode64(encodedImage)
|
60
|
-
File.open(@file_path_strategy.file_path_for_page_screenshot(@example), "
|
60
|
+
File.open(@file_path_strategy.file_path_for_page_screenshot(@example), "wb") { |f| f.write pngImage }
|
61
61
|
end
|
62
62
|
|
63
63
|
def retrieve_remote_control_logs
|
@@ -1,5 +1,5 @@
|
|
1
1
|
require "rubygems"
|
2
|
-
gem "rspec", "=1.
|
2
|
+
gem "rspec", "=1.2.6"
|
3
3
|
require 'spec'
|
4
4
|
require 'spec/example/example_group'
|
5
5
|
|
@@ -7,26 +7,36 @@ require 'spec/example/example_group'
|
|
7
7
|
# Monkey-patch RSpec Example Group so that we can track whether an
|
8
8
|
# example already failed or not in an after(:each) block
|
9
9
|
#
|
10
|
-
#
|
10
|
+
# Useful to only capture Selenium screenshots when a test fails
|
11
11
|
#
|
12
|
-
#
|
13
|
-
#
|
12
|
+
# * Changed execution_error to be an instance variable (in lieu of
|
13
|
+
# a local variable).
|
14
|
+
#
|
15
|
+
# * Introduced an unique id (example_uid) that is the same for
|
16
|
+
# a real Example (passed in after(:each) when screenshot is
|
17
|
+
# taken) as well as the corresponding ExampleProxy
|
18
|
+
# (passed to the HTML formatter). This unique id gives us
|
19
|
+
# a way to correlate file names between generation and
|
20
|
+
# reporting time.
|
14
21
|
#
|
15
22
|
module Spec
|
16
23
|
module Example
|
17
|
-
|
18
|
-
|
24
|
+
module ExampleMethods
|
25
|
+
|
19
26
|
attr_reader :execution_error
|
20
27
|
|
21
|
-
|
22
|
-
|
28
|
+
remove_method :execute
|
29
|
+
def execute(run_options, instance_variables) # :nodoc:
|
30
|
+
@_proxy.options[:actual_example] = self
|
31
|
+
|
32
|
+
run_options.reporter.example_started(@_proxy)
|
23
33
|
set_instance_variables_from_hash(instance_variables)
|
24
34
|
|
25
35
|
@execution_error = nil
|
26
|
-
Timeout.timeout(
|
36
|
+
Timeout.timeout(run_options.timeout) do
|
27
37
|
begin
|
28
38
|
before_each_example
|
29
|
-
|
39
|
+
instance_eval(&@_implementation)
|
30
40
|
rescue Exception => e
|
31
41
|
@execution_error ||= e
|
32
42
|
end
|
@@ -37,10 +47,50 @@ module Spec
|
|
37
47
|
end
|
38
48
|
end
|
39
49
|
|
40
|
-
|
50
|
+
run_options.reporter.example_finished(@_proxy.update(description), @execution_error)
|
41
51
|
success = @execution_error.nil? || ExamplePendingError === @execution_error
|
42
52
|
end
|
43
|
-
|
53
|
+
|
54
|
+
def actual_failure?
|
55
|
+
case execution_error
|
56
|
+
when nil
|
57
|
+
false
|
58
|
+
when Spec::Example::ExamplePendingError,
|
59
|
+
Spec::Example::PendingExampleFixedError,
|
60
|
+
Spec::Example::NoDescriptionError
|
61
|
+
false
|
62
|
+
else
|
63
|
+
true
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
def reporting_uid
|
68
|
+
# backtrace is not reliable anymore using the implementation proc
|
69
|
+
Digest::MD5.hexdigest @_implementation.inspect
|
70
|
+
end
|
71
|
+
|
72
|
+
def pending_for_browsers(*browser_regexps, &block)
|
73
|
+
actual_browser = selenium_driver.browser_string
|
74
|
+
match_browser_regexps = browser_regexps.inject(false) do |match, regexp|
|
75
|
+
match ||= actual_browser =~ Regexp.new(regexp.source, Regexp::IGNORECASE)
|
76
|
+
end
|
77
|
+
if match_browser_regexps
|
78
|
+
pending "#{actual_browser.gsub(/\*/, '').capitalize} does not support this feature yet"
|
79
|
+
else
|
80
|
+
yield
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
44
84
|
end
|
85
|
+
|
86
|
+
class ExampleProxy
|
87
|
+
|
88
|
+
def reporting_uid
|
89
|
+
options[:actual_example].reporting_uid
|
90
|
+
end
|
91
|
+
|
92
|
+
end
|
93
|
+
|
45
94
|
end
|
46
95
|
end
|
96
|
+
|
@@ -9,7 +9,9 @@ Spec::Runner.configure do |config|
|
|
9
9
|
|
10
10
|
config.prepend_after(:each) do
|
11
11
|
begin
|
12
|
-
|
12
|
+
if actual_failure?
|
13
|
+
Selenium::RSpec::SeleniumTestReportFormatter.capture_system_state(selenium_driver, self)
|
14
|
+
end
|
13
15
|
if selenium_driver.session_started?
|
14
16
|
selenium_driver.set_context "Ending example '#{self.description}'"
|
15
17
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: selenium-client
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.2.
|
4
|
+
version: 1.2.15
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- OpenQA
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2009-
|
12
|
+
date: 2009-05-12 00:00:00 -07:00
|
13
13
|
default_executable:
|
14
14
|
dependencies: []
|
15
15
|
|
@@ -54,6 +54,8 @@ files:
|
|
54
54
|
- README.markdown
|
55
55
|
has_rdoc: true
|
56
56
|
homepage: http://selenium-client.rubyforge.com
|
57
|
+
licenses: []
|
58
|
+
|
57
59
|
post_install_message:
|
58
60
|
rdoc_options:
|
59
61
|
- --title
|
@@ -78,9 +80,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
78
80
|
requirements: []
|
79
81
|
|
80
82
|
rubyforge_project: selenium-client
|
81
|
-
rubygems_version: 1.3.
|
83
|
+
rubygems_version: 1.3.2
|
82
84
|
signing_key:
|
83
|
-
specification_version:
|
85
|
+
specification_version: 3
|
84
86
|
summary: Official Ruby Client for Selenium RC.
|
85
87
|
test_files:
|
86
88
|
- test/all_unit_tests.rb
|