spinach 0.0.6 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile +1 -0
- data/Readme.md +3 -0
- data/bin/spinach +3 -1
- data/features/steps/error_reporting.rb +4 -8
- data/features/steps/exit_status.rb +0 -1
- data/features/steps/feature_name_guessing.rb +1 -2
- data/features/support/spinach_runner.rb +0 -2
- data/lib/spinach/capybara.rb +8 -8
- data/lib/spinach/cli.rb +30 -18
- data/lib/spinach/config.rb +29 -10
- data/lib/spinach/dsl.rb +45 -21
- data/lib/spinach/exceptions.rb +21 -8
- data/lib/spinach/feature.rb +8 -4
- data/lib/spinach/parser.rb +13 -7
- data/lib/spinach/reporter/stdout.rb +251 -53
- data/lib/spinach/reporter.rb +43 -26
- data/lib/spinach/runner/feature.rb +39 -26
- data/lib/spinach/runner/scenario.rb +43 -28
- data/lib/spinach/runner.rb +40 -20
- data/lib/spinach/support.rb +8 -7
- data/lib/spinach/version.rb +2 -1
- data/lib/spinach.rb +17 -9
- data/spinach.gemspec +2 -1
- data/test/spinach/capybara_test.rb +32 -3
- data/test/spinach/cli_test.rb +32 -11
- data/test/spinach/config_test.rb +9 -6
- data/test/spinach/dsl_test.rb +8 -1
- data/test/spinach/feature_test.rb +14 -11
- data/test/spinach/parser_test.rb +33 -20
- data/test/spinach/reporter/stdout_test.rb +364 -103
- data/test/spinach/reporter_test.rb +145 -20
- data/test/spinach/runner/feature_test.rb +26 -51
- data/test/spinach/runner/scenario_test.rb +64 -35
- data/test/spinach/runner_test.rb +41 -32
- data/test/spinach/support_test.rb +2 -10
- data/test/spinach_test.rb +14 -14
- data/test/test_helper.rb +13 -5
- metadata +36 -28
- data/examples/steps/user_logs_in.rb +0 -23
- data/examples/user_logs_in.feature +0 -6
- data/examples/user_logs_in.rb +0 -23
@@ -6,81 +6,279 @@ module Spinach
|
|
6
6
|
#
|
7
7
|
class Stdout < Reporter
|
8
8
|
|
9
|
+
# The output buffers to store the reports.
|
10
|
+
attr_reader :out, :error
|
11
|
+
|
12
|
+
# The last scenario error
|
13
|
+
attr_accessor :scenario_error
|
14
|
+
|
15
|
+
# Initialitzes the runner
|
16
|
+
#
|
17
|
+
# @param [Hash] options
|
18
|
+
# Sets a custom output buffer by setting options[:output]
|
19
|
+
# Sets a custom error buffer by setting options[:error]
|
20
|
+
#
|
21
|
+
def initialize(*args)
|
22
|
+
super(*args)
|
23
|
+
@out = options[:output] || $stdout
|
24
|
+
@error = options[:error] || $stderr
|
25
|
+
end
|
26
|
+
|
9
27
|
# Prints the feature name to the standard output
|
10
28
|
#
|
11
|
-
|
12
|
-
|
29
|
+
# @param [Hash] data
|
30
|
+
# The feature in a JSON Gherkin format
|
31
|
+
#
|
32
|
+
def before_feature_run(data)
|
33
|
+
name = data['name']
|
34
|
+
out.puts "\n#{'Feature:'.magenta} #{name.light_magenta}"
|
13
35
|
end
|
14
36
|
|
15
37
|
# Prints the scenario name to the standard ouput
|
16
38
|
#
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
when :skip
|
36
|
-
[:cyan, '~']
|
39
|
+
# @param [Hash] data
|
40
|
+
# The feature in a JSON Gherkin format
|
41
|
+
#
|
42
|
+
def before_scenario_run(data)
|
43
|
+
name = data['name']
|
44
|
+
out.puts "\n #{'Scenario:'.green} #{name.light_green}"
|
45
|
+
out.puts
|
46
|
+
end
|
47
|
+
|
48
|
+
# Adds an error report and re
|
49
|
+
#
|
50
|
+
# @param [Hash] data
|
51
|
+
# The feature in a JSON Gherkin format
|
52
|
+
#
|
53
|
+
def after_scenario_run(data)
|
54
|
+
if scenario_error
|
55
|
+
report_error(scenario_error, :full)
|
56
|
+
self.scenario_error = nil
|
37
57
|
end
|
38
|
-
|
58
|
+
end
|
39
59
|
|
60
|
+
# Adds a passed step to the output buffer.
|
61
|
+
#
|
62
|
+
# @param [Hash] step
|
63
|
+
# The step in a JSON Gherkin format
|
64
|
+
#
|
65
|
+
def on_successful_step(step)
|
66
|
+
output_step('✔', step, :green)
|
40
67
|
end
|
41
68
|
|
42
|
-
#
|
69
|
+
# Adds a failing step to the output buffer.
|
70
|
+
#
|
71
|
+
# @param [Hash] step
|
72
|
+
# The step in a JSON Gherkin format
|
73
|
+
#
|
74
|
+
# @param [Exception] failure
|
75
|
+
# The exception that caused the failure
|
43
76
|
#
|
44
|
-
def
|
45
|
-
|
77
|
+
def on_failed_step(step, failure)
|
78
|
+
output_step('✘', step, :red)
|
79
|
+
self.scenario_error = [current_feature, current_scenario, step, failure]
|
80
|
+
failed_steps << scenario_error
|
46
81
|
end
|
47
82
|
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
83
|
+
# Adds a step that has raised an error to the output buffer.
|
84
|
+
#
|
85
|
+
# @param [Hash] step
|
86
|
+
# The step in a JSON Gherkin format
|
87
|
+
#
|
88
|
+
# @param [Exception] failure
|
89
|
+
# The exception that caused the failure
|
90
|
+
#
|
91
|
+
def on_error_step(step, failure)
|
92
|
+
output_step('!', step, :red)
|
93
|
+
self.scenario_error = [current_feature, current_scenario, step, failure]
|
94
|
+
error_steps << scenario_error
|
95
|
+
end
|
96
|
+
|
97
|
+
# Adds an undefined step to the output buffer.
|
98
|
+
#
|
99
|
+
# @param [Hash] step
|
100
|
+
# The step in a JSON Gherkin format
|
101
|
+
#
|
102
|
+
def on_undefined_step(step)
|
103
|
+
output_step('?', step, :yellow)
|
104
|
+
self.scenario_error = [current_feature, current_scenario, step]
|
105
|
+
undefined_steps << scenario_error
|
106
|
+
end
|
107
|
+
|
108
|
+
# Adds a step that has been skipped to the output buffer.
|
109
|
+
#
|
110
|
+
# @param [Hash] step
|
111
|
+
# The step that Gherkin extracts
|
112
|
+
#
|
113
|
+
def on_skipped_step(step)
|
114
|
+
output_step('~', step, :cyan)
|
115
|
+
end
|
116
|
+
|
117
|
+
# Adds to the output buffer a step result
|
118
|
+
#
|
119
|
+
# @param [String] symbol
|
120
|
+
# A symbol to prepend before the step keyword (might be useful to
|
121
|
+
# indicate if everything went ok or not).
|
122
|
+
#
|
123
|
+
# @param [Hash] step
|
124
|
+
# The step in a JSON Gherkin format
|
125
|
+
#
|
126
|
+
# @param [Symbol] color
|
127
|
+
# The color code to use with Colorize to colorize the output.
|
128
|
+
#
|
129
|
+
def output_step(symbol, step, color)
|
130
|
+
out.puts " #{symbol.colorize(:"light_#{color}")} #{step['keyword'].strip.colorize(:"light_#{color}")} #{step['name'].strip.colorize(color)}"
|
131
|
+
end
|
132
|
+
|
133
|
+
# It prints the error summary if the run has failed
|
134
|
+
#
|
135
|
+
# @param [True,False] success
|
136
|
+
# whether the run has succeed or not
|
137
|
+
#
|
138
|
+
def after_run(success)
|
139
|
+
error_summary unless success
|
140
|
+
end
|
141
|
+
|
142
|
+
# Prints the errors for ths run.
|
143
|
+
#
|
144
|
+
def error_summary
|
145
|
+
error.puts "\nError summary:\n"
|
146
|
+
report_error_steps
|
147
|
+
report_failed_steps
|
148
|
+
report_undefined_steps
|
149
|
+
end
|
150
|
+
|
151
|
+
# Prints the steps that raised an error.
|
152
|
+
#
|
153
|
+
def report_error_steps
|
154
|
+
report_errors('Errors', error_steps, :light_red) if error_steps.any?
|
155
|
+
end
|
156
|
+
|
157
|
+
# Prints failing steps.
|
158
|
+
#
|
159
|
+
def report_failed_steps
|
160
|
+
report_errors('Failures', failed_steps, :light_red) if failed_steps.any?
|
161
|
+
end
|
162
|
+
|
163
|
+
# Prints undefined steps.
|
164
|
+
#
|
165
|
+
def report_undefined_steps
|
166
|
+
report_errors('Undefined steps', undefined_steps, :yellow) if undefined_steps.any?
|
167
|
+
end
|
168
|
+
|
169
|
+
# Prints the error for a given set of steps
|
170
|
+
#
|
171
|
+
# @param [String] banner
|
172
|
+
# the text to prepend as the title
|
173
|
+
#
|
174
|
+
# @param [Array] steps
|
175
|
+
# the steps to output
|
176
|
+
#
|
177
|
+
# @param [Symbol] color
|
178
|
+
# The color code to use with Colorize to colorize the output.
|
179
|
+
#
|
180
|
+
def report_errors(banner, steps, color)
|
181
|
+
error.puts "#{banner} (#{steps.length})".colorize(color)
|
182
|
+
steps.each do |error|
|
183
|
+
report_error error
|
184
|
+
end
|
185
|
+
error.puts ""
|
186
|
+
end
|
187
|
+
|
188
|
+
# Prints an error in a nice format
|
189
|
+
#
|
190
|
+
# @param [Array] error
|
191
|
+
# An array containing the feature, scenario, step and exception
|
192
|
+
#
|
193
|
+
# @param [Symbol] format
|
194
|
+
# The format to output the error. Currently supproted formats are
|
195
|
+
# :summarized (default) and :full
|
196
|
+
#
|
197
|
+
# @returns [String]
|
198
|
+
# The error report
|
199
|
+
#
|
200
|
+
def report_error(error, format=:summarized)
|
201
|
+
case format
|
202
|
+
when :summarized
|
203
|
+
self.error.puts summarized_error(error)
|
204
|
+
when :full
|
205
|
+
self.error.puts full_error(error)
|
206
|
+
else
|
207
|
+
raise "Format not defined"
|
208
|
+
end
|
209
|
+
end
|
210
|
+
|
211
|
+
# Returns summarized error report
|
212
|
+
#
|
213
|
+
# @param [Array] error
|
214
|
+
# An array containing the feature, scenario, step and exception
|
215
|
+
#
|
216
|
+
# @returns [String]
|
217
|
+
# The summarized error report
|
218
|
+
#
|
219
|
+
def summarized_error(error)
|
220
|
+
feature, scenario, step, exception = error
|
221
|
+
summary = " #{feature['name']} :: #{scenario['name']} :: #{full_step step}"
|
222
|
+
if exception.kind_of?(Spinach::StepNotDefinedException)
|
223
|
+
summary.yellow
|
224
|
+
else
|
225
|
+
summary.red
|
226
|
+
end
|
227
|
+
end
|
228
|
+
|
229
|
+
# Returns a complete error report
|
230
|
+
#
|
231
|
+
# @param [Array] error
|
232
|
+
# An array containing the feature, scenario, step and exception
|
233
|
+
#
|
234
|
+
# @returns [String]
|
235
|
+
# The coplete error report
|
236
|
+
#
|
237
|
+
def full_error(error)
|
238
|
+
feature, scenario, step, exception = error
|
239
|
+
output = String.new
|
240
|
+
output += report_exception(exception)
|
241
|
+
output +="\n"
|
242
|
+
|
243
|
+
if options[:backtrace]
|
244
|
+
output += "\n"
|
245
|
+
exception.backtrace.map do |line|
|
246
|
+
output << " #{line}\n"
|
71
247
|
end
|
72
|
-
|
248
|
+
else
|
249
|
+
output << " #{exception.backtrace[0]}"
|
73
250
|
end
|
251
|
+
output
|
252
|
+
end
|
253
|
+
|
254
|
+
# Constructs the full step definition
|
255
|
+
#
|
256
|
+
# @param [Hash] step
|
257
|
+
# The step in a JSON Gherkin format
|
258
|
+
#
|
259
|
+
def full_step(step)
|
260
|
+
"#{step['keyword'].strip} #{step['name'].strip}"
|
74
261
|
end
|
75
262
|
|
263
|
+
# Prints a information when an exception is raised.
|
264
|
+
#
|
265
|
+
# @param [Exception] exception
|
266
|
+
# The exception to report
|
267
|
+
#
|
268
|
+
# @returns [String]
|
269
|
+
# The exception report
|
270
|
+
#
|
76
271
|
def report_exception(exception)
|
77
|
-
@errors << exception
|
78
272
|
output = exception.message.split("\n").map{ |line|
|
79
273
|
" #{line}"
|
80
274
|
}.join("\n")
|
81
|
-
puts "#{output}\n\n"
|
82
|
-
end
|
83
275
|
|
276
|
+
if exception.kind_of?(Spinach::StepNotDefinedException)
|
277
|
+
output.yellow
|
278
|
+
else
|
279
|
+
output.red
|
280
|
+
end
|
281
|
+
end
|
84
282
|
end
|
85
283
|
end
|
86
284
|
end
|
data/lib/spinach/reporter.rb
CHANGED
@@ -10,40 +10,57 @@ module Spinach
|
|
10
10
|
def initialize(options = {})
|
11
11
|
@errors = []
|
12
12
|
@options = options
|
13
|
+
@undefined_steps = []
|
14
|
+
@failed_steps = []
|
15
|
+
@error_steps = []
|
13
16
|
end
|
14
17
|
|
15
|
-
|
16
|
-
|
17
|
-
# Receives this hook when a feature is invoked
|
18
|
-
# @param [String] name
|
19
|
-
# the feature name
|
18
|
+
# A Hash with options for the reporter
|
20
19
|
#
|
21
|
-
|
22
|
-
raise "Abstract method!"
|
23
|
-
end
|
20
|
+
attr_reader :options
|
24
21
|
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
def
|
30
|
-
|
22
|
+
attr_accessor :current_feature, :current_scenario
|
23
|
+
|
24
|
+
attr_reader :undefined_steps, :failed_steps, :error_steps
|
25
|
+
|
26
|
+
def bind
|
27
|
+
runner.after_run method(:after_run)
|
28
|
+
feature_runner.before_run method(:before_feature_run)
|
29
|
+
feature_runner.after_run method(:after_feature_run)
|
30
|
+
scenario_runner.before_run method(:before_scenario_run)
|
31
|
+
scenario_runner.after_run method(:after_scenario_run)
|
32
|
+
scenario_runner.on_successful_step method(:on_successful_step)
|
33
|
+
scenario_runner.on_failed_step method(:on_failed_step)
|
34
|
+
scenario_runner.on_error_step method(:on_error_step)
|
35
|
+
scenario_runner.on_skipped_step method(:on_skipped_step)
|
36
|
+
|
37
|
+
feature_runner.before_run method(:current_feature=)
|
38
|
+
feature_runner.after_run method(:clear_current_feature)
|
39
|
+
scenario_runner.before_run method(:current_scenario=)
|
40
|
+
scenario_runner.after_run method(:clear_current_scenario)
|
31
41
|
end
|
32
42
|
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
def
|
40
|
-
|
43
|
+
def feature_runner; Runner::Feature; end
|
44
|
+
def scenario_runner; Runner::Scenario; end
|
45
|
+
def runner; Runner; end
|
46
|
+
|
47
|
+
def after_run(*args); end;
|
48
|
+
def before_feature_run(*args); end
|
49
|
+
def after_feature_run(*args); end
|
50
|
+
def before_scenario_run(*args); end
|
51
|
+
def after_scenario_run(*args); end
|
52
|
+
def on_successful_step(*args); end;
|
53
|
+
def on_failed_step(*args); end;
|
54
|
+
def on_error_step(*args); end;
|
55
|
+
def on_undefined_step(*args); end;
|
56
|
+
def on_skipped_step(*args); end;
|
57
|
+
|
58
|
+
def clear_current_feature(*args)
|
59
|
+
self.current_feature = nil
|
41
60
|
end
|
42
61
|
|
43
|
-
|
44
|
-
|
45
|
-
def end
|
46
|
-
raise "Abstract method!"
|
62
|
+
def clear_current_scenario(*args)
|
63
|
+
self.current_scenario = nil
|
47
64
|
end
|
48
65
|
|
49
66
|
end
|
@@ -1,75 +1,88 @@
|
|
1
|
+
require 'hooks'
|
2
|
+
|
1
3
|
module Spinach
|
2
4
|
class Runner
|
3
|
-
# A feature runner handles a particular
|
5
|
+
# A feature runner handles a particular feature run.
|
4
6
|
#
|
5
7
|
class Feature
|
8
|
+
include Hooks
|
9
|
+
|
10
|
+
# The {Reporter} used in this feature.
|
11
|
+
attr_reader :reporter
|
12
|
+
|
13
|
+
# The file that describes the feature.
|
14
|
+
attr_reader :filename
|
15
|
+
|
16
|
+
define_hook :before_run
|
17
|
+
define_hook :after_run
|
6
18
|
|
7
19
|
# @param [String] filename
|
8
20
|
# path to the feature file. Scenario line could be passed to run just
|
9
21
|
# that scenario.
|
10
22
|
# @example feature/a_cool_feature.feature:12
|
11
23
|
#
|
12
|
-
# @
|
13
|
-
|
14
|
-
#
|
15
|
-
def initialize(filename, reporter)
|
24
|
+
# @api public
|
25
|
+
def initialize(filename)
|
16
26
|
@filename, @scenario_line = filename.split(':')
|
17
|
-
@reporter = reporter
|
18
27
|
end
|
19
28
|
|
20
|
-
|
29
|
+
# The file taht describes the feature.
|
30
|
+
#
|
21
31
|
attr_reader :filename
|
22
32
|
|
23
|
-
# @return [
|
24
|
-
#
|
33
|
+
# @return [Feature]
|
34
|
+
# The feature object used to run this scenario.
|
25
35
|
#
|
36
|
+
# @api public
|
26
37
|
def feature
|
27
38
|
@feature ||= Spinach.find_feature(feature_name).new
|
28
39
|
end
|
29
40
|
|
30
41
|
# @return [Hash]
|
31
|
-
#
|
42
|
+
# The parsed data for this feature.
|
32
43
|
#
|
44
|
+
# @api public
|
33
45
|
def data
|
34
46
|
@data ||= Spinach::Parser.new(filename).parse
|
35
47
|
end
|
36
48
|
|
37
49
|
# @return [String]
|
38
|
-
#
|
50
|
+
# This feature name.
|
39
51
|
#
|
52
|
+
# @api public
|
40
53
|
def feature_name
|
41
54
|
@feature_name ||= data['name']
|
42
55
|
end
|
43
56
|
|
44
57
|
# @return [Hash]
|
45
|
-
#
|
58
|
+
# The parsed scenarios for this runner's feature.
|
46
59
|
#
|
60
|
+
# @api public
|
47
61
|
def scenarios
|
48
62
|
@scenarios ||= (data['elements'] || [])
|
49
63
|
end
|
50
64
|
|
51
|
-
# Runs this feature
|
65
|
+
# Runs this feature.
|
52
66
|
#
|
67
|
+
# @return [true, false]
|
68
|
+
# Whether the run was successful or not.
|
69
|
+
#
|
70
|
+
# @api public
|
53
71
|
def run
|
54
|
-
|
55
|
-
|
72
|
+
run_hook :before_run, data
|
73
|
+
feature.run_hook :before, data
|
74
|
+
|
56
75
|
scenarios.each do |scenario|
|
57
76
|
if !@scenario_line || scenario['line'].to_s == @scenario_line
|
58
|
-
|
59
|
-
failure = Scenario.new(feature_name, feature, scenario, reporter).run
|
60
|
-
failures << failure if failure
|
61
|
-
feature.send(:after)
|
77
|
+
@success = Scenario.new(feature_name, feature, scenario).run
|
62
78
|
end
|
63
79
|
end
|
64
80
|
|
65
|
-
|
66
|
-
|
67
|
-
return false
|
68
|
-
else
|
69
|
-
return true
|
70
|
-
end
|
71
|
-
end
|
81
|
+
feature.run_hook :after, data
|
82
|
+
run_hook :after_run, data
|
72
83
|
|
84
|
+
return !!@success
|
85
|
+
end
|
73
86
|
end
|
74
87
|
end
|
75
88
|
end
|
@@ -1,54 +1,69 @@
|
|
1
|
+
require 'hooks'
|
2
|
+
|
1
3
|
module Spinach
|
2
4
|
class Runner
|
3
5
|
# A Scenario Runner handles a particular scenario run.
|
4
6
|
#
|
5
7
|
class Scenario
|
6
|
-
attr_reader :
|
8
|
+
attr_reader :feature, :feature_name, :data
|
9
|
+
|
10
|
+
include Hooks
|
7
11
|
|
8
|
-
|
9
|
-
|
12
|
+
define_hook :before_run
|
13
|
+
define_hook :on_successful_step
|
14
|
+
define_hook :on_failed_step
|
15
|
+
define_hook :on_error_step
|
16
|
+
define_hook :on_undefined_step
|
17
|
+
define_hook :on_skipped_step
|
18
|
+
define_hook :after_run
|
19
|
+
|
20
|
+
# @param [Feature] feature
|
21
|
+
# The feature that contains the steps.
|
10
22
|
#
|
11
23
|
# @param [Hash] data
|
12
|
-
#
|
13
|
-
#
|
14
|
-
# @param [Spinach::Reporter]
|
15
|
-
# the reporter
|
24
|
+
# The parsed feature data.
|
16
25
|
#
|
17
|
-
|
26
|
+
# @api public
|
27
|
+
def initialize(feature_name, feature, data)
|
18
28
|
@feature_name = feature_name
|
19
|
-
@
|
20
|
-
@steps = data['steps']
|
21
|
-
@reporter = reporter
|
29
|
+
@data = data
|
22
30
|
@feature = feature
|
23
31
|
end
|
24
32
|
|
25
|
-
|
26
|
-
|
33
|
+
def steps
|
34
|
+
@steps ||= data['steps']
|
35
|
+
end
|
36
|
+
|
37
|
+
# Runs this scenario
|
38
|
+
# @return [True, False]
|
39
|
+
# true if this scenario succeeded, false if not
|
27
40
|
def run
|
28
|
-
|
41
|
+
run_hook :before_run, data
|
42
|
+
feature.run_hook :before_scenario, data
|
29
43
|
steps.each do |step|
|
30
|
-
|
31
|
-
|
32
|
-
line = step['line']
|
33
|
-
unless @failure
|
44
|
+
feature.run_hook :before_step, step
|
45
|
+
unless @exception
|
34
46
|
begin
|
35
|
-
feature.execute_step(name)
|
36
|
-
|
47
|
+
feature.execute_step(step['name'])
|
48
|
+
run_hook :on_successful_step, step
|
37
49
|
rescue MiniTest::Assertion => e
|
38
|
-
@
|
39
|
-
|
50
|
+
@exception = e
|
51
|
+
run_hook :on_failed_step, step, @exception
|
40
52
|
rescue Spinach::StepNotDefinedException => e
|
41
|
-
@
|
42
|
-
|
53
|
+
@exception = e
|
54
|
+
run_hook :on_undefined_step, step, @exception
|
43
55
|
rescue StandardError => e
|
44
|
-
@
|
45
|
-
|
56
|
+
@exception = e
|
57
|
+
run_hook :on_error_step, step, @exception
|
46
58
|
end
|
47
59
|
else
|
48
|
-
|
60
|
+
run_hook :on_skipped_step, step
|
49
61
|
end
|
62
|
+
feature.run_hook :after_step, step
|
50
63
|
end
|
51
|
-
|
64
|
+
feature.run_hook :after_scenario, data
|
65
|
+
run_hook :after_run, data
|
66
|
+
!@exception
|
52
67
|
end
|
53
68
|
end
|
54
69
|
end
|