arturop-hydra 0.23.4 → 0.24.0
Sign up to get free protection for your applications and to get access to all the features.
- data/Rakefile +5 -5
- data/VERSION +1 -1
- data/lib/hydra/cucumber/partial_html.rb +24 -0
- data/lib/hydra/listener/cucumber.css +279 -0
- data/lib/hydra/listener/cucumber_html_report.rb +148 -0
- data/lib/hydra/listener/jquery-min.js +154 -0
- data/lib/hydra/listener/report_generator.rb +3 -0
- data/lib/hydra/master.rb +8 -2
- data/lib/hydra/proxy_config.rb +27 -0
- data/lib/hydra/runner.rb +42 -36
- data/lib/hydra/sync.rb +1 -1
- data/lib/hydra/tasks.rb +7 -2
- data/lib/hydra/threadsafe_io.rb +18 -0
- data/lib/hydra/trace.rb +5 -0
- data/lib/hydra/worker.rb +15 -7
- data/nulogy-hydra.gemspec +126 -0
- data/test/fixtures/bad_proxy_config.yml +4 -0
- data/test/fixtures/proxy_config.yml +4 -0
- data/test/fixtures/proxy_config_http.yml +4 -0
- data/test/proxy_config_test.rb +31 -0
- metadata +31 -21
data/Rakefile
CHANGED
@@ -7,13 +7,13 @@ begin
|
|
7
7
|
gem.name = "arturop-hydra"
|
8
8
|
gem.summary = %Q{Distributed testing toolkit}
|
9
9
|
gem.description = %Q{Spread your tests over multiple machines to test your code faster.}
|
10
|
-
gem.email = "
|
11
|
-
gem.homepage = "http://github.com/
|
12
|
-
gem.authors = ["Nick Gauthier", "
|
10
|
+
gem.email = "arturotd08@yahoo.ca"
|
11
|
+
gem.homepage = "http://github.com/nulogy/hydra"
|
12
|
+
gem.authors = ["Nick Gauthier", "Justin Fitzsimmons", "Victor Savkin", "Arturo Pie"]
|
13
13
|
gem.add_development_dependency "shoulda", "= 2.10.3"
|
14
14
|
gem.add_development_dependency "rspec", "= 2.0.0.beta.19"
|
15
|
-
gem.add_development_dependency "cucumber", "=
|
16
|
-
gem.add_development_dependency "therubyracer", "= 0.
|
15
|
+
gem.add_development_dependency "cucumber", "= 1.1.4"
|
16
|
+
gem.add_development_dependency "therubyracer", "= 0.9.9"
|
17
17
|
end
|
18
18
|
Jeweler::GemcutterTasks.new
|
19
19
|
rescue LoadError
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.24.0
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require 'cucumber/formatter/html'
|
2
|
+
|
3
|
+
module Hydra
|
4
|
+
module Formatter
|
5
|
+
class PartialHtml < Cucumber::Formatter::Html
|
6
|
+
|
7
|
+
def before_features(features)
|
8
|
+
# we do not want the default implementation as we will write our own header
|
9
|
+
end
|
10
|
+
|
11
|
+
def after_features(features)
|
12
|
+
# we do not want the default implementation as we will write our own footer
|
13
|
+
end
|
14
|
+
|
15
|
+
def after_step(step)
|
16
|
+
# need an alterantive way of incrementing progress/outputing stats
|
17
|
+
end
|
18
|
+
|
19
|
+
def percent_done
|
20
|
+
0
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,279 @@
|
|
1
|
+
/* cucumber.css is generated from cucumber.sass */
|
2
|
+
/* Regenerate with rake sass */
|
3
|
+
body {
|
4
|
+
font-size: 0px;
|
5
|
+
color: white;
|
6
|
+
margin: 0px;
|
7
|
+
padding: 0px;
|
8
|
+
}
|
9
|
+
|
10
|
+
.cucumber, td, th {
|
11
|
+
font: normal 11px "Lucida Grande", Helvetica, sans-serif;
|
12
|
+
background: white;
|
13
|
+
color: black;
|
14
|
+
}
|
15
|
+
.cucumber #cucumber-header, td #cucumber-header, th #cucumber-header {
|
16
|
+
background: #65c400;
|
17
|
+
color: white;
|
18
|
+
height: 6em;
|
19
|
+
}
|
20
|
+
.cucumber #cucumber-header #expand-collapse p, td #cucumber-header #expand-collapse p, th #cucumber-header #expand-collapse p {
|
21
|
+
float: right;
|
22
|
+
margin: 0 0 0 10px;
|
23
|
+
}
|
24
|
+
.cucumber .scenario h3, td .scenario h3, th .scenario h3 {
|
25
|
+
font-size: 11px;
|
26
|
+
padding: 3px;
|
27
|
+
margin: 0;
|
28
|
+
background: #65c400;
|
29
|
+
color: white;
|
30
|
+
font-weight: bold;
|
31
|
+
}
|
32
|
+
.cucumber h1, td h1, th h1 {
|
33
|
+
margin: 0px 10px 0px 10px;
|
34
|
+
padding: 10px;
|
35
|
+
font-family: "Lucida Grande", Helvetica, sans-serif;
|
36
|
+
font-size: 2em;
|
37
|
+
position: absolute;
|
38
|
+
}
|
39
|
+
.cucumber h4, td h4, th h4 {
|
40
|
+
margin-bottom: 2px;
|
41
|
+
}
|
42
|
+
.cucumber div.feature, td div.feature, th div.feature {
|
43
|
+
padding: 2px;
|
44
|
+
margin: 0px 10px 5px 10px;
|
45
|
+
}
|
46
|
+
.cucumber div.examples, td div.examples, th div.examples {
|
47
|
+
padding: 0em 0em 0em 1em;
|
48
|
+
}
|
49
|
+
.cucumber .stats, td .stats, th .stats {
|
50
|
+
margin: 2em;
|
51
|
+
}
|
52
|
+
.cucumber .summary ul.features li, td .summary ul.features li, th .summary ul.features li {
|
53
|
+
display: inline;
|
54
|
+
}
|
55
|
+
.cucumber .step_name, td .step_name, th .step_name {
|
56
|
+
float: left;
|
57
|
+
}
|
58
|
+
.cucumber .step_file, td .step_file, th .step_file {
|
59
|
+
text-align: right;
|
60
|
+
color: #999999;
|
61
|
+
}
|
62
|
+
.cucumber .step_file a, td .step_file a, th .step_file a {
|
63
|
+
color: #999999;
|
64
|
+
}
|
65
|
+
.cucumber .scenario_file, td .scenario_file, th .scenario_file {
|
66
|
+
float: right;
|
67
|
+
color: #999999;
|
68
|
+
}
|
69
|
+
.cucumber .tag, td .tag, th .tag {
|
70
|
+
font-weight: bold;
|
71
|
+
color: #246ac1;
|
72
|
+
}
|
73
|
+
.cucumber .backtrace, td .backtrace, th .backtrace {
|
74
|
+
margin-top: 0;
|
75
|
+
margin-bottom: 0;
|
76
|
+
margin-left: 1em;
|
77
|
+
color: black;
|
78
|
+
}
|
79
|
+
.cucumber a, td a, th a {
|
80
|
+
text-decoration: none;
|
81
|
+
color: #be5c00;
|
82
|
+
}
|
83
|
+
.cucumber a:hover, td a:hover, th a:hover {
|
84
|
+
text-decoration: underline;
|
85
|
+
}
|
86
|
+
.cucumber a:visited, td a:visited, th a:visited {
|
87
|
+
font-weight: normal;
|
88
|
+
}
|
89
|
+
.cucumber a div.examples, td a div.examples, th a div.examples {
|
90
|
+
margin: 5px 0px 5px 15px;
|
91
|
+
color: black;
|
92
|
+
}
|
93
|
+
.cucumber .outline table, td .outline table, th .outline table {
|
94
|
+
margin: 0px 0px 5px 10px;
|
95
|
+
}
|
96
|
+
.cucumber table, td table, th table {
|
97
|
+
border-collapse: collapse;
|
98
|
+
}
|
99
|
+
.cucumber table td, td table td, th table td {
|
100
|
+
padding: 3px 3px 3px 5px;
|
101
|
+
}
|
102
|
+
.cucumber table td.failed, .cucumber table td.passed, .cucumber table td.skipped, .cucumber table td.pending, .cucumber table td.undefined, td table td.failed, td table td.passed, td table td.skipped, td table td.pending, td table td.undefined, th table td.failed, th table td.passed, th table td.skipped, th table td.pending, th table td.undefined {
|
103
|
+
padding-left: 18px;
|
104
|
+
padding-right: 10px;
|
105
|
+
}
|
106
|
+
.cucumber table td.failed, td table td.failed, th table td.failed {
|
107
|
+
border-left: 5px solid #c20000;
|
108
|
+
border-bottom: 1px solid #c20000;
|
109
|
+
background: #fffbd3;
|
110
|
+
color: #c20000;
|
111
|
+
}
|
112
|
+
.cucumber table td.passed, td table td.passed, th table td.passed {
|
113
|
+
border-left: 5px solid #65c400;
|
114
|
+
border-bottom: 1px solid #65c400;
|
115
|
+
background: #dbffb4;
|
116
|
+
color: #3d7700;
|
117
|
+
}
|
118
|
+
.cucumber table td.skipped, td table td.skipped, th table td.skipped {
|
119
|
+
border-left: 5px solid aqua;
|
120
|
+
border-bottom: 1px solid aqua;
|
121
|
+
background: #e0ffff;
|
122
|
+
color: #001111;
|
123
|
+
}
|
124
|
+
.cucumber table td.pending, td table td.pending, th table td.pending {
|
125
|
+
border-left: 5px solid #faf834;
|
126
|
+
border-bottom: 1px solid #faf834;
|
127
|
+
background: #fcfb98;
|
128
|
+
color: #131313;
|
129
|
+
}
|
130
|
+
.cucumber table td.undefined, td table td.undefined, th table td.undefined {
|
131
|
+
border-left: 5px solid #faf834;
|
132
|
+
border-bottom: 1px solid #faf834;
|
133
|
+
background: #fcfb98;
|
134
|
+
color: #131313;
|
135
|
+
}
|
136
|
+
.cucumber table td.message, td table td.message, th table td.message {
|
137
|
+
border-left: 5px solid aqua;
|
138
|
+
border-bottom: 1px solid aqua;
|
139
|
+
background: #e0ffff;
|
140
|
+
color: #001111;
|
141
|
+
}
|
142
|
+
.cucumber ol, td ol, th ol {
|
143
|
+
list-style: none;
|
144
|
+
margin: 0px;
|
145
|
+
padding: 0px;
|
146
|
+
}
|
147
|
+
.cucumber ol li.step, td ol li.step, th ol li.step {
|
148
|
+
padding: 3px 3px 3px 18px;
|
149
|
+
margin: 5px 0px 5px 5px;
|
150
|
+
}
|
151
|
+
.cucumber ol li, td ol li, th ol li {
|
152
|
+
margin: 0em 0em 0em 1em;
|
153
|
+
padding: 0em 0em 0em 0.2em;
|
154
|
+
}
|
155
|
+
.cucumber ol li span.param, td ol li span.param, th ol li span.param {
|
156
|
+
font-weight: bold;
|
157
|
+
}
|
158
|
+
.cucumber ol li.failed, td ol li.failed, th ol li.failed {
|
159
|
+
border-left: 5px solid #c20000;
|
160
|
+
border-bottom: 1px solid #c20000;
|
161
|
+
background: #fffbd3;
|
162
|
+
color: #c20000;
|
163
|
+
}
|
164
|
+
.cucumber ol li.passed, td ol li.passed, th ol li.passed {
|
165
|
+
border-left: 5px solid #65c400;
|
166
|
+
border-bottom: 1px solid #65c400;
|
167
|
+
background: #dbffb4;
|
168
|
+
color: #3d7700;
|
169
|
+
}
|
170
|
+
.cucumber ol li.skipped, td ol li.skipped, th ol li.skipped {
|
171
|
+
border-left: 5px solid aqua;
|
172
|
+
border-bottom: 1px solid aqua;
|
173
|
+
background: #e0ffff;
|
174
|
+
color: #001111;
|
175
|
+
}
|
176
|
+
.cucumber ol li.pending, td ol li.pending, th ol li.pending {
|
177
|
+
border-left: 5px solid #faf834;
|
178
|
+
border-bottom: 1px solid #faf834;
|
179
|
+
background: #fcfb98;
|
180
|
+
color: #131313;
|
181
|
+
}
|
182
|
+
.cucumber ol li.undefined, td ol li.undefined, th ol li.undefined {
|
183
|
+
border-left: 5px solid #faf834;
|
184
|
+
border-bottom: 1px solid #faf834;
|
185
|
+
background: #fcfb98;
|
186
|
+
color: #131313;
|
187
|
+
}
|
188
|
+
.cucumber ol li.message, td ol li.message, th ol li.message {
|
189
|
+
border-left: 5px solid aqua;
|
190
|
+
border-bottom: 1px solid aqua;
|
191
|
+
background: #e0ffff;
|
192
|
+
color: #001111;
|
193
|
+
margin-left: 10px;
|
194
|
+
}
|
195
|
+
.cucumber #summary, td #summary, th #summary {
|
196
|
+
margin: 0px;
|
197
|
+
padding: 5px 10px;
|
198
|
+
text-align: right;
|
199
|
+
top: 0px;
|
200
|
+
right: 0px;
|
201
|
+
float: right;
|
202
|
+
}
|
203
|
+
.cucumber #summary p, td #summary p, th #summary p {
|
204
|
+
margin: 0 0 0 2px;
|
205
|
+
}
|
206
|
+
.cucumber #summary #totals, td #summary #totals, th #summary #totals {
|
207
|
+
font-size: 1.2em;
|
208
|
+
}
|
209
|
+
|
210
|
+
.ruby {
|
211
|
+
font-size: 12px;
|
212
|
+
font-family: monospace;
|
213
|
+
color: white;
|
214
|
+
background: black;
|
215
|
+
padding: 0.1em 0 0.2em 0;
|
216
|
+
}
|
217
|
+
.ruby .keyword {
|
218
|
+
color: #ff6600;
|
219
|
+
}
|
220
|
+
.ruby .constant {
|
221
|
+
color: #339999;
|
222
|
+
}
|
223
|
+
.ruby .attribute {
|
224
|
+
color: white;
|
225
|
+
}
|
226
|
+
.ruby .global {
|
227
|
+
color: white;
|
228
|
+
}
|
229
|
+
.ruby .module {
|
230
|
+
color: white;
|
231
|
+
}
|
232
|
+
.ruby .class {
|
233
|
+
color: white;
|
234
|
+
}
|
235
|
+
.ruby .string {
|
236
|
+
color: #66ff00;
|
237
|
+
}
|
238
|
+
.ruby .ident {
|
239
|
+
color: white;
|
240
|
+
}
|
241
|
+
.ruby .method {
|
242
|
+
color: #ffcc00;
|
243
|
+
}
|
244
|
+
.ruby .number {
|
245
|
+
color: white;
|
246
|
+
}
|
247
|
+
.ruby .char {
|
248
|
+
color: white;
|
249
|
+
}
|
250
|
+
.ruby .comment {
|
251
|
+
color: #9933cc;
|
252
|
+
}
|
253
|
+
.ruby .symbol {
|
254
|
+
color: white;
|
255
|
+
}
|
256
|
+
.ruby .regex {
|
257
|
+
color: #44b4cc;
|
258
|
+
}
|
259
|
+
.ruby .punct {
|
260
|
+
color: white;
|
261
|
+
}
|
262
|
+
.ruby .escape {
|
263
|
+
color: white;
|
264
|
+
}
|
265
|
+
.ruby .interp {
|
266
|
+
color: white;
|
267
|
+
}
|
268
|
+
.ruby .expr {
|
269
|
+
color: white;
|
270
|
+
}
|
271
|
+
.ruby .offending {
|
272
|
+
background: #333333;
|
273
|
+
}
|
274
|
+
.ruby .linenum {
|
275
|
+
width: 75px;
|
276
|
+
padding: 0.1em 1em 0.2em 0;
|
277
|
+
color: black;
|
278
|
+
background: #fffbd3;
|
279
|
+
}
|
@@ -0,0 +1,148 @@
|
|
1
|
+
require 'cucumber/formatter/ordered_xml_markup'
|
2
|
+
module Hydra #:nodoc:
|
3
|
+
module Listener #:nodoc:
|
4
|
+
# Output a textual report at the end of testing
|
5
|
+
class CucumberHtmlReport < Hydra::Listener::Abstract
|
6
|
+
|
7
|
+
def testing_end
|
8
|
+
CombineHtml.new.generate
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
class CombineHtml
|
13
|
+
def initialize(output_file = nil)
|
14
|
+
@results_path = File.join(Dir.pwd, 'results')
|
15
|
+
output_file = File.join(@results_path, 'html/index.html') if output_file.nil?
|
16
|
+
@io = File.open(output_file, "w")
|
17
|
+
@builder = create_builder(@io)
|
18
|
+
end
|
19
|
+
|
20
|
+
def generate
|
21
|
+
before_features
|
22
|
+
combine_features
|
23
|
+
after_features
|
24
|
+
@io.flush
|
25
|
+
@io.close
|
26
|
+
|
27
|
+
|
28
|
+
FileUtils.rm_r File.join(@results_path, 'features')
|
29
|
+
end
|
30
|
+
|
31
|
+
def wait_for_two_seconds_while_files_are_written
|
32
|
+
sleep 2
|
33
|
+
end
|
34
|
+
|
35
|
+
def combine_features
|
36
|
+
wait_for_two_seconds_while_files_are_written
|
37
|
+
Dir.glob(File.join(@results_path, 'features/*.html')).sort.each do |feature|
|
38
|
+
File.open( feature, "rb") do |f|
|
39
|
+
f.each_line do |line|
|
40
|
+
@builder << line
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def before_features
|
47
|
+
# <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
48
|
+
@builder.declare!(
|
49
|
+
:DOCTYPE,
|
50
|
+
:html,
|
51
|
+
:PUBLIC,
|
52
|
+
'-//W3C//DTD XHTML 1.0 Strict//EN',
|
53
|
+
'http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd'
|
54
|
+
)
|
55
|
+
|
56
|
+
@builder << '<html xmlns ="http://www.w3.org/1999/xhtml">'
|
57
|
+
@builder.head do
|
58
|
+
@builder.meta(:content => 'text/html;charset=utf-8')
|
59
|
+
@builder.title 'Cucumber'
|
60
|
+
inline_css
|
61
|
+
inline_js
|
62
|
+
end
|
63
|
+
@builder << '<body>'
|
64
|
+
#@builder << "<!-- Step count #{@step_count}-->"
|
65
|
+
@builder << '<div class="cucumber">'
|
66
|
+
@builder.div(:id => 'cucumber-header') do
|
67
|
+
@builder.div(:id => 'label') do
|
68
|
+
@builder.h1('Cucumber Features')
|
69
|
+
end
|
70
|
+
@builder.div(:id => 'summary') do
|
71
|
+
@builder.p('',:id => 'totals')
|
72
|
+
@builder.p('',:id => 'duration')
|
73
|
+
@builder.div(:id => 'expand-collapse') do
|
74
|
+
@builder.p('Expand All', :id => 'expander')
|
75
|
+
@builder.p('Collapse All', :id => 'collapser')
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
def after_features
|
82
|
+
@builder << '</div>'
|
83
|
+
@builder << '</body>'
|
84
|
+
@builder << '</html>'
|
85
|
+
end
|
86
|
+
|
87
|
+
|
88
|
+
def inline_css
|
89
|
+
@builder.style(:type => 'text/css') do
|
90
|
+
@builder << File.read(File.dirname(__FILE__) + '/cucumber.css')
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
def inline_js
|
95
|
+
@builder.script(:type => 'text/javascript') do
|
96
|
+
@builder << inline_jquery
|
97
|
+
@builder << inline_js_content
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
def inline_jquery
|
102
|
+
File.read(File.dirname(__FILE__) + '/jquery-min.js')
|
103
|
+
end
|
104
|
+
|
105
|
+
def inline_js_content
|
106
|
+
<<-EOF
|
107
|
+
|
108
|
+
SCENARIOS = "h3[id^='scenario_']";
|
109
|
+
|
110
|
+
$(document).ready(function() {
|
111
|
+
$(SCENARIOS).css('cursor', 'pointer');
|
112
|
+
$(SCENARIOS).click(function() {
|
113
|
+
$(this).siblings().toggle(250);
|
114
|
+
});
|
115
|
+
|
116
|
+
$("#collapser").css('cursor', 'pointer');
|
117
|
+
$("#collapser").click(function() {
|
118
|
+
$(SCENARIOS).siblings().hide();
|
119
|
+
});
|
120
|
+
|
121
|
+
$("#expander").css('cursor', 'pointer');
|
122
|
+
$("#expander").click(function() {
|
123
|
+
$(SCENARIOS).siblings().show();
|
124
|
+
});
|
125
|
+
})
|
126
|
+
|
127
|
+
function moveProgressBar(percentDone) {
|
128
|
+
$("cucumber-header").css('width', percentDone +"%");
|
129
|
+
}
|
130
|
+
function makeRed(element_id) {
|
131
|
+
$('#'+element_id).css('background', '#C40D0D');
|
132
|
+
$('#'+element_id).css('color', '#FFFFFF');
|
133
|
+
}
|
134
|
+
function makeYellow(element_id) {
|
135
|
+
$('#'+element_id).css('background', '#FAF834');
|
136
|
+
$('#'+element_id).css('color', '#000000');
|
137
|
+
}
|
138
|
+
|
139
|
+
EOF
|
140
|
+
end
|
141
|
+
|
142
|
+
|
143
|
+
def create_builder(io)
|
144
|
+
Cucumber::Formatter::OrderedXmlMarkup.new(:target => io, :indent => 0)
|
145
|
+
end
|
146
|
+
end
|
147
|
+
end
|
148
|
+
end
|