rspec-webdriver 0.0.1
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/.gitignore +4 -0
- data/Gemfile +4 -0
- data/README.md +17 -0
- data/Rakefile +19 -0
- data/lib/rspec/reporting/file_path_strategy.rb +78 -0
- data/lib/rspec/reporting/html_report.rb +123 -0
- data/lib/rspec/reporting/selenium_test_report_formatter.rb +82 -0
- data/lib/rspec/reporting/system_capture.rb +39 -0
- data/lib/rspec/rspec_extensions.rb +75 -0
- data/lib/rspec/spec_helper.rb +18 -0
- data/rspec-webdriver.gemspec +21 -0
- data/spec/example_run.rb +26 -0
- data/spec/report_spec.rb +24 -0
- data/spec/spec_results_for_comparison.html +356 -0
- metadata +80 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
data/README.md
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
#Rspec-Webdriver
|
|
2
|
+
|
|
3
|
+
Just some reporting if you are using rspec and webdriver
|
|
4
|
+
|
|
5
|
+
##Credit where credit is due
|
|
6
|
+
|
|
7
|
+
This is project is not much more than a port of the reporting from ph7's selenium-client. I added updates for rspec 2.0 and selenium-webdriver.
|
|
8
|
+
|
|
9
|
+
##How to play
|
|
10
|
+
|
|
11
|
+
Name your webdriver @driver in your specs. Do not close it at the end of your spec (the spec_helper will do that for you).
|
|
12
|
+
|
|
13
|
+
rspec --require 'rspec/reporting/selenium_test_report_formatter'
|
|
14
|
+
--require 'rspec/spec_helper' --format 'SeleniumTestReportFormatter'
|
|
15
|
+
-o './test_results.html' <your_spec.rb>
|
|
16
|
+
|
|
17
|
+
|
data/Rakefile
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
require "rubygems"
|
|
2
|
+
require "bundler"
|
|
3
|
+
Bundler.setup
|
|
4
|
+
Bundler::GemHelper.install_tasks
|
|
5
|
+
|
|
6
|
+
require "rake"
|
|
7
|
+
require "rspec/core/rake_task"
|
|
8
|
+
require "rspec/core/version"
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
desc "Run all examples"
|
|
12
|
+
RSpec::Core::RakeTask.new(:spec) do |t|
|
|
13
|
+
t.rspec_opts = %w[--color]
|
|
14
|
+
t.verbose = false
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
task :default => [:spec]
|
|
19
|
+
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
module Selenium
|
|
2
|
+
module RSpec
|
|
3
|
+
module Reporting
|
|
4
|
+
|
|
5
|
+
class FilePathStrategy
|
|
6
|
+
attr_reader :final_report_file_path
|
|
7
|
+
|
|
8
|
+
REPORT_DEFAULT_FILE_PATH = File.join(Dir::tmpdir, "selenium_test_report", "index.html")
|
|
9
|
+
|
|
10
|
+
def initialize(final_report_file_path)
|
|
11
|
+
@final_report_file_path = final_report_file_path || REPORT_DEFAULT_FILE_PATH
|
|
12
|
+
@relative_dir = nil
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def base_report_dir
|
|
16
|
+
@base_report_dir ||= File.dirname((File.expand_path(@final_report_file_path) rescue @final_report_file_path.path))
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def relative_dir
|
|
20
|
+
return @relative_dir if @relative_dir
|
|
21
|
+
|
|
22
|
+
file_name_without_extension = (File.basename(@final_report_file_path).sub(/\.[^\.]*$/, "") rescue File.basename(@final_report_file_path.path).sub(/\.[^\.]*$/, ""))
|
|
23
|
+
@relative_dir ||= "resources/" + file_name_without_extension
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def relative_file_path_for_html_capture(example)
|
|
27
|
+
"#{relative_dir}/example_#{example.reporting_uid}.html"
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def relative_file_path_for_system_screenshot(example)
|
|
31
|
+
"#{relative_dir}/example_#{example.reporting_uid}_system_screenshot.png"
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def relative_file_path_for_page_screenshot(example)
|
|
35
|
+
"#{relative_dir}/example_#{example.reporting_uid}_page_screenshot.png"
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def relative_file_path_for_remote_control_logs(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"
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def file_path_for_html_capture(example)
|
|
47
|
+
file_path relative_file_path_for_html_capture(example)
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def file_path_for_system_screenshot(example)
|
|
51
|
+
file_path relative_file_path_for_system_screenshot(example)
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def file_path_for_page_screenshot(example)
|
|
55
|
+
file_path relative_file_path_for_page_screenshot(example)
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def file_path_for_remote_control_logs(example)
|
|
59
|
+
file_path relative_file_path_for_remote_control_logs(example)
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def file_path_for_browser_network_traffic(example)
|
|
63
|
+
file_path relative_file_path_for_browser_network_traffic(example)
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def file_path(relative_file_path)
|
|
67
|
+
the_file_path = base_report_dir + "/" + relative_file_path
|
|
68
|
+
parent_dir = File.dirname(the_file_path)
|
|
69
|
+
FileUtils.mkdir_p(parent_dir) unless File.directory?(parent_dir)
|
|
70
|
+
the_file_path
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
end
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
module Selenium
|
|
2
|
+
module RSpec
|
|
3
|
+
module Reporting
|
|
4
|
+
|
|
5
|
+
class HtmlReport
|
|
6
|
+
|
|
7
|
+
PLACEHOLDER = "<<placeholder>>"
|
|
8
|
+
|
|
9
|
+
def initialize(file_path_strategy)
|
|
10
|
+
@file_path_strategy = file_path_strategy
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def self.inject_placeholder(content)
|
|
14
|
+
content + Selenium::RSpec::Reporting::HtmlReport::PLACEHOLDER
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def replace_placeholder_with_system_state_content(result, example)
|
|
18
|
+
result.gsub! PLACEHOLDER, logs_and_screenshot_sections(example)
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def logs_and_screenshot_sections(example)
|
|
22
|
+
dom_id = "example_" + example.reporting_uid
|
|
23
|
+
system_screenshot_url = @file_path_strategy.relative_file_path_for_system_screenshot(example)
|
|
24
|
+
page_screenshot_url = @file_path_strategy.relative_file_path_for_page_screenshot(example)
|
|
25
|
+
snapshot_url = @file_path_strategy.relative_file_path_for_html_capture(example)
|
|
26
|
+
remote_control_logs_url = @file_path_strategy.relative_file_path_for_remote_control_logs(example)
|
|
27
|
+
|
|
28
|
+
html = ""
|
|
29
|
+
if File.exists? @file_path_strategy.file_path_for_html_capture(example)
|
|
30
|
+
html << toggable_section(dom_id, :id => "snapshot", :url=> snapshot_url, :name => "Dynamic HTML Snapshot")
|
|
31
|
+
end
|
|
32
|
+
if File.exists? @file_path_strategy.file_path_for_remote_control_logs(example)
|
|
33
|
+
html << toggable_section(dom_id, :id => "rc_logs", :url=> remote_control_logs_url, :name => "Remote Control Logs")
|
|
34
|
+
end
|
|
35
|
+
if File.exists? @file_path_strategy.file_path_for_page_screenshot(example)
|
|
36
|
+
html << toggable_image_section(dom_id, :id => "page_screenshot", :name => "Page Screenshot", :url => page_screenshot_url)
|
|
37
|
+
end
|
|
38
|
+
if File.exists? @file_path_strategy.file_path_for_system_screenshot(example)
|
|
39
|
+
html << toggable_image_section(dom_id, :id => "system_screenshot", :name => "System Screenshot", :url => system_screenshot_url)
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
return html
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def self.append_javascript(global_scripts)
|
|
46
|
+
global_scripts + <<-EOF
|
|
47
|
+
function toggleVisilibility(id, description) {
|
|
48
|
+
var section;
|
|
49
|
+
var link;
|
|
50
|
+
|
|
51
|
+
section = document.getElementById(id);
|
|
52
|
+
link = document.getElementById(id + "_link");
|
|
53
|
+
|
|
54
|
+
if (section.style.display == "block") {
|
|
55
|
+
section.style.display = "none"
|
|
56
|
+
link.innerHTML = "Show " + description
|
|
57
|
+
} else {
|
|
58
|
+
section.style.display = "block"
|
|
59
|
+
link.innerHTML = "Hide " + description
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
EOF
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def self.append_css(global_styles)
|
|
66
|
+
global_styles + <<-EOF
|
|
67
|
+
|
|
68
|
+
div.rspec-report textarea {
|
|
69
|
+
width: 100%;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
div.rspec-report .dyn-source {
|
|
73
|
+
background: #FFFFEE none repeat scroll 0%;
|
|
74
|
+
border:1px dotted black;
|
|
75
|
+
color: #000000;
|
|
76
|
+
display: none;
|
|
77
|
+
margin: 0.5em 2em;
|
|
78
|
+
padding: 0.5em;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
EOF
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
def toggable_section(dom_id, options)
|
|
85
|
+
<<-EOS
|
|
86
|
+
|
|
87
|
+
<div>[
|
|
88
|
+
<a id="#{dom_id}_#{options[:id]}_link"
|
|
89
|
+
href=\"javascript:toggleVisilibility('#{dom_id}_#{options[:id]}', '#{options[:name]}')\">Show #{options[:name]}</a>
|
|
90
|
+
]</div>
|
|
91
|
+
<br/><br/>
|
|
92
|
+
<div id="#{dom_id}_#{options[:id]}" class="dyn-source">
|
|
93
|
+
<a href="#{options[:url]}">Full screen</a><br/><br/>
|
|
94
|
+
<iframe src="#{options[:url]}" width="100%" height="600px" ></iframe>
|
|
95
|
+
</div>
|
|
96
|
+
|
|
97
|
+
EOS
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
def toggable_image_section(dom_id, options)
|
|
101
|
+
<<-EOS
|
|
102
|
+
|
|
103
|
+
<div>[<a id="#{dom_id}_#{options[:id]}_link" href="javascript:toggleVisilibility('#{dom_id}_#{options[:id]}', '#{options[:name]}');">Show #{options[:name]}</a>]</div>
|
|
104
|
+
<br/>
|
|
105
|
+
<div id="#{dom_id}_#{options[:id]}" style="display: none">
|
|
106
|
+
<a href="#{options[:url]}">
|
|
107
|
+
<img width="80%" src="#{options[:url]}" />
|
|
108
|
+
</a>
|
|
109
|
+
</div>
|
|
110
|
+
<br/>
|
|
111
|
+
|
|
112
|
+
EOS
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
def report_header
|
|
116
|
+
super + "\n<script type=\"text/javascript\">moveProgressBar('100.0');</script>"
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
end
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
end
|
|
123
|
+
end
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
#
|
|
2
|
+
# Explicit requires in this file so that we can invoke RSpec runner with a
|
|
3
|
+
# single:
|
|
4
|
+
# --require 'lib/selenium/rspec/reporting/selenium_test_report_formatter'
|
|
5
|
+
#
|
|
6
|
+
require "digest/md5"
|
|
7
|
+
require "base64"
|
|
8
|
+
require 'tmpdir'
|
|
9
|
+
require "rubygems"
|
|
10
|
+
gem "rspec", ">=2.0"
|
|
11
|
+
require 'rspec/core'
|
|
12
|
+
require 'rspec/core/formatters/html_formatter'
|
|
13
|
+
require File.expand_path(File.dirname(__FILE__) + "/file_path_strategy")
|
|
14
|
+
require File.expand_path(File.dirname(__FILE__) + "/system_capture")
|
|
15
|
+
require File.expand_path(File.dirname(__FILE__) + "/html_report")
|
|
16
|
+
|
|
17
|
+
class SeleniumTestReportFormatter < RSpec::Core::Formatters::HtmlFormatter
|
|
18
|
+
|
|
19
|
+
def initialize(output)
|
|
20
|
+
super
|
|
21
|
+
raise "Unexpected output type #{output.inspect}" unless output.kind_of?(String) || output.kind_of?(File)
|
|
22
|
+
@@file_path_strategy = Selenium::RSpec::Reporting::FilePathStrategy.new(output)
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def start(example_count)
|
|
26
|
+
super
|
|
27
|
+
# ensure there's at least 1 example group header (normally 0 with deep_test)
|
|
28
|
+
# prevents js and html validity errors
|
|
29
|
+
example_group = Object.new
|
|
30
|
+
def example_group.description; ""; end
|
|
31
|
+
#example_group_started example_group
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def move_progress
|
|
35
|
+
# we don't have current_example_number, and we don't really care about the progress bar
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def extra_failure_content(failure)
|
|
39
|
+
Selenium::RSpec::Reporting::HtmlReport.inject_placeholder(super)
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def example_pending(example_proxy)
|
|
43
|
+
super
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def example_failed(example)
|
|
47
|
+
old_output = @output
|
|
48
|
+
@output = StringIO.new
|
|
49
|
+
super
|
|
50
|
+
|
|
51
|
+
result = @output.string
|
|
52
|
+
report = Selenium::RSpec::Reporting::HtmlReport.new(@@file_path_strategy)
|
|
53
|
+
report.replace_placeholder_with_system_state_content(result, example)
|
|
54
|
+
old_output.puts result
|
|
55
|
+
old_output.flush
|
|
56
|
+
ensure
|
|
57
|
+
@output = old_output
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
# Should be called from config.after(:each) in spec helper
|
|
61
|
+
def self.capture_system_state(selenium_driver, example)
|
|
62
|
+
system_capture = Selenium::RSpec::Reporting::SystemCapture.new(selenium_driver, example, file_path_strategy)
|
|
63
|
+
system_capture.capture_system_state
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def global_scripts
|
|
67
|
+
Selenium::RSpec::Reporting::HtmlReport.append_javascript(super)
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
def global_styles
|
|
71
|
+
Selenium::RSpec::Reporting::HtmlReport.append_css(super)
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
def self.file_path_strategy
|
|
75
|
+
### HACK ####
|
|
76
|
+
# When running with DeepTest the class instance variable could not have been set
|
|
77
|
+
# For now you must set the env variable before launching the tests. We need to revisit the way DeepTest
|
|
78
|
+
# and RSpec reporting work for a proper fix.
|
|
79
|
+
@@file_path_strategy ||= Selenium::RSpec::Reporting::FilePathStrategy.new(ENV["SELENIUM_TEST_REPORT_FILE"])
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
end
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
module Selenium
|
|
2
|
+
module RSpec
|
|
3
|
+
module Reporting
|
|
4
|
+
|
|
5
|
+
class SystemCapture
|
|
6
|
+
|
|
7
|
+
def initialize(selenium_driver, example, file_path_strategy)
|
|
8
|
+
@webdriver = selenium_driver
|
|
9
|
+
@example = example
|
|
10
|
+
@file_path_strategy = file_path_strategy
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def capture_system_state
|
|
14
|
+
begin
|
|
15
|
+
capture_html_snapshot
|
|
16
|
+
rescue Exception => e
|
|
17
|
+
STDERR.puts "WARNING: Could not capture HTML snapshot: #{e}"
|
|
18
|
+
end
|
|
19
|
+
begin
|
|
20
|
+
capture_page_screenshot
|
|
21
|
+
rescue Exception => e
|
|
22
|
+
STDERR.puts "WARNING: Could not capture page screenshot: #{e}"
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def capture_html_snapshot
|
|
27
|
+
html = @webdriver.page_source
|
|
28
|
+
File.open(@file_path_strategy.file_path_for_html_capture(@example), "w") { |f| f.write html }
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def capture_page_screenshot
|
|
32
|
+
@webdriver.save_screenshot(@file_path_strategy.file_path_for_page_screenshot(@example))
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
require "rubygems"
|
|
2
|
+
gem "rspec", ">=2.0"
|
|
3
|
+
require 'rspec/core'
|
|
4
|
+
require 'rspec/core/example'
|
|
5
|
+
|
|
6
|
+
#
|
|
7
|
+
# Monkey-patch RSpec Example Group so that we can track whether an
|
|
8
|
+
# example already failed or not in an after(:each) block
|
|
9
|
+
#
|
|
10
|
+
# Useful to only capture Selenium screenshots when a test fails
|
|
11
|
+
#
|
|
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.
|
|
21
|
+
#
|
|
22
|
+
module RSpec
|
|
23
|
+
module Core
|
|
24
|
+
class ExampleGroup
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
def actual_failure?
|
|
28
|
+
case example.exception
|
|
29
|
+
when nil
|
|
30
|
+
false
|
|
31
|
+
when RSpec::Core::PendingExampleFixedError
|
|
32
|
+
#RSpec::Example::ExamplePendingError,
|
|
33
|
+
#RSpec::Example::PendingExampleFixedError,
|
|
34
|
+
#RSpec::Example::NoDescriptionError
|
|
35
|
+
false
|
|
36
|
+
else
|
|
37
|
+
true
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
class Example
|
|
43
|
+
|
|
44
|
+
attr_reader :exception
|
|
45
|
+
|
|
46
|
+
def reporting_uid
|
|
47
|
+
# backtrace is not reliable anymore using the implementation proc
|
|
48
|
+
Digest::MD5.hexdigest(metadata[:execution_result][:started_at].to_s+metadata[:full_description].to_s)
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def pending_for_browsers(*browser_regexps, &block)
|
|
52
|
+
actual_browser = selenium_driver.browser_string
|
|
53
|
+
match_browser_regexps = browser_regexps.inject(false) do |match, regexp|
|
|
54
|
+
match ||= actual_browser =~ Regexp.new(regexp.source, Regexp::IGNORECASE)
|
|
55
|
+
end
|
|
56
|
+
if match_browser_regexps
|
|
57
|
+
pending "#{actual_browser.gsub(/\*/, '').capitalize} does not support this feature yet"
|
|
58
|
+
else
|
|
59
|
+
yield
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
class ExampleProxy
|
|
66
|
+
|
|
67
|
+
def reporting_uid
|
|
68
|
+
options[:actual_example].reporting_uid
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
require 'rubygems'
|
|
2
|
+
require 'rspec/core'
|
|
3
|
+
require 'base64'
|
|
4
|
+
require 'fileutils'
|
|
5
|
+
require File.expand_path(File.dirname(__FILE__) + "/rspec_extensions")
|
|
6
|
+
require File.expand_path(File.dirname(__FILE__) + "/reporting/selenium_test_report_formatter")
|
|
7
|
+
|
|
8
|
+
RSpec.configure do |config|
|
|
9
|
+
|
|
10
|
+
config.after(:each) do
|
|
11
|
+
if actual_failure?
|
|
12
|
+
SeleniumTestReportFormatter.capture_system_state(@driver, self.example)
|
|
13
|
+
end
|
|
14
|
+
@driver.quit
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
end
|
|
18
|
+
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
|
2
|
+
$LOAD_PATH.unshift File.expand_path("../lib", __FILE__)
|
|
3
|
+
|
|
4
|
+
Gem::Specification.new do |s|
|
|
5
|
+
s.name = "rspec-webdriver"
|
|
6
|
+
s.version = "0.0.1"
|
|
7
|
+
s.platform = Gem::Platform::RUBY
|
|
8
|
+
s.authors = ["Brian Faherty"]
|
|
9
|
+
s.email = "anothergenericuser+ruby@gmail.com"
|
|
10
|
+
s.summary = "rspec-webdriver-0.0.1"
|
|
11
|
+
s.description = "RSpec reporting for selenium-webdriver"
|
|
12
|
+
|
|
13
|
+
s.rubygems_version = "1.3.7"
|
|
14
|
+
|
|
15
|
+
s.files = `git ls-files`.split("\n")
|
|
16
|
+
s.test_files = `git ls-files -- {spec,features}/*`.split("\n")
|
|
17
|
+
#s.extra_rdoc_files = [ "README.md" ]
|
|
18
|
+
s.rdoc_options = ["--charset=UTF-8"]
|
|
19
|
+
s.require_path = "lib"
|
|
20
|
+
end
|
|
21
|
+
|
data/spec/example_run.rb
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
require "selenium-webdriver"
|
|
2
|
+
require "test/unit/assertions"
|
|
3
|
+
include Test::Unit::Assertions
|
|
4
|
+
|
|
5
|
+
describe "Report" do
|
|
6
|
+
attr_reader :driver
|
|
7
|
+
|
|
8
|
+
it "Generates a clean report when needed" do
|
|
9
|
+
@driver = Selenium::WebDriver.for :firefox
|
|
10
|
+
@driver.navigate.to "http://google.com"
|
|
11
|
+
element = @driver.find_element(:name, 'q')
|
|
12
|
+
element.send_keys "Hello Web@driver!"
|
|
13
|
+
element.submit
|
|
14
|
+
puts @driver.title
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
it "Generates a clean report when needed" do
|
|
18
|
+
@driver = Selenium::WebDriver.for :firefox
|
|
19
|
+
@driver.navigate.to "http://google.com"
|
|
20
|
+
element = @driver.find_element(:name, 'q')
|
|
21
|
+
assert false
|
|
22
|
+
element.send_keys "Hello Web@driver!"
|
|
23
|
+
element.submit
|
|
24
|
+
puts @driver.title
|
|
25
|
+
end
|
|
26
|
+
end
|
data/spec/report_spec.rb
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
#require "nokogiri"
|
|
2
|
+
require "rspec/core/rake_task"
|
|
3
|
+
|
|
4
|
+
describe "Report" do
|
|
5
|
+
it "Generates a clean report when needed" do
|
|
6
|
+
RSpec::Core::RakeTask.new(:test_for_specs) do |t|
|
|
7
|
+
t.pattern = File.expand_path(File.dirname(__FILE__) + "/example_run.rb")
|
|
8
|
+
t.rspec_opts = "--require 'lib/rspec/reporting/selenium_test_report_formatter' "
|
|
9
|
+
t.rspec_opts << "--require 'lib/rspec/spec_helper' "
|
|
10
|
+
t.rspec_opts << "--format SeleniumTestReportFormatter "
|
|
11
|
+
t.rspec_opts << "-o ./spec_test_report.html "
|
|
12
|
+
t.verbose = false
|
|
13
|
+
end
|
|
14
|
+
Rake::Task[:test_for_specs].invoke rescue nil
|
|
15
|
+
out = File.read(File.expand_path(File.dirname(__FILE__) + "/../spec_test_report.html")).to_s
|
|
16
|
+
out.gsub! /\d+\.\d+ seconds/, 'x seconds'
|
|
17
|
+
out.match /example_([a-z0-9]+)_snapshot/
|
|
18
|
+
reporting_uid = $1
|
|
19
|
+
2.times{out.gsub! reporting_uid.to_s, "ZASDF"}
|
|
20
|
+
expected = File.read(File.expand_path(File.dirname(__FILE__) + "/spec_results_for_comparison.html")).to_s
|
|
21
|
+
STDOUT.puts "The reporteding_uid was #{reporting_uid}"
|
|
22
|
+
out.should == expected
|
|
23
|
+
end
|
|
24
|
+
end
|
|
@@ -0,0 +1,356 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
+
<!DOCTYPE html
|
|
3
|
+
PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
|
|
4
|
+
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
|
5
|
+
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
|
6
|
+
<head>
|
|
7
|
+
<title>RSpec results</title>
|
|
8
|
+
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
|
9
|
+
<meta http-equiv="Expires" content="-1" />
|
|
10
|
+
<meta http-equiv="Pragma" content="no-cache" />
|
|
11
|
+
<style type="text/css">
|
|
12
|
+
body {
|
|
13
|
+
margin: 0;
|
|
14
|
+
padding: 0;
|
|
15
|
+
background: #fff;
|
|
16
|
+
font-size: 80%;
|
|
17
|
+
}
|
|
18
|
+
</style>
|
|
19
|
+
<script type="text/javascript">
|
|
20
|
+
// <![CDATA[
|
|
21
|
+
|
|
22
|
+
function addClass(element_id, classname) {
|
|
23
|
+
document.getElementById(element_id).className += (" " + classname);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
function removeClass(element_id, classname) {
|
|
27
|
+
var elem = document.getElementById(element_id);
|
|
28
|
+
var classlist = elem.className.replace(classname,'');
|
|
29
|
+
elem.className = classlist;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
function moveProgressBar(percentDone) {
|
|
33
|
+
document.getElementById("rspec-header").style.width = percentDone +"%";
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
function makeRed(element_id) {
|
|
37
|
+
removeClass(element_id, 'passed');
|
|
38
|
+
removeClass(element_id, 'not_implemented');
|
|
39
|
+
addClass(element_id,'failed');
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
function makeYellow(element_id) {
|
|
43
|
+
var elem = document.getElementById(element_id);
|
|
44
|
+
if (elem.className.indexOf("failed") == -1) { // class doesn't includes failed
|
|
45
|
+
if (elem.className.indexOf("not_implemented") == -1) { // class doesn't include not_implemented
|
|
46
|
+
removeClass(element_id, 'passed');
|
|
47
|
+
addClass(element_id,'not_implemented');
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
function apply_filters() {
|
|
53
|
+
var passed_filter = document.getElementById('passed_checkbox').checked;
|
|
54
|
+
var failed_filter = document.getElementById('failed_checkbox').checked;
|
|
55
|
+
var pending_filter = document.getElementById('pending_checkbox').checked;
|
|
56
|
+
|
|
57
|
+
assign_display_style("example passed", passed_filter);
|
|
58
|
+
assign_display_style("example failed", failed_filter);
|
|
59
|
+
assign_display_style("example not_implemented", pending_filter);
|
|
60
|
+
|
|
61
|
+
assign_display_style_for_group("example_group passed", passed_filter);
|
|
62
|
+
assign_display_style_for_group("example_group not_implemented", pending_filter, pending_filter || passed_filter);
|
|
63
|
+
assign_display_style_for_group("example_group failed", failed_filter, failed_filter || pending_filter || passed_filter);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
function get_display_style(display_flag) {
|
|
67
|
+
var style_mode = 'none';
|
|
68
|
+
if (display_flag == true) {
|
|
69
|
+
style_mode = 'block';
|
|
70
|
+
}
|
|
71
|
+
return style_mode;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
function assign_display_style(classname, display_flag) {
|
|
75
|
+
var style_mode = get_display_style(display_flag);
|
|
76
|
+
var elems = document.getElementsByClassName(classname)
|
|
77
|
+
for (var i=0; i<elems.length;i++) {
|
|
78
|
+
elems[i].style.display = style_mode;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
function assign_display_style_for_group(classname, display_flag, subgroup_flag) {
|
|
83
|
+
var display_style_mode = get_display_style(display_flag);
|
|
84
|
+
var subgroup_style_mode = get_display_style(subgroup_flag);
|
|
85
|
+
var elems = document.getElementsByClassName(classname)
|
|
86
|
+
for (var i=0; i<elems.length;i++) {
|
|
87
|
+
var style_mode = display_style_mode;
|
|
88
|
+
if ((display_flag != subgroup_flag) && (elems[i].getElementsByTagName('dt')[0].innerHTML.indexOf(", ") != -1)) {
|
|
89
|
+
elems[i].style.display = subgroup_style_mode;
|
|
90
|
+
} else {
|
|
91
|
+
elems[i].style.display = display_style_mode;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
function toggleVisilibility(id, description) {
|
|
96
|
+
var section;
|
|
97
|
+
var link;
|
|
98
|
+
|
|
99
|
+
section = document.getElementById(id);
|
|
100
|
+
link = document.getElementById(id + "_link");
|
|
101
|
+
|
|
102
|
+
if (section.style.display == "block") {
|
|
103
|
+
section.style.display = "none"
|
|
104
|
+
link.innerHTML = "Show " + description
|
|
105
|
+
} else {
|
|
106
|
+
section.style.display = "block"
|
|
107
|
+
link.innerHTML = "Hide " + description
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
// ]]>
|
|
112
|
+
</script>
|
|
113
|
+
<style type="text/css">
|
|
114
|
+
#rspec-header {
|
|
115
|
+
background: #65C400; color: #fff; height: 4em;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
.rspec-report h1 {
|
|
119
|
+
margin: 0px 10px 0px 10px;
|
|
120
|
+
padding: 10px;
|
|
121
|
+
font-family: "Lucida Grande", Helvetica, sans-serif;
|
|
122
|
+
font-size: 1.8em;
|
|
123
|
+
position: absolute;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
#label {
|
|
127
|
+
float:left;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
#display-filters {
|
|
131
|
+
float:left;
|
|
132
|
+
padding: 28px 0 0 40%;
|
|
133
|
+
font-family: "Lucida Grande", Helvetica, sans-serif;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
#summary {
|
|
137
|
+
float:right;
|
|
138
|
+
padding: 5px 10px;
|
|
139
|
+
font-family: "Lucida Grande", Helvetica, sans-serif;
|
|
140
|
+
text-align: right;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
#summary p {
|
|
144
|
+
margin: 0 0 0 2px;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
#summary #totals {
|
|
148
|
+
font-size: 1.2em;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
.example_group {
|
|
152
|
+
margin: 0 10px 5px;
|
|
153
|
+
background: #fff;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
dl {
|
|
157
|
+
margin: 0; padding: 0 0 5px;
|
|
158
|
+
font: normal 11px "Lucida Grande", Helvetica, sans-serif;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
dt {
|
|
162
|
+
padding: 3px;
|
|
163
|
+
background: #65C400;
|
|
164
|
+
color: #fff;
|
|
165
|
+
font-weight: bold;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
dd {
|
|
169
|
+
margin: 5px 0 5px 5px;
|
|
170
|
+
padding: 3px 3px 3px 18px;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
|
|
174
|
+
dd.example.passed {
|
|
175
|
+
border-left: 5px solid #65C400;
|
|
176
|
+
border-bottom: 1px solid #65C400;
|
|
177
|
+
background: #DBFFB4; color: #3D7700;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
dd.example.not_implemented {
|
|
181
|
+
border-left: 5px solid #FAF834;
|
|
182
|
+
border-bottom: 1px solid #FAF834;
|
|
183
|
+
background: #FCFB98; color: #131313;
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
dd.example.pending_fixed {
|
|
187
|
+
border-left: 5px solid #0000C2;
|
|
188
|
+
border-bottom: 1px solid #0000C2;
|
|
189
|
+
color: #0000C2; background: #D3FBFF;
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
dd.example.failed {
|
|
193
|
+
border-left: 5px solid #C20000;
|
|
194
|
+
border-bottom: 1px solid #C20000;
|
|
195
|
+
color: #C20000; background: #FFFBD3;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
|
|
199
|
+
dt.not_implemented {
|
|
200
|
+
color: #000000; background: #FAF834;
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
dt.pending_fixed {
|
|
204
|
+
color: #FFFFFF; background: #C40D0D;
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
dt.failed {
|
|
208
|
+
color: #FFFFFF; background: #C40D0D;
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
|
|
212
|
+
#rspec-header.not_implemented {
|
|
213
|
+
color: #000000; background: #FAF834;
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
#rspec-header.pending_fixed {
|
|
217
|
+
color: #FFFFFF; background: #C40D0D;
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
#rspec-header.failed {
|
|
221
|
+
color: #FFFFFF; background: #C40D0D;
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
|
|
225
|
+
.backtrace {
|
|
226
|
+
color: #000;
|
|
227
|
+
font-size: 12px;
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
a {
|
|
231
|
+
color: #BE5C00;
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
/* Ruby code, style similar to vibrant ink */
|
|
235
|
+
.ruby {
|
|
236
|
+
font-size: 12px;
|
|
237
|
+
font-family: monospace;
|
|
238
|
+
color: white;
|
|
239
|
+
background-color: black;
|
|
240
|
+
padding: 0.1em 0 0.2em 0;
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
.ruby .keyword { color: #FF6600; }
|
|
244
|
+
.ruby .constant { color: #339999; }
|
|
245
|
+
.ruby .attribute { color: white; }
|
|
246
|
+
.ruby .global { color: white; }
|
|
247
|
+
.ruby .module { color: white; }
|
|
248
|
+
.ruby .class { color: white; }
|
|
249
|
+
.ruby .string { color: #66FF00; }
|
|
250
|
+
.ruby .ident { color: white; }
|
|
251
|
+
.ruby .method { color: #FFCC00; }
|
|
252
|
+
.ruby .number { color: white; }
|
|
253
|
+
.ruby .char { color: white; }
|
|
254
|
+
.ruby .comment { color: #9933CC; }
|
|
255
|
+
.ruby .symbol { color: white; }
|
|
256
|
+
.ruby .regex { color: #44B4CC; }
|
|
257
|
+
.ruby .punct { color: white; }
|
|
258
|
+
.ruby .escape { color: white; }
|
|
259
|
+
.ruby .interp { color: white; }
|
|
260
|
+
.ruby .expr { color: white; }
|
|
261
|
+
|
|
262
|
+
.ruby .offending { background-color: gray; }
|
|
263
|
+
.ruby .linenum {
|
|
264
|
+
width: 75px;
|
|
265
|
+
padding: 0.1em 1em 0.2em 0;
|
|
266
|
+
color: #000000;
|
|
267
|
+
background-color: #FFFBD3;
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
div.rspec-report textarea {
|
|
271
|
+
width: 100%;
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
div.rspec-report .dyn-source {
|
|
275
|
+
background: #FFFFEE none repeat scroll 0%;
|
|
276
|
+
border:1px dotted black;
|
|
277
|
+
color: #000000;
|
|
278
|
+
display: none;
|
|
279
|
+
margin: 0.5em 2em;
|
|
280
|
+
padding: 0.5em;
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
|
|
284
|
+
</style>
|
|
285
|
+
</head>
|
|
286
|
+
<body>
|
|
287
|
+
<div class="rspec-report">
|
|
288
|
+
|
|
289
|
+
<div id="rspec-header">
|
|
290
|
+
<div id="label">
|
|
291
|
+
<h1>RSpec Code Examples</h1>
|
|
292
|
+
</div>
|
|
293
|
+
|
|
294
|
+
<div id="display-filters">
|
|
295
|
+
<input id="passed_checkbox" name="passed_checkbox" type="checkbox" checked onchange="apply_filters()" value="1"> <label for="passed_checkbox">Passed</label>
|
|
296
|
+
<input id="failed_checkbox" name="failed_checkbox" type="checkbox" checked onchange="apply_filters()" value="2"> <label for="failed_checkbox">Failed</label>
|
|
297
|
+
<input id="pending_checkbox" name="pending_checkbox" type="checkbox" checked onchange="apply_filters()" value="3"> <label for="pending_checkbox">Pending</label>
|
|
298
|
+
</div>
|
|
299
|
+
|
|
300
|
+
<div id="summary">
|
|
301
|
+
<p id="totals"> </p>
|
|
302
|
+
<p id="duration"> </p>
|
|
303
|
+
</div>
|
|
304
|
+
</div>
|
|
305
|
+
|
|
306
|
+
|
|
307
|
+
<div class="results">
|
|
308
|
+
<div id="div_group_1" class="example_group passed">
|
|
309
|
+
<dl style="margin-left: 0px;">
|
|
310
|
+
<dt id="example_group_1" class="passed">Report</dt>
|
|
311
|
+
<dd class="example passed"><span class="passed_spec_name">Generates a clean report when needed</span></dd>
|
|
312
|
+
<script type="text/javascript">makeRed('rspec-header');</script>
|
|
313
|
+
<script type="text/javascript">makeRed('div_group_1');</script>
|
|
314
|
+
<script type="text/javascript">makeRed('example_group_1');</script>
|
|
315
|
+
<dd class="example failed">
|
|
316
|
+
<span class="failed_spec_name">Generates a clean report when needed</span>
|
|
317
|
+
<div class="failure" id="failure_1">
|
|
318
|
+
<div class="message"><pre><false> is not true.</pre></div>
|
|
319
|
+
<div class="backtrace"><pre>./spec/example_run.rb:21</pre></div>
|
|
320
|
+
<pre class="ruby"><code><span class="linenum">19</span> @driver.navigate.to "http://google.com"
|
|
321
|
+
<span class="linenum">20</span> element = @driver.find_element(:name, 'q')
|
|
322
|
+
<span class="offending"><span class="linenum">21</span> assert false</span>
|
|
323
|
+
<span class="linenum">22</span> element.send_keys "Hello Web@driver!"
|
|
324
|
+
<span class="linenum">23</span> element.submit
|
|
325
|
+
<span class="linenum">24</span><span class="comment"># gem install syntax to get syntax highlighting</span></code></pre>
|
|
326
|
+
<div>[
|
|
327
|
+
<a id="example_ZASDF_snapshot_link"
|
|
328
|
+
href="javascript:toggleVisilibility('example_ZASDF_snapshot', 'Dynamic HTML Snapshot')">Show Dynamic HTML Snapshot</a>
|
|
329
|
+
]</div>
|
|
330
|
+
<br/><br/>
|
|
331
|
+
<div id="example_ZASDF_snapshot" class="dyn-source">
|
|
332
|
+
<a href="resources/spec_test_report/example_ZASDF.html">Full screen</a><br/><br/>
|
|
333
|
+
<iframe src="resources/spec_test_report/example_ZASDF.html" width="100%" height="600px" ></iframe>
|
|
334
|
+
</div>
|
|
335
|
+
|
|
336
|
+
|
|
337
|
+
<div>[<a id="example_ZASDF_page_screenshot_link" href="javascript:toggleVisilibility('example_ZASDF_page_screenshot', 'Page Screenshot');">Show Page Screenshot</a>]</div>
|
|
338
|
+
<br/>
|
|
339
|
+
<div id="example_ZASDF_page_screenshot" style="display: none">
|
|
340
|
+
<a href="resources/spec_test_report/example_ZASDF_page_screenshot.png">
|
|
341
|
+
<img width="80%" src="resources/spec_test_report/example_ZASDF_page_screenshot.png" />
|
|
342
|
+
</a>
|
|
343
|
+
</div>
|
|
344
|
+
<br/>
|
|
345
|
+
|
|
346
|
+
|
|
347
|
+
</div>
|
|
348
|
+
</dd>
|
|
349
|
+
</dl>
|
|
350
|
+
</div>
|
|
351
|
+
<script type="text/javascript">document.getElementById('duration').innerHTML = "Finished in <strong>x seconds</strong>";</script>
|
|
352
|
+
<script type="text/javascript">document.getElementById('totals').innerHTML = "2 examples, 1 failure";</script>
|
|
353
|
+
</div>
|
|
354
|
+
</div>
|
|
355
|
+
</body>
|
|
356
|
+
</html>
|
metadata
ADDED
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: rspec-webdriver
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
hash: 29
|
|
5
|
+
prerelease: false
|
|
6
|
+
segments:
|
|
7
|
+
- 0
|
|
8
|
+
- 0
|
|
9
|
+
- 1
|
|
10
|
+
version: 0.0.1
|
|
11
|
+
platform: ruby
|
|
12
|
+
authors:
|
|
13
|
+
- Brian Faherty
|
|
14
|
+
autorequire:
|
|
15
|
+
bindir: bin
|
|
16
|
+
cert_chain: []
|
|
17
|
+
|
|
18
|
+
date: 2011-04-08 00:00:00 -07:00
|
|
19
|
+
default_executable:
|
|
20
|
+
dependencies: []
|
|
21
|
+
|
|
22
|
+
description: RSpec reporting for selenium-webdriver
|
|
23
|
+
email: anothergenericuser+ruby@gmail.com
|
|
24
|
+
executables: []
|
|
25
|
+
|
|
26
|
+
extensions: []
|
|
27
|
+
|
|
28
|
+
extra_rdoc_files: []
|
|
29
|
+
|
|
30
|
+
files:
|
|
31
|
+
- .gitignore
|
|
32
|
+
- Gemfile
|
|
33
|
+
- README.md
|
|
34
|
+
- Rakefile
|
|
35
|
+
- lib/rspec/reporting/file_path_strategy.rb
|
|
36
|
+
- lib/rspec/reporting/html_report.rb
|
|
37
|
+
- lib/rspec/reporting/selenium_test_report_formatter.rb
|
|
38
|
+
- lib/rspec/reporting/system_capture.rb
|
|
39
|
+
- lib/rspec/rspec_extensions.rb
|
|
40
|
+
- lib/rspec/spec_helper.rb
|
|
41
|
+
- rspec-webdriver.gemspec
|
|
42
|
+
- spec/example_run.rb
|
|
43
|
+
- spec/report_spec.rb
|
|
44
|
+
- spec/spec_results_for_comparison.html
|
|
45
|
+
has_rdoc: true
|
|
46
|
+
homepage:
|
|
47
|
+
licenses: []
|
|
48
|
+
|
|
49
|
+
post_install_message:
|
|
50
|
+
rdoc_options:
|
|
51
|
+
- --charset=UTF-8
|
|
52
|
+
require_paths:
|
|
53
|
+
- lib
|
|
54
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
55
|
+
none: false
|
|
56
|
+
requirements:
|
|
57
|
+
- - ">="
|
|
58
|
+
- !ruby/object:Gem::Version
|
|
59
|
+
hash: 3
|
|
60
|
+
segments:
|
|
61
|
+
- 0
|
|
62
|
+
version: "0"
|
|
63
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
64
|
+
none: false
|
|
65
|
+
requirements:
|
|
66
|
+
- - ">="
|
|
67
|
+
- !ruby/object:Gem::Version
|
|
68
|
+
hash: 3
|
|
69
|
+
segments:
|
|
70
|
+
- 0
|
|
71
|
+
version: "0"
|
|
72
|
+
requirements: []
|
|
73
|
+
|
|
74
|
+
rubyforge_project:
|
|
75
|
+
rubygems_version: 1.3.7
|
|
76
|
+
signing_key:
|
|
77
|
+
specification_version: 3
|
|
78
|
+
summary: rspec-webdriver-0.0.1
|
|
79
|
+
test_files: []
|
|
80
|
+
|