lopata 0.1.25 → 0.1.26
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 +4 -4
- data/lib/lopata/observers/console_output_observer.rb +19 -18
- data/lib/lopata/observers/web_logger.rb +18 -19
- data/lib/lopata/scenario.rb +53 -53
- data/lib/lopata/scenario_builder.rb +7 -3
- data/lib/lopata/step.rb +136 -84
- data/lib/lopata/version.rb +1 -1
- metadata +3 -4
- data/lib/lopata/observers/group_tree.rb +0 -64
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: c48d8c35ec3fbda8e6e707ec75a4d48c98a7e0733a4156869e932a00cadb6a10
|
|
4
|
+
data.tar.gz: 70ef965bafbf052815cd06f9807f1ac209dd06668e7fe17dabee4684e7066885
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 9547b0ce6a37588e0fac9a3f0c899502e755e17caf753eac1bdcaba8dbf2119b2d5ddcda3897b8450cecc03b9796a1b2234bd3f09ebe4e442501cc7f79f62410
|
|
7
|
+
data.tar.gz: f1c6e073a0dce8cfdd22182214fddb5ff88acef2771df288bf8109333533506a941db6e9d3111553e7ea5dea2dba05b21d096924dc424dee6dfea1f5d7cd147d
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
require_relative 'backtrace_formatter'
|
|
2
|
-
require_relative 'group_tree'
|
|
3
2
|
require 'forwardable'
|
|
4
3
|
|
|
5
4
|
module Lopata
|
|
@@ -34,25 +33,27 @@ module Lopata
|
|
|
34
33
|
statuses[scenario.status] ||= 0
|
|
35
34
|
statuses[scenario.status] += 1
|
|
36
35
|
|
|
37
|
-
if scenario.failed?
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
36
|
+
log_steps(scenario.steps) if scenario.failed?
|
|
37
|
+
|
|
38
|
+
flush
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
# @private
|
|
42
|
+
def log_steps(steps)
|
|
43
|
+
steps.each do |step|
|
|
44
|
+
next unless step.loggable?
|
|
45
|
+
if step.group?
|
|
46
|
+
status = step.status
|
|
47
|
+
if %i{ passed skipped ignored }.include?(status)
|
|
48
|
+
puts colored(" #{status_marker(step.status)} #{step.title}", status)
|
|
49
|
+
else
|
|
50
|
+
log_steps(step.steps)
|
|
51
51
|
end
|
|
52
|
+
else
|
|
53
|
+
puts colored(" #{status_marker(step.status)} #{step.title}", step.status)
|
|
54
|
+
puts indent(4, backtrace_formatter.error_message(step.exception, include_backtrace: true)) if step.failed?
|
|
52
55
|
end
|
|
53
56
|
end
|
|
54
|
-
|
|
55
|
-
flush
|
|
56
57
|
end
|
|
57
58
|
|
|
58
59
|
private
|
|
@@ -61,7 +62,7 @@ module Lopata
|
|
|
61
62
|
case status
|
|
62
63
|
when :failed then red(text)
|
|
63
64
|
when :passed then green(text)
|
|
64
|
-
when :skipped then cyan(text)
|
|
65
|
+
when :skipped, :ignored then cyan(text)
|
|
65
66
|
when :pending then yellow(text)
|
|
66
67
|
else text
|
|
67
68
|
end
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
require 'httparty'
|
|
2
2
|
require 'json'
|
|
3
3
|
require_relative 'backtrace_formatter'
|
|
4
|
-
require_relative 'group_tree'
|
|
5
4
|
|
|
6
5
|
module Lopata
|
|
7
6
|
module Observers
|
|
@@ -49,24 +48,7 @@ module Lopata
|
|
|
49
48
|
|
|
50
49
|
def add_attempt(scenario, finished)
|
|
51
50
|
status = scenario.failed? ? Lopata::FAILED : Lopata::PASSED
|
|
52
|
-
steps =
|
|
53
|
-
GroupTree.steps_hierarhy(scenario.steps).walk_through do |step|
|
|
54
|
-
if step.is_a?(Lopata::StepExecution)
|
|
55
|
-
next unless step.loggable?
|
|
56
|
-
steps << step_hash(step)
|
|
57
|
-
else # GroupTree
|
|
58
|
-
|
|
59
|
-
group = step
|
|
60
|
-
if %i{ passed skipped }.include?(group.status)
|
|
61
|
-
steps << group_hash(group)
|
|
62
|
-
false
|
|
63
|
-
else
|
|
64
|
-
true
|
|
65
|
-
end
|
|
66
|
-
end
|
|
67
|
-
end
|
|
68
|
-
|
|
69
|
-
steps = scenario.steps.select(&:loggable?).map { |s| step_hash(s) }
|
|
51
|
+
steps = build_hashes(scenario.steps)
|
|
70
52
|
request = { status: status, steps: steps, launch: { id: @launch_id, finished: finished } }
|
|
71
53
|
test = test_id(scenario)
|
|
72
54
|
post("/tests/#{test}/attempts.json", body: request)
|
|
@@ -76,6 +58,23 @@ module Lopata
|
|
|
76
58
|
puts e.backtrace
|
|
77
59
|
end
|
|
78
60
|
|
|
61
|
+
def build_hashes(steps)
|
|
62
|
+
hashes = []
|
|
63
|
+
steps.each do |step|
|
|
64
|
+
next unless step.loggable?
|
|
65
|
+
if step.group?
|
|
66
|
+
if %i{ passed skipped ignored }.include?(step.status)
|
|
67
|
+
hashes << group_hash(step)
|
|
68
|
+
else
|
|
69
|
+
hashes += build_hashes(step.steps)
|
|
70
|
+
end
|
|
71
|
+
else
|
|
72
|
+
hashes << step_hash(step)
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
hashes
|
|
76
|
+
end
|
|
77
|
+
|
|
79
78
|
def step_hash(step)
|
|
80
79
|
hash = { status: step.status, title: step.title }
|
|
81
80
|
if step.failed?
|
data/lib/lopata/scenario.rb
CHANGED
|
@@ -45,8 +45,9 @@ class Lopata::Scenario
|
|
|
45
45
|
|
|
46
46
|
# @private
|
|
47
47
|
def method_missing(method, *args, &block)
|
|
48
|
-
|
|
49
|
-
|
|
48
|
+
|
|
49
|
+
if (let_method = execution.find_let_method(method))
|
|
50
|
+
let_method.call_in_scenario(self, *args)
|
|
50
51
|
elsif metadata.keys.include?(method)
|
|
51
52
|
metadata[method]
|
|
52
53
|
else
|
|
@@ -56,21 +57,18 @@ class Lopata::Scenario
|
|
|
56
57
|
|
|
57
58
|
# @private
|
|
58
59
|
def respond_to_missing?(method, *)
|
|
59
|
-
execution.
|
|
60
|
+
execution.find_let_method(method) or metadata.keys.include?(method) or super
|
|
60
61
|
end
|
|
61
62
|
|
|
62
63
|
# @private
|
|
63
64
|
# Scenario execution and live-cycle information
|
|
64
65
|
class Execution
|
|
65
|
-
attr_reader :scenario, :
|
|
66
|
-
|
|
67
|
-
def initialize(title,
|
|
68
|
-
@title = [title, options_title].compact.reject(&:empty?).join(' ')
|
|
69
|
-
@metadata = metadata
|
|
70
|
-
@let_methods = {}
|
|
71
|
-
@status = :not_runned
|
|
72
|
-
@steps = []
|
|
66
|
+
attr_reader :scenario, :current_step, :top
|
|
67
|
+
|
|
68
|
+
def initialize(title, metadata = {})
|
|
73
69
|
@scenario = Lopata::Scenario.new(self)
|
|
70
|
+
@top = Lopata::GroupExecution.new(Lopata::TopStep.new(title, metadata: metadata), nil, steps: [])
|
|
71
|
+
@current_step = @top
|
|
74
72
|
end
|
|
75
73
|
|
|
76
74
|
# Provide a human-readable representation of this class
|
|
@@ -79,32 +77,42 @@ class Lopata::Scenario
|
|
|
79
77
|
end
|
|
80
78
|
alias to_s inspect
|
|
81
79
|
|
|
80
|
+
def steps
|
|
81
|
+
top.steps
|
|
82
|
+
end
|
|
83
|
+
|
|
82
84
|
def run
|
|
83
|
-
@status = :running
|
|
84
|
-
sort_steps
|
|
85
85
|
world.notify_observers(:scenario_started, self)
|
|
86
|
-
|
|
87
|
-
@status = steps.any?(&:failed?) ? :failed : :passed
|
|
86
|
+
run_step(top)
|
|
88
87
|
world.notify_observers(:scenario_finished, self)
|
|
89
88
|
cleanup
|
|
90
89
|
end
|
|
91
90
|
|
|
92
91
|
def run_step(step)
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
if
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
92
|
+
@current_step = step
|
|
93
|
+
return :skipped if step.skipped?
|
|
94
|
+
return :ignored if step.ignored?
|
|
95
|
+
if step.condition&.dynamic && !step.condition.match_dynamic?(scenario)
|
|
96
|
+
step.ignored!
|
|
97
|
+
return :ignored
|
|
98
|
+
end
|
|
99
|
+
if step.group?
|
|
100
|
+
skip_rest = false
|
|
101
|
+
step.steps.each do
|
|
102
|
+
if _1.teardown?
|
|
103
|
+
run_step(_1)
|
|
104
|
+
elsif skip_rest
|
|
105
|
+
_1.skip!
|
|
106
|
+
else
|
|
107
|
+
run_step(_1)
|
|
108
|
+
skip_rest = true if _1.failed? && _1.skip_rest_on_failure?
|
|
109
|
+
end
|
|
102
110
|
end
|
|
111
|
+
step.status!
|
|
112
|
+
else
|
|
113
|
+
step.run(scenario)
|
|
114
|
+
step.status
|
|
103
115
|
end
|
|
104
|
-
@current_step = step
|
|
105
|
-
step.run(scenario)
|
|
106
|
-
skip_rest if step.failed? && step.skip_rest_on_failure?
|
|
107
|
-
@current_step = nil
|
|
108
116
|
end
|
|
109
117
|
|
|
110
118
|
def world
|
|
@@ -115,55 +123,47 @@ class Lopata::Scenario
|
|
|
115
123
|
status == :failed
|
|
116
124
|
end
|
|
117
125
|
|
|
118
|
-
def
|
|
119
|
-
|
|
126
|
+
def metadata
|
|
127
|
+
current_step.metadata
|
|
120
128
|
end
|
|
121
129
|
|
|
122
|
-
def
|
|
123
|
-
|
|
130
|
+
def let_methods
|
|
131
|
+
current_step.let_methods
|
|
124
132
|
end
|
|
125
133
|
|
|
126
|
-
def
|
|
127
|
-
|
|
134
|
+
def find_let_method(name)
|
|
135
|
+
current_step.find_let_method(name)
|
|
128
136
|
end
|
|
129
137
|
|
|
130
|
-
def
|
|
131
|
-
|
|
132
|
-
@metadata.merge(current_step.metadata)
|
|
133
|
-
else
|
|
134
|
-
@metadata
|
|
135
|
-
end
|
|
138
|
+
def title
|
|
139
|
+
top.title
|
|
136
140
|
end
|
|
137
141
|
|
|
138
|
-
def
|
|
139
|
-
|
|
140
|
-
@let_methods.merge(current_step.let_methods)
|
|
141
|
-
else
|
|
142
|
-
@let_methods
|
|
143
|
-
end
|
|
142
|
+
def status
|
|
143
|
+
top.status
|
|
144
144
|
end
|
|
145
145
|
|
|
146
146
|
def let_base
|
|
147
|
-
if current_step
|
|
148
|
-
current_step
|
|
147
|
+
if current_step.group?
|
|
148
|
+
current_step
|
|
149
149
|
else
|
|
150
|
-
|
|
150
|
+
current_step.parent
|
|
151
151
|
end
|
|
152
152
|
end
|
|
153
153
|
|
|
154
154
|
def let(method_name, &block)
|
|
155
|
-
let_base
|
|
155
|
+
let_base.add_let_method(method_name, LetMethod.new(&block))
|
|
156
156
|
end
|
|
157
157
|
|
|
158
158
|
def let!(method_name, &block)
|
|
159
|
-
let_base
|
|
159
|
+
let_base.add_let_method(method_name, LetBangMethod.new(&block))
|
|
160
160
|
end
|
|
161
161
|
|
|
162
162
|
def cleanup
|
|
163
163
|
@title = nil
|
|
164
|
-
@metadata = nil
|
|
165
|
-
@steps = nil
|
|
166
164
|
@scenario = nil
|
|
165
|
+
@top = nil
|
|
166
|
+
@current_step = nil
|
|
167
167
|
end
|
|
168
168
|
end
|
|
169
169
|
|
|
@@ -38,16 +38,20 @@ class Lopata::ScenarioBuilder
|
|
|
38
38
|
filters = Lopata.configuration.filters
|
|
39
39
|
option_combinations.each do |option_set|
|
|
40
40
|
metadata = common_metadata.merge(option_set.metadata)
|
|
41
|
-
|
|
42
|
-
|
|
41
|
+
scenario_title = [title, option_set.title].compact.reject(&:empty?).join(' ')
|
|
42
|
+
scenario = Lopata::Scenario::Execution.new(scenario_title, metadata)
|
|
43
|
+
|
|
43
44
|
unless filters.empty?
|
|
44
45
|
next unless filters.all? { |f| f[scenario] }
|
|
45
46
|
end
|
|
46
47
|
|
|
48
|
+
exec_steps = []
|
|
47
49
|
steps_with_hooks.each do |step|
|
|
48
50
|
next if step.condition && !step.condition.match?(scenario)
|
|
49
|
-
step.execution_steps(scenario).each { |s|
|
|
51
|
+
step.execution_steps(scenario, parent: scenario.top).each { |s| exec_steps << s }
|
|
50
52
|
end
|
|
53
|
+
scenario.steps.push(*exec_steps.reject(&:teardown?))
|
|
54
|
+
scenario.steps.push(*exec_steps.select(&:teardown?))
|
|
51
55
|
|
|
52
56
|
world.scenarios << scenario
|
|
53
57
|
end
|
data/lib/lopata/step.rb
CHANGED
|
@@ -7,12 +7,13 @@ module Lopata
|
|
|
7
7
|
# metadata overrien by the step.
|
|
8
8
|
attr_accessor :metadata
|
|
9
9
|
|
|
10
|
-
def initialize(method_name, *args, condition: nil, shared_step: nil, &block)
|
|
10
|
+
def initialize(method_name, *args, condition: nil, shared_step: nil, metadata: {}, &block)
|
|
11
11
|
@method_name = method_name
|
|
12
12
|
@args = args
|
|
13
13
|
@block = block
|
|
14
14
|
@shared_step = shared_step
|
|
15
15
|
@condition = condition
|
|
16
|
+
@metadata = metadata
|
|
16
17
|
initialized! if defined? initialized!
|
|
17
18
|
end
|
|
18
19
|
|
|
@@ -22,31 +23,31 @@ module Lopata
|
|
|
22
23
|
base_title
|
|
23
24
|
end
|
|
24
25
|
|
|
25
|
-
def execution_steps(scenario,
|
|
26
|
+
def execution_steps(scenario, parent:)
|
|
26
27
|
return [] if condition && !condition.match?(scenario)
|
|
27
28
|
return [] unless block
|
|
28
|
-
[StepExecution.new(self,
|
|
29
|
+
[StepExecution.new(self, parent, condition: condition, &block)]
|
|
29
30
|
end
|
|
30
31
|
end
|
|
31
32
|
|
|
32
33
|
# @private
|
|
33
34
|
# Used for action, setup, teardown, verify
|
|
34
35
|
class ActionStep < Step
|
|
35
|
-
def execution_steps(scenario,
|
|
36
|
+
def execution_steps(scenario, parent:)
|
|
36
37
|
steps = []
|
|
37
38
|
return steps if condition && !condition.match?(scenario)
|
|
38
39
|
convert_args(scenario).each do |step|
|
|
39
40
|
if step.is_a?(String)
|
|
40
41
|
Lopata::SharedStep.find(step).steps.each do |shared_step|
|
|
41
42
|
next if shared_step.condition && !shared_step.condition.match?(scenario)
|
|
42
|
-
steps += shared_step.execution_steps(scenario,
|
|
43
|
+
steps += shared_step.execution_steps(scenario, parent: parent)
|
|
43
44
|
end
|
|
44
45
|
elsif step.is_a?(Proc)
|
|
45
|
-
steps << StepExecution.new(self,
|
|
46
|
+
steps << StepExecution.new(self, parent, condition: condition, &step)
|
|
46
47
|
end
|
|
47
48
|
end
|
|
48
|
-
steps << StepExecution.new(self,
|
|
49
|
-
steps
|
|
49
|
+
steps << StepExecution.new(self, parent, condition: condition, &block) if block
|
|
50
|
+
steps
|
|
50
51
|
end
|
|
51
52
|
|
|
52
53
|
def separate_args(args)
|
|
@@ -74,22 +75,18 @@ module Lopata
|
|
|
74
75
|
# Used for context
|
|
75
76
|
class GroupStep < Step
|
|
76
77
|
|
|
77
|
-
def execution_steps(scenario,
|
|
78
|
+
def execution_steps(scenario, parent: nil)
|
|
78
79
|
steps = []
|
|
79
80
|
return steps if condition && !condition.match?(scenario)
|
|
81
|
+
group = GroupExecution.new(self, parent, steps: steps, condition: condition)
|
|
80
82
|
@steps.each do |step|
|
|
81
|
-
steps += step.execution_steps(scenario,
|
|
83
|
+
steps += step.execution_steps(scenario, parent: group)
|
|
82
84
|
end
|
|
83
|
-
steps.reject
|
|
84
|
-
steps.
|
|
85
|
+
group.steps.push(*steps.reject(&:teardown?))
|
|
86
|
+
group.steps.push(*steps.select(&:teardown?))
|
|
87
|
+
[group]
|
|
85
88
|
end
|
|
86
89
|
|
|
87
|
-
def let_methods
|
|
88
|
-
@let_methods ||= {}
|
|
89
|
-
end
|
|
90
|
-
|
|
91
|
-
private
|
|
92
|
-
|
|
93
90
|
# Group step's block is a block in context of builder, not scenario. So hide the @block to not be used in scenario.
|
|
94
91
|
def initialized!
|
|
95
92
|
builder = Lopata::ScenarioBuilder.new(title)
|
|
@@ -99,70 +96,60 @@ module Lopata
|
|
|
99
96
|
end
|
|
100
97
|
end
|
|
101
98
|
|
|
102
|
-
|
|
103
|
-
class
|
|
104
|
-
|
|
99
|
+
# @private
|
|
100
|
+
class TopStep < Step
|
|
101
|
+
def initialize(title, metadata: {})
|
|
102
|
+
super(:top, title, metadata: metadata)
|
|
103
|
+
end
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
# @private
|
|
107
|
+
# Abstract execution step. Composition, may be group or step.
|
|
108
|
+
class BaseExecution
|
|
109
|
+
attr_reader :step, :status, :parent, :condition
|
|
105
110
|
extend Forwardable
|
|
106
111
|
def_delegators :step, :method_name
|
|
107
112
|
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
def initialize(step, groups, condition: nil, &block)
|
|
113
|
+
def initialize(step, parent, condition: nil)
|
|
111
114
|
@step = step
|
|
115
|
+
@parent = parent
|
|
112
116
|
@status = :not_runned
|
|
113
|
-
@exception = nil
|
|
114
|
-
@block = block
|
|
115
|
-
@groups = groups
|
|
116
117
|
@condition = condition
|
|
117
118
|
end
|
|
118
119
|
|
|
119
|
-
def
|
|
120
|
-
|
|
120
|
+
def group?
|
|
121
|
+
false
|
|
121
122
|
end
|
|
122
123
|
|
|
123
|
-
def
|
|
124
|
-
|
|
124
|
+
def top?
|
|
125
|
+
!parent
|
|
125
126
|
end
|
|
126
127
|
|
|
127
|
-
def
|
|
128
|
-
|
|
129
|
-
begin
|
|
130
|
-
unless check_dynamic_condition?(scenario)
|
|
131
|
-
@status = :ignored
|
|
132
|
-
return
|
|
133
|
-
end
|
|
134
|
-
run_step(scenario)
|
|
135
|
-
if pending?
|
|
136
|
-
@status = :failed
|
|
137
|
-
raise PendingStepFixedError, 'Expected step to fail since it is pending, but it passed.'
|
|
138
|
-
else
|
|
139
|
-
@status = :passed
|
|
140
|
-
end
|
|
141
|
-
rescue Exception => e
|
|
142
|
-
@status = :failed unless pending?
|
|
143
|
-
@exception = e
|
|
144
|
-
end
|
|
128
|
+
def teardown?
|
|
129
|
+
%i{ teardown cleanup }.include?(method_name)
|
|
145
130
|
end
|
|
146
131
|
|
|
147
|
-
def
|
|
148
|
-
|
|
149
|
-
|
|
132
|
+
def parents
|
|
133
|
+
result = []
|
|
134
|
+
prnt = parent
|
|
135
|
+
while prnt
|
|
136
|
+
result << prnt
|
|
137
|
+
prnt = prnt.parent
|
|
138
|
+
end
|
|
139
|
+
result
|
|
150
140
|
end
|
|
151
141
|
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
142
|
+
# Step metadata is a combination of metadata given for step and all contexts (groups) the step included
|
|
143
|
+
def metadata
|
|
144
|
+
result = step.metadata || {}
|
|
145
|
+
if parent
|
|
146
|
+
result = parent.metadata.merge(result)
|
|
155
147
|
end
|
|
156
|
-
|
|
148
|
+
result
|
|
157
149
|
end
|
|
158
150
|
|
|
159
|
-
def
|
|
160
|
-
|
|
161
|
-
conds << condition if condition&.dynamic?
|
|
162
|
-
groups.each do
|
|
163
|
-
conds << _1.condition if _1.condition&.dynamic?
|
|
164
|
-
end
|
|
165
|
-
conds
|
|
151
|
+
def find_let_method(name)
|
|
152
|
+
parent&.find_let_method(name)
|
|
166
153
|
end
|
|
167
154
|
|
|
168
155
|
def failed?
|
|
@@ -189,13 +176,12 @@ module Lopata
|
|
|
189
176
|
@status = :skipped
|
|
190
177
|
end
|
|
191
178
|
|
|
192
|
-
def
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
@pending_message = message
|
|
179
|
+
def title
|
|
180
|
+
if parent && !parent.top?
|
|
181
|
+
"#{parent.title}: #{step.title}"
|
|
182
|
+
else
|
|
183
|
+
step.title
|
|
184
|
+
end
|
|
199
185
|
end
|
|
200
186
|
|
|
201
187
|
# Need log this step.
|
|
@@ -204,30 +190,96 @@ module Lopata
|
|
|
204
190
|
not %i{ let let! }.include?(method_name)
|
|
205
191
|
end
|
|
206
192
|
|
|
207
|
-
def
|
|
208
|
-
%i{
|
|
193
|
+
def skip_rest_on_failure?
|
|
194
|
+
%i{ setup action }.include?(method_name)
|
|
209
195
|
end
|
|
196
|
+
end
|
|
210
197
|
|
|
211
|
-
|
|
212
|
-
|
|
198
|
+
# @private
|
|
199
|
+
class GroupExecution < BaseExecution
|
|
200
|
+
attr_reader :steps
|
|
201
|
+
|
|
202
|
+
def initialize(step, parent, condition: nil, steps:)
|
|
203
|
+
super(step, parent, condition: condition)
|
|
204
|
+
@steps = steps
|
|
205
|
+
@let_methods = {}
|
|
213
206
|
end
|
|
214
207
|
|
|
215
|
-
def
|
|
216
|
-
|
|
208
|
+
def group?
|
|
209
|
+
true
|
|
217
210
|
end
|
|
218
211
|
|
|
219
|
-
def
|
|
220
|
-
|
|
212
|
+
def status!
|
|
213
|
+
# return @status if @status
|
|
214
|
+
statuses = steps.map(&:status!).uniq
|
|
215
|
+
@status =
|
|
216
|
+
if statuses.length == 1
|
|
217
|
+
statuses.first
|
|
218
|
+
elsif statuses.include?(:failed)
|
|
219
|
+
:failed
|
|
220
|
+
else
|
|
221
|
+
statuses.first || :skipped
|
|
222
|
+
end
|
|
223
|
+
@status = :passed if @status == :pending
|
|
224
|
+
@status
|
|
221
225
|
end
|
|
222
226
|
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
227
|
+
def find_let_method(name)
|
|
228
|
+
@let_methods[name] || parent&.find_let_method(name)
|
|
229
|
+
end
|
|
230
|
+
|
|
231
|
+
def add_let_method(name, method)
|
|
232
|
+
@let_methods[name] = method
|
|
233
|
+
end
|
|
234
|
+
|
|
235
|
+
def ignored!
|
|
236
|
+
@status = :ignored
|
|
237
|
+
steps.each(&:ignored!)
|
|
238
|
+
end
|
|
239
|
+
end
|
|
240
|
+
|
|
241
|
+
# @private
|
|
242
|
+
class StepExecution < BaseExecution
|
|
243
|
+
attr_reader :exception, :block, :pending_message
|
|
244
|
+
|
|
245
|
+
class PendingStepFixedError < StandardError; end
|
|
246
|
+
|
|
247
|
+
def initialize(step, parent, condition: nil, &block)
|
|
248
|
+
super(step, parent, condition: condition)
|
|
249
|
+
@exception = nil
|
|
250
|
+
@block = block
|
|
251
|
+
end
|
|
252
|
+
|
|
253
|
+
alias status! status
|
|
254
|
+
|
|
255
|
+
def run(scenario)
|
|
256
|
+
@status = :running
|
|
257
|
+
begin
|
|
258
|
+
run_step(scenario)
|
|
259
|
+
if pending?
|
|
260
|
+
@status = :failed
|
|
261
|
+
raise PendingStepFixedError, 'Expected step to fail since it is pending, but it passed.'
|
|
262
|
+
else
|
|
263
|
+
@status = :passed
|
|
264
|
+
end
|
|
265
|
+
rescue Exception => e
|
|
266
|
+
@status = :failed unless pending?
|
|
267
|
+
@exception = e
|
|
268
|
+
end
|
|
226
269
|
end
|
|
227
270
|
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
271
|
+
def run_step(scenario)
|
|
272
|
+
return unless block
|
|
273
|
+
scenario.instance_exec(&block)
|
|
274
|
+
end
|
|
275
|
+
|
|
276
|
+
def pending?
|
|
277
|
+
status == :pending
|
|
278
|
+
end
|
|
279
|
+
|
|
280
|
+
def pending!(message = nil)
|
|
281
|
+
@status = :pending
|
|
282
|
+
@pending_message = message
|
|
231
283
|
end
|
|
232
284
|
end
|
|
233
285
|
end
|
data/lib/lopata/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: lopata
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.1.
|
|
4
|
+
version: 0.1.26
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Alexey Volochnev
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2023-09-
|
|
11
|
+
date: 2023-09-06 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: httparty
|
|
@@ -107,7 +107,6 @@ files:
|
|
|
107
107
|
- lib/lopata/observers/backtrace_formatter.rb
|
|
108
108
|
- lib/lopata/observers/base_observer.rb
|
|
109
109
|
- lib/lopata/observers/console_output_observer.rb
|
|
110
|
-
- lib/lopata/observers/group_tree.rb
|
|
111
110
|
- lib/lopata/observers/web_logger.rb
|
|
112
111
|
- lib/lopata/role.rb
|
|
113
112
|
- lib/lopata/runner.rb
|
|
@@ -139,5 +138,5 @@ requirements: []
|
|
|
139
138
|
rubygems_version: 3.2.15
|
|
140
139
|
signing_key:
|
|
141
140
|
specification_version: 4
|
|
142
|
-
summary: lopata-0.1.
|
|
141
|
+
summary: lopata-0.1.26
|
|
143
142
|
test_files: []
|
|
@@ -1,64 +0,0 @@
|
|
|
1
|
-
module Lopata
|
|
2
|
-
GroupTree = Struct.new(:group, :items, :title) do
|
|
3
|
-
def status
|
|
4
|
-
# return @status if @status
|
|
5
|
-
statuses = items.map(&:status).uniq
|
|
6
|
-
@status =
|
|
7
|
-
if statuses.length == 1
|
|
8
|
-
statuses.first
|
|
9
|
-
elsif statuses.include?(:failed)
|
|
10
|
-
:failed
|
|
11
|
-
elsif
|
|
12
|
-
statuses.first
|
|
13
|
-
end
|
|
14
|
-
@status
|
|
15
|
-
end
|
|
16
|
-
|
|
17
|
-
# Returns steps hierarhy: Group with nestet setps or groups
|
|
18
|
-
def self.steps_hierarhy(steps)
|
|
19
|
-
top = GroupTree.new(nil, [], '')
|
|
20
|
-
hierarhy = [top]
|
|
21
|
-
current_groups = []
|
|
22
|
-
steps.each do |step|
|
|
23
|
-
if step.groups == current_groups
|
|
24
|
-
hierarhy.last.items << step
|
|
25
|
-
else
|
|
26
|
-
# ensure hierarhy to is in current step tree - remove from hierary all groups not in new tree.
|
|
27
|
-
while hierarhy.last.group && !step.groups.include?(hierarhy.last.group)
|
|
28
|
-
hierarhy.pop
|
|
29
|
-
end
|
|
30
|
-
if hierarhy.last.group == step.groups.last
|
|
31
|
-
hierarhy.last.items << step
|
|
32
|
-
else
|
|
33
|
-
group_rest = step.groups.dup
|
|
34
|
-
while hierarhy.last.group && group_rest.first != hierarhy.last.group
|
|
35
|
-
group_rest.shift
|
|
36
|
-
end
|
|
37
|
-
group_rest.shift if group_rest.first == hierarhy.last.group
|
|
38
|
-
group_rest.each do
|
|
39
|
-
title = (hierarhy.map(&:group).compact + [_1]).map(&:title).join(': ')
|
|
40
|
-
group = GroupTree.new(_1, [], title)
|
|
41
|
-
hierarhy.last.items << group
|
|
42
|
-
hierarhy << group
|
|
43
|
-
end
|
|
44
|
-
hierarhy.last.items << step
|
|
45
|
-
end
|
|
46
|
-
current_groups = step.groups
|
|
47
|
-
end
|
|
48
|
-
end
|
|
49
|
-
return top
|
|
50
|
-
end
|
|
51
|
-
|
|
52
|
-
def walk_through(&block)
|
|
53
|
-
items.each do |step|
|
|
54
|
-
if step.is_a?(Lopata::StepExecution)
|
|
55
|
-
yield step
|
|
56
|
-
else # GroupTree
|
|
57
|
-
group = step
|
|
58
|
-
go_dipper = yield group
|
|
59
|
-
group.walk_through(&block) if go_dipper
|
|
60
|
-
end
|
|
61
|
-
end
|
|
62
|
-
end
|
|
63
|
-
end
|
|
64
|
-
end
|