sim 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.
- checksums.yaml +15 -0
- data/Gemfile +11 -0
- data/History.md +3 -0
- data/License.txt +22 -0
- data/README.md +27 -0
- data/lib/sim/all_inc.rb +5 -0
- data/lib/sim/custom_parallel_html_formatter.rb +65 -0
- data/lib/sim/fail_fast.rb +39 -0
- data/lib/sim/html_formatter.rb +67 -0
- data/lib/sim/html_report.rb +119 -0
- data/lib/sim/local.rb +13 -0
- data/lib/sim/local_phantomjs.rb +7 -0
- data/lib/sim/logger_base.rb +64 -0
- data/lib/sim/parallel_html_formatter.rb +187 -0
- data/lib/sim/remote.rb +72 -0
- data/lib/sim/support/capybara_util.rb +0 -0
- data/lib/sim/support/config.rb +10 -0
- data/lib/sim/support/cucumber_util.rb +21 -0
- data/lib/sim/support/database_cleaner.rb +14 -0
- data/lib/sim/support/rspec_util.rb +65 -0
- data/lib/sim/support/sim_util.rb +7 -0
- data/lib/sim/support/web_testing.rb +64 -0
- metadata +190 -0
checksums.yaml
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
---
|
2
|
+
!binary "U0hBMQ==":
|
3
|
+
metadata.gz: !binary |-
|
4
|
+
Mzg2OTc5MTlmNDY4OGEzNWU5MDA2NmRiNGFkYmY0YWE5ODQ5NjZhZA==
|
5
|
+
data.tar.gz: !binary |-
|
6
|
+
OGFjMjBkZjA2OWIyNjM3ZjMzMWNiNGMxMGExNTIxOTBiYTVmM2NkOQ==
|
7
|
+
SHA512:
|
8
|
+
metadata.gz: !binary |-
|
9
|
+
YjJkOWE2ZjRjMjk3MGI3MjMxMGZhZGFkNTU1YWJhZWVlZGNmM2E2Nzg3ZDEx
|
10
|
+
ZTVlMDk2YThkOWUzNmM2YzY5Y2E0NTY1MzgwMDNiOWJmNmRhNjdjN2I1MGMw
|
11
|
+
MDZlNTViMzViYTJlNTMyZTIxN2EyNmViMzc3ZDljY2JiZjU2NWE=
|
12
|
+
data.tar.gz: !binary |-
|
13
|
+
ZGFiZjY3NjcyYWZhYjQ4Mzk2OGVlMjRkYjYxOTY3NjZhNGI3ZGY1OGVjN2Iw
|
14
|
+
ZGM0MDhmOWZkN2ZiN2E0NjUxOWIzMGNlZDdmZTdlZjQzZTg2MWZlZWY0Njlj
|
15
|
+
YzcwMTI2ZGQzZjJkMzlhMGZiOTdmOGQ2NTU2ZjE0YzIxZjI4MTA=
|
data/Gemfile
ADDED
@@ -0,0 +1,11 @@
|
|
1
|
+
source 'https://rubygems.org'
|
2
|
+
|
3
|
+
gem "system-getifaddrs", "~> 0.2"
|
4
|
+
gem 'rspec-rails', '~> 2.0'
|
5
|
+
gem "parallel_tests", '~> 0.16'
|
6
|
+
gem 'selenium-webdriver', '~> 2.39'
|
7
|
+
gem 'poltergeist', '~> 1.5'
|
8
|
+
gem 'cucumber-rails', '~> 1.4', :require => false
|
9
|
+
gem 'ci_reporter', '~> 1.9'
|
10
|
+
gem "capybara", "~> 2.1"
|
11
|
+
gem 'database_cleaner', '~> 1.2'
|
data/History.md
ADDED
data/License.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
(The MIT License)
|
2
|
+
|
3
|
+
Copyright (c) 2009-2012 Jonas Nicklas
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
'Software'), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
19
|
+
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
20
|
+
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
21
|
+
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
22
|
+
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
# Rspec-Capybara-Jenkins
|
2
|
+
|
3
|
+
## Key benefits
|
4
|
+
|
5
|
+
- Integrate Capybara with:
|
6
|
+
Jenkins
|
7
|
+
parallel_test
|
8
|
+
thread-safe HTML reporting
|
9
|
+
- pre-configured switch between:
|
10
|
+
local
|
11
|
+
remote
|
12
|
+
fail fast
|
13
|
+
|
14
|
+
## Setup
|
15
|
+
|
16
|
+
sim requires Ruby 1.9.3 or later. To install, type:
|
17
|
+
|
18
|
+
```bash
|
19
|
+
gem install sim
|
20
|
+
```
|
21
|
+
|
22
|
+
|
23
|
+
|
24
|
+
|
25
|
+
|
26
|
+
|
27
|
+
|
data/lib/sim/all_inc.rb
ADDED
@@ -0,0 +1,65 @@
|
|
1
|
+
require_relative 'parallel_html_formatter'
|
2
|
+
require 'erb'
|
3
|
+
require_relative 'support/utilities'
|
4
|
+
require_relative 'html_report'
|
5
|
+
|
6
|
+
class CustomParallelHtmlFormatter < ParallelHtmlFormatter
|
7
|
+
include ERB::Util
|
8
|
+
include HTMLReport
|
9
|
+
|
10
|
+
def initialize(output)
|
11
|
+
super
|
12
|
+
# raise "output has to be a file path!" unless output.is_a?(String)
|
13
|
+
@output_dir = File.dirname(@output)
|
14
|
+
end
|
15
|
+
|
16
|
+
def example_passed(example)
|
17
|
+
example_passed_helper(example, @buffer)
|
18
|
+
end
|
19
|
+
|
20
|
+
def example_failed(example)
|
21
|
+
example_failed_helper(example, @buffer)
|
22
|
+
end
|
23
|
+
|
24
|
+
def example_group_started(example_group)
|
25
|
+
super(example_group)
|
26
|
+
end
|
27
|
+
|
28
|
+
def example_group_finished(example_group)
|
29
|
+
super(example_group)
|
30
|
+
end
|
31
|
+
|
32
|
+
def example_started(example)
|
33
|
+
super(example)
|
34
|
+
end
|
35
|
+
|
36
|
+
def print_screenshot(example)
|
37
|
+
print_screenshot_helper(example, @buffer)
|
38
|
+
end
|
39
|
+
|
40
|
+
def example_pending(example)
|
41
|
+
super(example)
|
42
|
+
end
|
43
|
+
|
44
|
+
def extra_failure_content(failure)
|
45
|
+
content = []
|
46
|
+
content << "<span>"
|
47
|
+
content << ""
|
48
|
+
content << "</span>"
|
49
|
+
super + content.join($/)
|
50
|
+
end
|
51
|
+
|
52
|
+
def link_for(file_name)
|
53
|
+
return unless file_name && File.exists?(file_name)
|
54
|
+
|
55
|
+
description = File.extname(file_name).upcase[1..-1]
|
56
|
+
path = Pathname.new(file_name)
|
57
|
+
"<a href='#{path.relative_path_from(Pathname.new(@output_dir))}'>#{description}</a> "
|
58
|
+
end
|
59
|
+
|
60
|
+
# def start(example_count)
|
61
|
+
# lock_output do
|
62
|
+
# super(example_count)
|
63
|
+
# end
|
64
|
+
# end
|
65
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
require_relative 'all_inc.rb'
|
2
|
+
|
3
|
+
require 'rspec/rails'
|
4
|
+
require 'capybara/rails'
|
5
|
+
|
6
|
+
require_relative 'support/config'
|
7
|
+
|
8
|
+
puts "loading fail_fast.rb"
|
9
|
+
|
10
|
+
RSpec.configure do |config|
|
11
|
+
config.fail_fast = true
|
12
|
+
|
13
|
+
config.after(:each) do
|
14
|
+
if example.exception
|
15
|
+
# stub in browser close method
|
16
|
+
Selenium::WebDriver::Driver.class_eval do
|
17
|
+
def quit
|
18
|
+
puts "preventing browser close"
|
19
|
+
#STDOUT.puts "#{self.class}#quit: no-op"
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
# stub in driver close method
|
24
|
+
Selenium::WebDriver::Chrome::Service.class_eval do
|
25
|
+
def stop
|
26
|
+
puts "preventing ChromeDriver stop"
|
27
|
+
#STDOUT.puts "#{self.class}#stop: no-op"
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
# stub in Capybara's reset which to resets browser to about page
|
32
|
+
Capybara::Selenium::Driver.class_eval do
|
33
|
+
def reset!
|
34
|
+
puts "preventing reset to about page"
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
require 'rspec/core/formatters/html_formatter'
|
2
|
+
require 'erb'
|
3
|
+
require_relative 'support/utilities'
|
4
|
+
require_relative 'html_report'
|
5
|
+
|
6
|
+
class CapybaraHtmlFormatter < RSpec::Core::Formatters::HtmlFormatter
|
7
|
+
include ERB::Util
|
8
|
+
include HTMLReport
|
9
|
+
|
10
|
+
def initialize(output)
|
11
|
+
super
|
12
|
+
# raise "output has to be a file path!" unless output.is_a?(String)
|
13
|
+
@output_dir = File.dirname(@output)
|
14
|
+
end
|
15
|
+
|
16
|
+
def example_passed(example)
|
17
|
+
example_passed_helper(example, @output)
|
18
|
+
|
19
|
+
@printer.flush
|
20
|
+
@output.flush
|
21
|
+
end
|
22
|
+
|
23
|
+
def example_failed(example)
|
24
|
+
example_failed_helper(example, @output)
|
25
|
+
|
26
|
+
@printer.flush
|
27
|
+
@output.flush
|
28
|
+
end
|
29
|
+
|
30
|
+
def example_group_started(example_group)
|
31
|
+
super(example_group)
|
32
|
+
end
|
33
|
+
|
34
|
+
def example_group_finished(example_group)
|
35
|
+
super(example_group)
|
36
|
+
end
|
37
|
+
|
38
|
+
def example_started(example)
|
39
|
+
super(example)
|
40
|
+
end
|
41
|
+
|
42
|
+
def print_screenshot(example)
|
43
|
+
print_screenshot_helper(example, @output)
|
44
|
+
|
45
|
+
@output.flush
|
46
|
+
end
|
47
|
+
|
48
|
+
def example_pending(example)
|
49
|
+
super(example)
|
50
|
+
end
|
51
|
+
|
52
|
+
def extra_failure_content(failure)
|
53
|
+
content = []
|
54
|
+
content << "<span>"
|
55
|
+
content << ""
|
56
|
+
content << "</span>"
|
57
|
+
super + content.join($/)
|
58
|
+
end
|
59
|
+
|
60
|
+
def link_for(file_name)
|
61
|
+
return unless file_name && File.exists?(file_name)
|
62
|
+
|
63
|
+
description = File.extname(file_name).upcase[1..-1]
|
64
|
+
path = Pathname.new(file_name)
|
65
|
+
"<a href='#{path.relative_path_from(Pathname.new(@output_dir))}'>#{description}</a> "
|
66
|
+
end
|
67
|
+
end
|
@@ -0,0 +1,119 @@
|
|
1
|
+
require_relative 'support/utilities'
|
2
|
+
|
3
|
+
module HTMLReport
|
4
|
+
def example_passed_helper(example, output_buffer)
|
5
|
+
move_tmp_to_final(example)
|
6
|
+
@printer.move_progress(percent_done)
|
7
|
+
|
8
|
+
description = example.metadata[:description_args].join('')
|
9
|
+
run_time = example.execution_result[:run_time]
|
10
|
+
formatted_run_time = sprintf("%.5f", run_time)
|
11
|
+
output_buffer.puts " <dd class=\"example passed\"><span class=\"passed_spec_name\">#{h(description)}</span><span class='duration'>#{formatted_run_time}s</span>"
|
12
|
+
|
13
|
+
output_buffer.puts "<div class=\"screenshots\">"
|
14
|
+
print_screenshot(example)
|
15
|
+
output_buffer.puts "</div>"
|
16
|
+
|
17
|
+
output_buffer.puts "</dd>"
|
18
|
+
end
|
19
|
+
|
20
|
+
def example_failed_helper(example, output_buffer)
|
21
|
+
move_tmp_to_final(example)
|
22
|
+
unless @header_red
|
23
|
+
@header_red = true
|
24
|
+
@printer.make_header_red
|
25
|
+
end
|
26
|
+
|
27
|
+
unless @example_group_red
|
28
|
+
@example_group_red = true
|
29
|
+
@printer.make_example_group_header_red(example_group_number)
|
30
|
+
end
|
31
|
+
|
32
|
+
@printer.move_progress(percent_done)
|
33
|
+
|
34
|
+
exception = example.metadata[:execution_result][:exception]
|
35
|
+
exception_details = if exception
|
36
|
+
{
|
37
|
+
:class => exception.class.to_s,
|
38
|
+
:message => exception.message,
|
39
|
+
:backtrace => format_backtrace(exception.backtrace, example).join("\n")
|
40
|
+
}
|
41
|
+
else
|
42
|
+
false
|
43
|
+
end
|
44
|
+
extra = extra_failure_content(exception)
|
45
|
+
|
46
|
+
pending_fixed = example.execution_result[:pending_fixed]
|
47
|
+
description = example.description
|
48
|
+
run_time = example.execution_result[:run_time]
|
49
|
+
failure_id = @failed_examples.size
|
50
|
+
exception = exception_details
|
51
|
+
extra_content = (extra == "") ? false : extra
|
52
|
+
escape_backtrace = true
|
53
|
+
formatted_run_time = sprintf("%.5f", run_time)
|
54
|
+
|
55
|
+
output_buffer.puts " <dd class=\"example #{pending_fixed ? 'pending_fixed' : 'failed'}\">"
|
56
|
+
output_buffer.puts " <span class=\"failed_spec_name\">#{h(description)}</span>"
|
57
|
+
output_buffer.puts " <span class=\"duration\">#{formatted_run_time}s</span>"
|
58
|
+
output_buffer.puts " <div class=\"failure\" id=\"failure_#{failure_id}\">"
|
59
|
+
if exception
|
60
|
+
output_buffer.puts " <div class=\"class\"><pre>#{h(exception[:class])}</pre></div>"
|
61
|
+
output_buffer.puts " <div class=\"message\"><pre>#{h(exception[:message])}</pre></div>"
|
62
|
+
if escape_backtrace
|
63
|
+
output_buffer.puts " <div class=\"backtrace\"><pre>#{h exception[:backtrace]}</pre></div>"
|
64
|
+
else
|
65
|
+
output_buffer.puts " <div class=\"backtrace\"><pre>#{exception[:backtrace]}</pre></div>"
|
66
|
+
end
|
67
|
+
end
|
68
|
+
output_buffer.puts extra_content if extra_content
|
69
|
+
output_buffer.puts " </div>"
|
70
|
+
|
71
|
+
output_buffer.puts "<div class=\"rerun_command\">bundle exec rspec " + example.metadata[:file_path] + ":" + example.metadata[:line_number].to_s + $local_run_args + "</div>"
|
72
|
+
output_buffer.puts "<div class=\"screenshots\">"
|
73
|
+
output_buffer.puts "</div>"
|
74
|
+
print_screenshot(example)
|
75
|
+
output_buffer.puts " </dd>"
|
76
|
+
end
|
77
|
+
|
78
|
+
def print_screenshot_helper(example, output_buffer)
|
79
|
+
file_count = Dir[File.join(example.metadata[:screenshot_path], '*.html')].count
|
80
|
+
max_columns = 8
|
81
|
+
curr_column = 0
|
82
|
+
|
83
|
+
if file_count > 0 then output_buffer.puts "<table>" end
|
84
|
+
|
85
|
+
Dir[File.join(example.metadata[:screenshot_path], '*.html')].sort_by{|filename| filename }.each do |path|
|
86
|
+
if curr_column == 0 then output_buffer.puts "<tr>" end
|
87
|
+
output_buffer.puts " <td>"
|
88
|
+
|
89
|
+
path_to_html = Pathname.new(path).relative_path_from(Pathname.new(@output_dir))
|
90
|
+
file_name_no_extension = File.basename(path_to_html.basename, '.*')
|
91
|
+
directory = Pathname.new(path).dirname
|
92
|
+
relative_path_to_img = File.join(path_to_html.dirname, file_name_no_extension) + '.png'
|
93
|
+
absolute_path_to_img = File.join(directory, file_name_no_extension) + '.png'
|
94
|
+
|
95
|
+
if File.file?(absolute_path_to_img)
|
96
|
+
output_buffer.puts " <a href=\"#{relative_path_to_img}\" style=\"text-decoration: none;\">"
|
97
|
+
output_buffer.puts " <img src=\"#{relative_path_to_img}\" alt=\"#{item}\" height=\"100\" width=\"100\">"
|
98
|
+
output_buffer.puts " </a>"
|
99
|
+
output_buffer.puts " </br>"
|
100
|
+
end
|
101
|
+
output_buffer.puts " <a href=\"#{path_to_html}\" style=\"text-decoration: none;\">"
|
102
|
+
output_buffer.puts " <pre align=\"center\">#{dealphabetize_names(File.basename(path, '.*'))}</pre>"
|
103
|
+
output_buffer.puts " </a>"
|
104
|
+
output_buffer.puts " </td>"
|
105
|
+
if curr_column == (max_columns - 1) then output_buffer.puts "</tr>" end
|
106
|
+
curr_column = (curr_column + 1) % (max_columns - 1)
|
107
|
+
end
|
108
|
+
|
109
|
+
if (curr_column != 0) then output_buffer.puts("</tr>") end
|
110
|
+
if (file_count > 0) then output_buffer.puts("</table>") end
|
111
|
+
end
|
112
|
+
|
113
|
+
def move_tmp_to_final(example)
|
114
|
+
if path_to_tmp(example) != path_to_screenshot(example)
|
115
|
+
FileUtils.mv(path_to_tmp(example), path_to_screenshot(example))
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
data/lib/sim/local.rb
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
require_relative 'all_inc.rb'
|
2
|
+
|
3
|
+
require_relative 'support/config'
|
4
|
+
require 'capybara/rails'
|
5
|
+
|
6
|
+
puts "loading local.rb"
|
7
|
+
|
8
|
+
# Capybara local run
|
9
|
+
Capybara.javascript_driver = :selenium
|
10
|
+
Capybara.default_driver = :selenium
|
11
|
+
Capybara.register_driver :selenium do |app|
|
12
|
+
Capybara::Selenium::Driver.new(app, :browser => :chrome)
|
13
|
+
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
module ParallelTests
|
2
|
+
module RSpec
|
3
|
+
end
|
4
|
+
end
|
5
|
+
|
6
|
+
begin
|
7
|
+
require 'rspec/core/formatters/base_text_formatter'
|
8
|
+
base = RSpec::Core::Formatters::BaseTextFormatter
|
9
|
+
rescue LoadError
|
10
|
+
require 'spec/runner/formatter/base_text_formatter'
|
11
|
+
base = Spec::Runner::Formatter::BaseTextFormatter
|
12
|
+
end
|
13
|
+
|
14
|
+
ParallelTests::RSpec::LoggerBaseBase = base
|
15
|
+
|
16
|
+
class ParallelTests::RSpec::LoggerBase < ParallelTests::RSpec::LoggerBaseBase
|
17
|
+
RSPEC_1 = !defined?(RSpec::Core::Formatters::BaseTextFormatter) # do not test for Spec, this will trigger deprecation warning in rspec 2
|
18
|
+
|
19
|
+
def initialize(*args)
|
20
|
+
super
|
21
|
+
|
22
|
+
@output ||= args[1] || args[0] # rspec 1 has output as second argument
|
23
|
+
|
24
|
+
if String === @output # a path ?
|
25
|
+
FileUtils.mkdir_p(File.dirname(@output))
|
26
|
+
File.open(@output, 'w'){} # overwrite previous results
|
27
|
+
@output = File.open(@output, 'a')
|
28
|
+
elsif File === @output # close and restart in append mode
|
29
|
+
@output.close
|
30
|
+
@output = File.open(@output.path, 'a')
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
#stolen from Rspec
|
35
|
+
def close
|
36
|
+
@output.close if (IO === @output) & (@output != $stdout)
|
37
|
+
end
|
38
|
+
|
39
|
+
# do not let multiple processes get in each others way
|
40
|
+
def lock_output
|
41
|
+
if File === @output
|
42
|
+
begin
|
43
|
+
@output.flock File::LOCK_EX
|
44
|
+
yield
|
45
|
+
ensure
|
46
|
+
@output.flock File::LOCK_UN
|
47
|
+
end
|
48
|
+
else
|
49
|
+
yield
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
def lock_output_begin
|
54
|
+
if File === @output
|
55
|
+
@output.flock File::LOCK_EX
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
def lock_output_end
|
60
|
+
if File === @output
|
61
|
+
@output.flock File::LOCK_UN
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
@@ -0,0 +1,187 @@
|
|
1
|
+
|
2
|
+
require 'rspec/core/formatters/html_printer'
|
3
|
+
require 'parallel_tests'
|
4
|
+
require 'parallel_tests/rspec/logger_base'
|
5
|
+
|
6
|
+
class ParallelHtmlFormatter < ParallelTests::RSpec::LoggerBase
|
7
|
+
def initialize(output)
|
8
|
+
super(output)
|
9
|
+
|
10
|
+
@buffer = StringIO.new
|
11
|
+
@header_buffer = StringIO.new
|
12
|
+
|
13
|
+
@example_group_number = 0
|
14
|
+
@example_number = 0
|
15
|
+
@header_red = nil
|
16
|
+
@printer = RSpec::Core::Formatters::HtmlPrinter.new(@buffer)
|
17
|
+
|
18
|
+
@header_printer = RSpec::Core::Formatters::HtmlPrinter.new(@header_buffer)
|
19
|
+
|
20
|
+
if ENV[:TEST_ENV_NUMBER.to_s] == ""
|
21
|
+
# puts %[hello from process #{ENV[:TEST_ENV_NUMBER.to_s].inspect}]
|
22
|
+
# puts ENV[:TEST_ENV_NUMBER.to_s].class
|
23
|
+
|
24
|
+
# lock this whole section so other threads don't get ahead of the html header flush
|
25
|
+
lock_output do
|
26
|
+
@header_printer.print_html_start
|
27
|
+
@header_buffer.puts "<input id=\"curr_duration\" type=\"hidden\" value=\"0\"/>"
|
28
|
+
@header_buffer.puts "<input id=\"curr_example_count\" type=\"hidden\" value=\"0\"/>"
|
29
|
+
@header_buffer.puts "<input id=\"curr_failure_count\" type=\"hidden\" value=\"0\"/>"
|
30
|
+
@output.puts @header_buffer.string
|
31
|
+
|
32
|
+
@output.flush
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
private
|
38
|
+
def method_missing(m, *a, &b)
|
39
|
+
# no-op
|
40
|
+
end
|
41
|
+
|
42
|
+
public
|
43
|
+
def message(message)
|
44
|
+
end
|
45
|
+
|
46
|
+
# The number of the currently running example_group
|
47
|
+
def example_group_number
|
48
|
+
@example_group_number
|
49
|
+
end
|
50
|
+
|
51
|
+
# The number of the currently running example (a global counter)
|
52
|
+
def example_number
|
53
|
+
@example_number
|
54
|
+
end
|
55
|
+
|
56
|
+
def start(example_count)
|
57
|
+
super(example_count)
|
58
|
+
end
|
59
|
+
|
60
|
+
def example_group_started(example_group)
|
61
|
+
super(example_group)
|
62
|
+
@example_group_red = false
|
63
|
+
@example_group_number += 1
|
64
|
+
|
65
|
+
unless example_group_number == 1
|
66
|
+
@printer.print_example_group_end
|
67
|
+
end
|
68
|
+
@printer.print_example_group_start( example_group_number, example_group.description, example_group.parent_groups.size )
|
69
|
+
end
|
70
|
+
|
71
|
+
def start_dump
|
72
|
+
@printer.print_example_group_end
|
73
|
+
end
|
74
|
+
|
75
|
+
def example_started(example)
|
76
|
+
super(example)
|
77
|
+
@example_number += 1
|
78
|
+
end
|
79
|
+
|
80
|
+
def example_passed(example)
|
81
|
+
@printer.move_progress(percent_done)
|
82
|
+
@printer.print_example_passed( example.description, example.execution_result[:run_time] )
|
83
|
+
end
|
84
|
+
|
85
|
+
def example_failed(example)
|
86
|
+
super(example)
|
87
|
+
|
88
|
+
unless @header_red
|
89
|
+
@header_red = true
|
90
|
+
@printer.make_header_red
|
91
|
+
end
|
92
|
+
|
93
|
+
unless @example_group_red
|
94
|
+
@example_group_red = true
|
95
|
+
@printer.make_example_group_header_red(example_group_number)
|
96
|
+
end
|
97
|
+
|
98
|
+
@printer.move_progress(percent_done)
|
99
|
+
|
100
|
+
exception = example.metadata[:execution_result][:exception]
|
101
|
+
exception_details = if exception
|
102
|
+
{
|
103
|
+
:message => exception.message,
|
104
|
+
:backtrace => format_backtrace(exception.backtrace, example).join("\n")
|
105
|
+
}
|
106
|
+
else
|
107
|
+
false
|
108
|
+
end
|
109
|
+
extra = extra_failure_content(exception)
|
110
|
+
|
111
|
+
@printer.print_example_failed(
|
112
|
+
example.execution_result[:pending_fixed],
|
113
|
+
example.description,
|
114
|
+
example.execution_result[:run_time],
|
115
|
+
@failed_examples.size,
|
116
|
+
exception_details,
|
117
|
+
(extra == "") ? false : extra,
|
118
|
+
true
|
119
|
+
)
|
120
|
+
end
|
121
|
+
|
122
|
+
def example_pending(example)
|
123
|
+
|
124
|
+
@printer.make_header_yellow unless @header_red
|
125
|
+
@printer.make_example_group_header_yellow(example_group_number) unless @example_group_red
|
126
|
+
@printer.move_progress(percent_done)
|
127
|
+
@printer.print_example_pending( example.description, example.metadata[:execution_result][:pending_message] )
|
128
|
+
end
|
129
|
+
|
130
|
+
# Override this method if you wish to output extra HTML for a failed spec. For example, you
|
131
|
+
# could output links to images or other files produced during the specs.
|
132
|
+
#
|
133
|
+
def extra_failure_content(exception)
|
134
|
+
require 'rspec/core/formatters/snippet_extractor'
|
135
|
+
backtrace = exception.backtrace.map {|line| backtrace_line(line)}
|
136
|
+
backtrace.compact!
|
137
|
+
@snippet_extractor ||= RSpec::Core::Formatters::SnippetExtractor.new
|
138
|
+
" <pre class=\"ruby\"><code>#{@snippet_extractor.snippet(backtrace)}</code></pre>"
|
139
|
+
end
|
140
|
+
|
141
|
+
def percent_done
|
142
|
+
result = 100.0
|
143
|
+
if @example_count > 0
|
144
|
+
result = (((example_number).to_f / @example_count.to_f * 1000).to_i / 10.0).to_f
|
145
|
+
end
|
146
|
+
result
|
147
|
+
end
|
148
|
+
|
149
|
+
def dump_failures
|
150
|
+
end
|
151
|
+
|
152
|
+
def dump_pending
|
153
|
+
end
|
154
|
+
|
155
|
+
def dump_summary(duration, example_count, failure_count, pending_count)
|
156
|
+
# @printer.print_summary(
|
157
|
+
# dry_run?,
|
158
|
+
# duration,
|
159
|
+
# example_count,
|
160
|
+
# failure_count,
|
161
|
+
# pending_count
|
162
|
+
# )
|
163
|
+
# TODO - kill dry_run?
|
164
|
+
|
165
|
+
formatted_duration = sprintf("%.5f", duration)
|
166
|
+
|
167
|
+
@buffer.puts "<script type=\"text/javascript\">"
|
168
|
+
@buffer.puts " var curr_duration = parseFloat(document.getElementById('curr_duration').value) + #{formatted_duration};"
|
169
|
+
@buffer.puts " document.getElementById('curr_duration').value = curr_duration;"
|
170
|
+
@buffer.puts " document.getElementById('duration').innerHTML = 'Finished in <strong>' + curr_duration.toFixed(3) + ' seconds</strong>';"
|
171
|
+
@buffer.puts "</script>"
|
172
|
+
@buffer.puts "<script type=\"text/javascript\">"
|
173
|
+
@buffer.puts " var curr_example_count = Number(document.getElementById('curr_example_count').value) + #{example_count};"
|
174
|
+
@buffer.puts " var curr_failure_count = Number(document.getElementById('curr_failure_count').value) + #{failure_count};"
|
175
|
+
@buffer.puts " document.getElementById('curr_example_count').value = curr_example_count;"
|
176
|
+
@buffer.puts " document.getElementById('curr_failure_count').value = curr_failure_count;"
|
177
|
+
@buffer.puts " document.getElementById('totals').innerHTML = curr_example_count + ' example(s),' + curr_failure_count + ' failure(s)';"
|
178
|
+
@buffer.puts "</script>"
|
179
|
+
@buffer.puts "</div>"
|
180
|
+
@buffer.puts "</div>"
|
181
|
+
|
182
|
+
lock_output do
|
183
|
+
@output.puts @buffer.string
|
184
|
+
@output.flush
|
185
|
+
end
|
186
|
+
end
|
187
|
+
end
|
data/lib/sim/remote.rb
ADDED
@@ -0,0 +1,72 @@
|
|
1
|
+
puts "loading support/remote.rb"
|
2
|
+
|
3
|
+
require_relative 'all_inc.rb'
|
4
|
+
require_relative 'support/config'
|
5
|
+
require 'selenium-webdriver'
|
6
|
+
require 'rspec/rails'
|
7
|
+
require 'capybara/rails'
|
8
|
+
|
9
|
+
def set_app_address()
|
10
|
+
require 'system/getifaddrs'
|
11
|
+
ip = $webserver_ip != nil ? $webserver_ip : System.get_ifaddrs.find{ |socket| socket[1][:inet_addr] != "127.0.0.1" } [1][:inet_addr]
|
12
|
+
port = $webserver_port != nil ? $webserver_port : Capybara.current_session.server.port
|
13
|
+
Capybara.app_host = "http://#{ip}:#{port}"
|
14
|
+
puts "Registering http://#{ip}:#{port} as root server"
|
15
|
+
end
|
16
|
+
|
17
|
+
Capybara.javascript_driver = :selenium_chrome
|
18
|
+
Capybara.default_driver = :selenium_phantomjs
|
19
|
+
|
20
|
+
# Capybara remote run
|
21
|
+
# # init ip
|
22
|
+
caps = Selenium::WebDriver::Remote::Capabilities.chrome
|
23
|
+
# caps.version = "8"
|
24
|
+
caps.platform = :WINDOWS
|
25
|
+
|
26
|
+
Capybara.register_driver :selenium_chrome do |app|
|
27
|
+
Capybara::Selenium::Driver.new(
|
28
|
+
app,
|
29
|
+
:browser => :remote,
|
30
|
+
:url => "http://#{$grid_host}:#{$grid_port}/wd/hub",
|
31
|
+
:desired_capabilities => caps
|
32
|
+
)
|
33
|
+
end
|
34
|
+
|
35
|
+
# Capybara remote run phantomjs
|
36
|
+
# # init ip
|
37
|
+
caps_phantomjs = Selenium::WebDriver::Remote::Capabilities.phantomjs
|
38
|
+
# caps.version = "8"
|
39
|
+
# caps_phantomjs.platform = :WINDOWS
|
40
|
+
|
41
|
+
Capybara.register_driver :selenium_phantomjs do |app|
|
42
|
+
Capybara::Selenium::Driver.new(
|
43
|
+
app,
|
44
|
+
:browser => :remote,
|
45
|
+
:url => "http://#{$grid_host}:#{$grid_port}/wd/hub",
|
46
|
+
:desired_capabilities => caps_phantomjs
|
47
|
+
)
|
48
|
+
end
|
49
|
+
|
50
|
+
if is_cucumber()
|
51
|
+
puts "yes"
|
52
|
+
Before do |scenario|
|
53
|
+
set_app_address()
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
if is_rspec()
|
58
|
+
puts "no"
|
59
|
+
RSpec.configure do |config|
|
60
|
+
config.include Capybara::DSL
|
61
|
+
|
62
|
+
# this allows each test to use the proper port when using
|
63
|
+
# Capybara's "random available port"
|
64
|
+
config.before(:each) do
|
65
|
+
next if Capybara.current_session.server.nil?
|
66
|
+
|
67
|
+
set_app_address()
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
|
File without changes
|
@@ -0,0 +1,10 @@
|
|
1
|
+
$cucumber_base_report_dir = "features/report"
|
2
|
+
$base_screenshot_dir = 'spec/reports/HTML/screenshots'
|
3
|
+
$local_run_args = ' -r html_formatter.rb -f CapybaraHtmlFormatter -o spec/reports/HTML/index.html -r fail_fast.rb -r local.rb '
|
4
|
+
|
5
|
+
$grid_host = "10.242.1.187"
|
6
|
+
$grid_port = "4444"
|
7
|
+
|
8
|
+
# webserver_ip
|
9
|
+
#$webserver_ip = '10.242.1.171'
|
10
|
+
#$webserver_port = 3000
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module Utilities
|
2
|
+
def full_title(page_title)
|
3
|
+
base_title = "Ruby on Rails Tutorial Sample App"
|
4
|
+
if page_title.empty?
|
5
|
+
base_title
|
6
|
+
else
|
7
|
+
"#{base_title} | #{page_title}"
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
def path_to(page_name)
|
12
|
+
case page_name
|
13
|
+
when /homepage/
|
14
|
+
root_path
|
15
|
+
else
|
16
|
+
raise "Can't find mapping from \"{page_name}\" to a path."
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
World(Utilities)
|
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'rspec/rails'
|
2
|
+
require 'database_cleaner'
|
3
|
+
|
4
|
+
DatabaseCleaner.strategy = :truncation
|
5
|
+
|
6
|
+
RSpec.configure do |config|
|
7
|
+
config.use_transactional_fixtures = false
|
8
|
+
config.before :each do
|
9
|
+
DatabaseCleaner.start
|
10
|
+
end
|
11
|
+
config.after :each do
|
12
|
+
DatabaseCleaner.clean
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,65 @@
|
|
1
|
+
require 'capybara'
|
2
|
+
|
3
|
+
$filename_padding = 3
|
4
|
+
|
5
|
+
def alphabetize_names(filename)
|
6
|
+
example.metadata[:snapshot_count] + '-' + filename
|
7
|
+
end
|
8
|
+
|
9
|
+
def dealphabetize_names(filename)
|
10
|
+
filename[4..filename.length]
|
11
|
+
end
|
12
|
+
|
13
|
+
def save_snapshot(example,filename)
|
14
|
+
|
15
|
+
ordered_filename = alphabetize_names(filename)
|
16
|
+
save_html_to_file(example, ordered_filename)
|
17
|
+
|
18
|
+
if example.metadata[:js]
|
19
|
+
save_screenshot_to_file(example, ordered_filename)
|
20
|
+
end
|
21
|
+
example.metadata[:snapshot_count] = (example.metadata[:snapshot_count].to_i + 1).to_s.rjust($filename_padding, '0')
|
22
|
+
end
|
23
|
+
|
24
|
+
def save_html_to_file(example, filename)
|
25
|
+
File.open("#{path_to_tmp(example)}/#{filename}.html", 'w') {|f| f.write(page.html) }
|
26
|
+
end
|
27
|
+
|
28
|
+
def save_screenshot_to_file(example, filename)
|
29
|
+
page.save_screenshot("#{path_to_tmp(example)}/#{filename}.png")
|
30
|
+
end
|
31
|
+
|
32
|
+
def path_to_tmp(example)
|
33
|
+
if example.metadata[:tmp_path]
|
34
|
+
return example.metadata[:tmp_path]
|
35
|
+
end
|
36
|
+
example.metadata[:tmp_path] = path_to_screenshot(example)
|
37
|
+
example.metadata[:tmp_path]
|
38
|
+
end
|
39
|
+
|
40
|
+
def path_to_screenshot(example)
|
41
|
+
if example.metadata[:screenshot_path]
|
42
|
+
return example.metadata[:screenshot_path]
|
43
|
+
end
|
44
|
+
desc = example.metadata[:description_args].empty? ? example.metadata[:id] : example.metadata[:description_args].first.gsub('"',"'").gsub('|', '')
|
45
|
+
example.metadata[:screenshot_path] = path_of_example_groups(example, desc)
|
46
|
+
example.metadata[:screenshot_path]
|
47
|
+
end
|
48
|
+
|
49
|
+
def path_of_example_groups(example, desc)
|
50
|
+
# metadata maintains example_group structure as nested example_groups from inner to outer
|
51
|
+
# so we build array from inner to outer and then reverse it
|
52
|
+
groups = []
|
53
|
+
groups << desc
|
54
|
+
current_group = example.metadata[:example_group]
|
55
|
+
while (!current_group.nil?) do
|
56
|
+
groups << current_group[:description]
|
57
|
+
current_group = current_group[:example_group]
|
58
|
+
end
|
59
|
+
|
60
|
+
groups << $base_screenshot_dir
|
61
|
+
|
62
|
+
groups.reverse.join('/')
|
63
|
+
|
64
|
+
end
|
65
|
+
|
@@ -0,0 +1,64 @@
|
|
1
|
+
puts "loading support/web_testing.rb"
|
2
|
+
|
3
|
+
require_relative 'config'
|
4
|
+
require_relative 'sim_util'
|
5
|
+
require_relative 'capybara_util'
|
6
|
+
|
7
|
+
if is_cucumber
|
8
|
+
require_relative 'cucumber_util'
|
9
|
+
require 'capybara/cucumber'
|
10
|
+
|
11
|
+
FileUtils.rm_rf($cucumber_base_report_dir)
|
12
|
+
FileUtils.mkdir($cucumber_base_report_dir) # cucumber does not auto build directory when capturing screenshot
|
13
|
+
|
14
|
+
After do |scenario|
|
15
|
+
# if(scenario.failed?)
|
16
|
+
img_name = "#{scenario.__id__}.png"
|
17
|
+
path_to_img = File.join($cucumber_base_report_dir,img_name)
|
18
|
+
|
19
|
+
page.save_screenshot(path_to_img)
|
20
|
+
|
21
|
+
self.embed(path_to_img, "image/png", "SCREENSHOT")
|
22
|
+
# end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
if is_rspec
|
27
|
+
require_relative 'rspec_util'
|
28
|
+
require 'capybara'
|
29
|
+
require 'rspec/rails'
|
30
|
+
|
31
|
+
# TESTING SUITE
|
32
|
+
FileUtils.rm_rf($base_screenshot_dir)
|
33
|
+
|
34
|
+
RSpec.configure do |config|
|
35
|
+
config.include Capybara::RSpecMatchers
|
36
|
+
config.include Capybara::DSL
|
37
|
+
config.include Rails.application.routes.url_helpers
|
38
|
+
|
39
|
+
# use default driver on all tests
|
40
|
+
# config.after do
|
41
|
+
# Capybara.reset_sessions!
|
42
|
+
# Capybara.use_default_driver
|
43
|
+
# end
|
44
|
+
|
45
|
+
config.before(:each) do
|
46
|
+
# don't test model
|
47
|
+
if example.metadata[:type] != :model
|
48
|
+
example.metadata[:id] = @example_number
|
49
|
+
example.metadata[:snapshot_count] = '000'
|
50
|
+
FileUtils.mkdir_p(path_to_tmp(example)) unless File.exists?(path_to_tmp(example))
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
config.after(:each) do
|
55
|
+
# don't test model
|
56
|
+
if example.metadata[:type] != :model
|
57
|
+
result_name = example.exception ? "failure" : "final"
|
58
|
+
|
59
|
+
save_snapshot(example,result_name)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
# END TESTING SUITE
|
63
|
+
end
|
64
|
+
end
|
metadata
ADDED
@@ -0,0 +1,190 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: sim
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Raybeam
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2014-01-23 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: system-getifaddrs
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ~>
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0.2'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ~>
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0.2'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rspec-rails
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ~>
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '2.0'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ~>
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '2.0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: parallel_tests
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ~>
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0.16'
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ~>
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0.16'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: selenium-webdriver
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ~>
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '2.39'
|
62
|
+
type: :runtime
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ~>
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '2.39'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: poltergeist
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ~>
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '1.5'
|
76
|
+
type: :runtime
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ~>
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '1.5'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: cucumber-rails
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ~>
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '1.4'
|
90
|
+
type: :runtime
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ~>
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '1.4'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: ci_reporter
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - ~>
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '1.9'
|
104
|
+
type: :runtime
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - ~>
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '1.9'
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: capybara
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - ~>
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '2.1'
|
118
|
+
type: :runtime
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - ~>
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: '2.1'
|
125
|
+
- !ruby/object:Gem::Dependency
|
126
|
+
name: database_cleaner
|
127
|
+
requirement: !ruby/object:Gem::Requirement
|
128
|
+
requirements:
|
129
|
+
- - ~>
|
130
|
+
- !ruby/object:Gem::Version
|
131
|
+
version: '1.2'
|
132
|
+
type: :runtime
|
133
|
+
prerelease: false
|
134
|
+
version_requirements: !ruby/object:Gem::Requirement
|
135
|
+
requirements:
|
136
|
+
- - ~>
|
137
|
+
- !ruby/object:Gem::Version
|
138
|
+
version: '1.2'
|
139
|
+
description: Preconfigure rspec and capybara to work with jenkins
|
140
|
+
email: jfu@raybeam.com
|
141
|
+
executables: []
|
142
|
+
extensions: []
|
143
|
+
extra_rdoc_files: []
|
144
|
+
files:
|
145
|
+
- Gemfile
|
146
|
+
- History.md
|
147
|
+
- License.txt
|
148
|
+
- README.md
|
149
|
+
- lib/sim/all_inc.rb
|
150
|
+
- lib/sim/custom_parallel_html_formatter.rb
|
151
|
+
- lib/sim/fail_fast.rb
|
152
|
+
- lib/sim/html_formatter.rb
|
153
|
+
- lib/sim/html_report.rb
|
154
|
+
- lib/sim/local.rb
|
155
|
+
- lib/sim/local_phantomjs.rb
|
156
|
+
- lib/sim/logger_base.rb
|
157
|
+
- lib/sim/parallel_html_formatter.rb
|
158
|
+
- lib/sim/remote.rb
|
159
|
+
- lib/sim/support/capybara_util.rb
|
160
|
+
- lib/sim/support/config.rb
|
161
|
+
- lib/sim/support/cucumber_util.rb
|
162
|
+
- lib/sim/support/database_cleaner.rb
|
163
|
+
- lib/sim/support/rspec_util.rb
|
164
|
+
- lib/sim/support/sim_util.rb
|
165
|
+
- lib/sim/support/web_testing.rb
|
166
|
+
homepage: http://rubygems.org/gems/sim
|
167
|
+
licenses:
|
168
|
+
- MIT
|
169
|
+
metadata: {}
|
170
|
+
post_install_message:
|
171
|
+
rdoc_options: []
|
172
|
+
require_paths:
|
173
|
+
- lib
|
174
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
175
|
+
requirements:
|
176
|
+
- - ! '>='
|
177
|
+
- !ruby/object:Gem::Version
|
178
|
+
version: '0'
|
179
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
180
|
+
requirements:
|
181
|
+
- - ! '>='
|
182
|
+
- !ruby/object:Gem::Version
|
183
|
+
version: '0'
|
184
|
+
requirements: []
|
185
|
+
rubyforge_project:
|
186
|
+
rubygems_version: 2.2.1
|
187
|
+
signing_key:
|
188
|
+
specification_version: 4
|
189
|
+
summary: Integrate capybara with jenkins
|
190
|
+
test_files: []
|