lopata 0.1.13 → 0.1.17

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.
@@ -1,131 +1,131 @@
1
- require 'httparty'
2
- require 'json'
3
- require_relative 'backtrace_formatter'
4
-
5
- module Lopata
6
- module Observers
7
- # @private
8
- class WebLogger < BaseObserver
9
- def started(world)
10
- @client = Lopata::Client.new
11
- @client.start(world.scenarios.count)
12
- @finished = 0
13
- end
14
-
15
- def scenario_finished(scenario)
16
- @finished += 1
17
- @client.add_attempt(scenario, @finished)
18
- end
19
- end
20
- end
21
-
22
- # @private
23
- PASSED = 0
24
- # @private
25
- FAILED = 1
26
- # @private
27
- PENDING = 2
28
- # @private
29
- SKIPPED = 5
30
-
31
- # @private
32
- class Client
33
- include HTTParty
34
-
35
- attr_reader :url, :project_code, :build_number
36
-
37
- def initialize
38
- params = Lopata.configuration.web_logging_params
39
- raise "Web logging is not initailzed" unless params
40
- @url = HTTParty.normalize_base_uri(params[:url])
41
- @project_code = params[:project_code]
42
- @build_number = params[:build_number]
43
- end
44
-
45
- def start(count)
46
- @launch_id = JSON.parse(post("/projects/#{project_code}/builds/#{build_number}/launches.json", body: {total: count}).body)['id']
47
- end
48
-
49
- def add_attempt(scenario, finished)
50
- status = scenario.failed? ? Lopata::FAILED : Lopata::PASSED
51
- steps = scenario.steps.map { |s| step_hash(s) }
52
- request = { status: status, steps: steps, launch: { id: @launch_id, finished: finished } }
53
- test = test_id(scenario)
54
- post("/tests/#{test}/attempts.json", body: request)
55
- end
56
-
57
- def step_hash(step)
58
- hash = { status: step.status, title: step.title }
59
- if step.failed?
60
- hash[:message] = error_message_for(step)
61
- hash[:backtrace] = backtrace_for(step)
62
- end
63
- hash
64
- end
65
-
66
- def test_id(scenario)
67
- request = {
68
- test: {
69
- project_code: project_code,
70
- title: scenario.title,
71
- scenario: scenario.title,
72
- build_number: build_number
73
- }
74
- }
75
- response = post("/tests.json", body: request)
76
- JSON.parse(response.body)["id"]
77
- end
78
-
79
- def to_rerun
80
- get_json("/projects/#{project_code}/builds/#{build_number}/suspects.json")
81
- end
82
-
83
- def to_full_rescan
84
- to_rerun + get_json("/projects/#{project_code}/builds/#{build_number}/failures.json")
85
- end
86
-
87
- private
88
-
89
- def get_json(path)
90
- JSON.parse(self.class.get(path, base_uri: url).body)
91
- end
92
-
93
- def post(*args)
94
- self.class.post(*with_base_uri(args))
95
- end
96
-
97
- def patch(*args)
98
- self.class.patch(*with_base_uri(args))
99
- end
100
-
101
- def with_base_uri(args = [])
102
- if args.last.is_a? Hash
103
- args.last[:base_uri] = url
104
- else
105
- args << { base_uri: url }
106
- end
107
- args
108
- end
109
-
110
- def error_message_for(step)
111
- if step.exception
112
- backtrace_formatter.error_message(step.exception)
113
- else
114
- 'Empty error message'
115
- end
116
- end
117
-
118
- def backtrace_for(step)
119
- msg = ''
120
- if step.exception
121
- msg = backtrace_formatter.format(step.exception.backtrace).join("\n")
122
- msg << "\n"
123
- end
124
- msg
125
- end
126
-
127
- def backtrace_formatter
128
- @backtrace_formatter ||= Lopata::Observers::BacktraceFormatter.new
129
- end
130
- end
1
+ require 'httparty'
2
+ require 'json'
3
+ require_relative 'backtrace_formatter'
4
+
5
+ module Lopata
6
+ module Observers
7
+ # @private
8
+ class WebLogger < BaseObserver
9
+ def started(world)
10
+ @client = Lopata::Client.new
11
+ @client.start(world.scenarios.count)
12
+ @finished = 0
13
+ end
14
+
15
+ def scenario_finished(scenario)
16
+ @finished += 1
17
+ @client.add_attempt(scenario, @finished)
18
+ end
19
+ end
20
+ end
21
+
22
+ # @private
23
+ PASSED = 0
24
+ # @private
25
+ FAILED = 1
26
+ # @private
27
+ PENDING = 2
28
+ # @private
29
+ SKIPPED = 5
30
+
31
+ # @private
32
+ class Client
33
+ include HTTParty
34
+
35
+ attr_reader :url, :project_code, :build_number
36
+
37
+ def initialize
38
+ params = Lopata.configuration.web_logging_params
39
+ raise "Web logging is not initailzed" unless params
40
+ @url = HTTParty.normalize_base_uri(params[:url])
41
+ @project_code = params[:project_code]
42
+ @build_number = params[:build_number]
43
+ end
44
+
45
+ def start(count)
46
+ @launch_id = JSON.parse(post("/projects/#{project_code}/builds/#{build_number}/launches.json", body: {total: count}).body)['id']
47
+ end
48
+
49
+ def add_attempt(scenario, finished)
50
+ status = scenario.failed? ? Lopata::FAILED : Lopata::PASSED
51
+ steps = scenario.steps.map { |s| step_hash(s) }
52
+ request = { status: status, steps: steps, launch: { id: @launch_id, finished: finished } }
53
+ test = test_id(scenario)
54
+ post("/tests/#{test}/attempts.json", body: request)
55
+ end
56
+
57
+ def step_hash(step)
58
+ hash = { status: step.status, title: step.title }
59
+ if step.failed?
60
+ hash[:message] = error_message_for(step)
61
+ hash[:backtrace] = backtrace_for(step)
62
+ end
63
+ hash
64
+ end
65
+
66
+ def test_id(scenario)
67
+ request = {
68
+ test: {
69
+ project_code: project_code,
70
+ title: scenario.title,
71
+ scenario: scenario.title,
72
+ build_number: build_number
73
+ }
74
+ }
75
+ response = post("/tests.json", body: request)
76
+ JSON.parse(response.body)["id"]
77
+ end
78
+
79
+ def to_rerun
80
+ get_json("/projects/#{project_code}/builds/#{build_number}/suspects.json")
81
+ end
82
+
83
+ def to_full_rescan
84
+ to_rerun + get_json("/projects/#{project_code}/builds/#{build_number}/failures.json")
85
+ end
86
+
87
+ private
88
+
89
+ def get_json(path)
90
+ JSON.parse(self.class.get(path, base_uri: url).body)
91
+ end
92
+
93
+ def post(*args)
94
+ self.class.post(*with_base_uri(args))
95
+ end
96
+
97
+ def patch(*args)
98
+ self.class.patch(*with_base_uri(args))
99
+ end
100
+
101
+ def with_base_uri(args = [])
102
+ if args.last.is_a? Hash
103
+ args.last[:base_uri] = url
104
+ else
105
+ args << { base_uri: url }
106
+ end
107
+ args
108
+ end
109
+
110
+ def error_message_for(step)
111
+ if step.exception
112
+ backtrace_formatter.error_message(step.exception)
113
+ else
114
+ 'Empty error message'
115
+ end
116
+ end
117
+
118
+ def backtrace_for(step)
119
+ msg = ''
120
+ if step.exception
121
+ msg = backtrace_formatter.format(step.exception.backtrace).join("\n")
122
+ msg << "\n"
123
+ end
124
+ msg
125
+ end
126
+
127
+ def backtrace_formatter
128
+ @backtrace_formatter ||= Lopata::Observers::BacktraceFormatter.new
129
+ end
130
+ end
131
131
  end
@@ -1,5 +1,5 @@
1
- # @private
2
- module Lopata::Observers
3
- autoload :BaseObserver, 'lopata/observers/base_observer.rb'
4
- autoload :ConsoleOutputObserver, 'lopata/observers/console_output_observer.rb'
1
+ # @private
2
+ module Lopata::Observers
3
+ autoload :BaseObserver, 'lopata/observers/base_observer.rb'
4
+ autoload :ConsoleOutputObserver, 'lopata/observers/console_output_observer.rb'
5
5
  end
data/lib/lopata/role.rb CHANGED
@@ -1,110 +1,110 @@
1
- module Lopata
2
- # Adds ability to run scenarios by given user roles
3
- #
4
- # @example Usage
5
- # require 'lopata/role'
6
- # Lopata.configure do |c|
7
- # c.role_descriptions = {
8
- # user: 'User',
9
- # admin: 'Admin'
10
- # }
11
- # c.default_role = :user
12
- # c.before_scenaro 'setup user'
13
- # end
14
- # Lopata.shared_step 'setup user' do
15
- # setup { @user = User.create(role: current_role) if current_role }
16
- # cleanup :user
17
- # end
18
- # Lopata.define 'login' do
19
- # # will generate 2 scenarios, one for :user and one for :admin
20
- # as :user, :admin
21
- # action 'login'
22
- # # verify the user is logged in
23
- # end
24
- #
25
- # @see Lopata::Configuration#role_descriptions
26
- # @see Lopata::Configuration#default_role
27
- module Role
28
- # To be included in Lopata::Scenario
29
- module Methods
30
- # @return [Symbol, nil] user role for current scenario or nil, if scenario is running without user.
31
- def current_role
32
- metadata[:as]
33
- end
34
- end
35
-
36
- # To be included in Lopata::ScenarioBuilder
37
- module DSL
38
- # Enumerate the roles the scenario to be runned under.
39
- # If not invoked the default role only will be used.
40
- #
41
- # The scenario should be set to use the role via before_scenario step using #current_role param.
42
- #
43
- # @param args [Array<Symbol>] list of roles the scenario to be runned with.
44
- # @param block [Block] the block to calculate role from scenario metadata.
45
- def as(*args, &block)
46
- @roles = args.flatten
47
- @roles << Lopata::ScenarioBuilder::CalculatedValue.new(&block) if block_given?
48
- @use_all_roles = true
49
- @role_options = nil
50
- end
51
-
52
- # Enumerate the roles the scenario can be run.
53
- #
54
- # The scenario should be set to use the role via before_scenario step using #current_role param.
55
- #
56
- # Only first role will be used if scenario has no options or diagonales. Some first roles will be used if
57
- # options or diagonales are declared, in order of appearence.
58
- #
59
- # Use this to describe possible roles, but not needed to run scenario with all of them in order to save time
60
- # of running.
61
- #
62
- # @param args [Array<Symbol>] list of roles the scenario to be runned with.
63
- def as_first(*args, &block)
64
- @roles = args.flatten
65
- @use_all_roles = false
66
- @role_options = nil
67
- end
68
-
69
- # @private
70
- def role_options
71
- @role_options ||= build_role_options
72
- end
73
-
74
- # Marks scenario to be runned without user.
75
- #
76
- # @example
77
- # Lopata.define 'scenario withou user' do
78
- # without_user
79
- # it 'does not define the user' do
80
- # expect(current_role).to be_nil
81
- # end
82
- # end
83
- def without_user
84
- @without_user = true
85
- end
86
-
87
- # @private
88
- def build_role_options
89
- return [] unless roles
90
- role_variants = roles.map { |r| [Lopata.configuration.role_descriptions[r], r] }
91
- [Lopata::ScenarioBuilder::Diagonal.new(:as, role_variants, @use_all_roles)]
92
- end
93
-
94
- # @private
95
- def roles
96
- return false if @without_user
97
- @roles ||= [Lopata.configuration.default_role].compact
98
- end
99
-
100
- # @private
101
- def diagonals
102
- super + role_options
103
- end
104
- end
105
- end
106
- end
107
-
108
- Lopata::Scenario.include Lopata::Role::Methods
109
- # Prepend the module to overload #diagonals method
1
+ module Lopata
2
+ # Adds ability to run scenarios by given user roles
3
+ #
4
+ # @example Usage
5
+ # require 'lopata/role'
6
+ # Lopata.configure do |c|
7
+ # c.role_descriptions = {
8
+ # user: 'User',
9
+ # admin: 'Admin'
10
+ # }
11
+ # c.default_role = :user
12
+ # c.before_scenaro 'setup user'
13
+ # end
14
+ # Lopata.shared_step 'setup user' do
15
+ # setup { @user = User.create(role: current_role) if current_role }
16
+ # cleanup :user
17
+ # end
18
+ # Lopata.define 'login' do
19
+ # # will generate 2 scenarios, one for :user and one for :admin
20
+ # as :user, :admin
21
+ # action 'login'
22
+ # # verify the user is logged in
23
+ # end
24
+ #
25
+ # @see Lopata::Configuration#role_descriptions
26
+ # @see Lopata::Configuration#default_role
27
+ module Role
28
+ # To be included in Lopata::Scenario
29
+ module Methods
30
+ # @return [Symbol, nil] user role for current scenario or nil, if scenario is running without user.
31
+ def current_role
32
+ metadata[:as]
33
+ end
34
+ end
35
+
36
+ # To be included in Lopata::ScenarioBuilder
37
+ module DSL
38
+ # Enumerate the roles the scenario to be runned under.
39
+ # If not invoked the default role only will be used.
40
+ #
41
+ # The scenario should be set to use the role via before_scenario step using #current_role param.
42
+ #
43
+ # @param args [Array<Symbol>] list of roles the scenario to be runned with.
44
+ # @param block [Block] the block to calculate role from scenario metadata.
45
+ def as(*args, &block)
46
+ @roles = args.flatten
47
+ @roles << Lopata::ScenarioBuilder::CalculatedValue.new(&block) if block_given?
48
+ @use_all_roles = true
49
+ @role_options = nil
50
+ end
51
+
52
+ # Enumerate the roles the scenario can be run.
53
+ #
54
+ # The scenario should be set to use the role via before_scenario step using #current_role param.
55
+ #
56
+ # Only first role will be used if scenario has no options or diagonales. Some first roles will be used if
57
+ # options or diagonales are declared, in order of appearence.
58
+ #
59
+ # Use this to describe possible roles, but not needed to run scenario with all of them in order to save time
60
+ # of running.
61
+ #
62
+ # @param args [Array<Symbol>] list of roles the scenario to be runned with.
63
+ def as_first(*args, &block)
64
+ @roles = args.flatten
65
+ @use_all_roles = false
66
+ @role_options = nil
67
+ end
68
+
69
+ # @private
70
+ def role_options
71
+ @role_options ||= build_role_options
72
+ end
73
+
74
+ # Marks scenario to be runned without user.
75
+ #
76
+ # @example
77
+ # Lopata.define 'scenario withou user' do
78
+ # without_user
79
+ # it 'does not define the user' do
80
+ # expect(current_role).to be_nil
81
+ # end
82
+ # end
83
+ def without_user
84
+ @without_user = true
85
+ end
86
+
87
+ # @private
88
+ def build_role_options
89
+ return [] unless roles
90
+ role_variants = roles.map { |r| [Lopata.configuration.role_descriptions[r], r] }
91
+ [Lopata::ScenarioBuilder::Diagonal.new(:as, role_variants, @use_all_roles)]
92
+ end
93
+
94
+ # @private
95
+ def roles
96
+ return false if @without_user
97
+ @roles ||= [Lopata.configuration.default_role].compact
98
+ end
99
+
100
+ # @private
101
+ def diagonals
102
+ super + role_options
103
+ end
104
+ end
105
+ end
106
+ end
107
+
108
+ Lopata::Scenario.include Lopata::Role::Methods
109
+ # Prepend the module to overload #diagonals method
110
110
  Lopata::ScenarioBuilder.prepend Lopata::Role::DSL
data/lib/lopata/runner.rb CHANGED
@@ -1,67 +1,80 @@
1
- require 'thor'
2
- require_relative 'generators/app'
3
- require_relative 'world'
4
- require_relative 'loader'
5
- require_relative '../lopata'
6
- require_relative 'observers'
7
- require_relative 'condition'
8
-
9
- module Lopata
10
- # @private
11
- class Runner < Thor
12
- desc 'test', 'Run tests'
13
- option :env, default: :qa, aliases: 'e'
14
- option :rerun, type: :boolean, aliases: 'r'
15
- option :keep, type: :boolean, aliases: 'k'
16
- option :text, aliases: 't'
17
- def test(*args)
18
- trap_interrupt
19
- configure_from_options
20
- Lopata::Loader.load_shared_steps
21
- Lopata::Loader.load_scenarios(*args)
22
- world = Lopata.world
23
- world.notify_observers(:started, world)
24
- world.scenarios.each { |s| s.run }
25
- world.notify_observers(:finished, world)
26
- end
27
-
28
- default_task :test
29
-
30
- register Generators::App, :new, 'lopata new project-name', 'Init new lopata projects'
31
-
32
- def self.exit_on_failure?
33
- true
34
- end
35
-
36
- no_commands do
37
- def configure_from_options
38
- Lopata.configure do |c|
39
- c.env = options[:env].to_sym
40
- c.keep = options[:keep]
41
- c.load_environment
42
- c.run_before_start_hooks
43
- end
44
- add_text_filter(options[:text]) if options[:text]
45
- add_rerun_filter if options[:rerun]
46
- end
47
-
48
- def add_text_filter(text)
49
- Lopata.configuration.filters << -> (scenario) { scenario.title.include?(text) }
50
- end
51
-
52
- def add_rerun_filter
53
- to_rerun = Lopata::Client.new.to_rerun
54
- Lopata.configuration.filters << -> (scenario) { to_rerun.include?(scenario.title) }
55
- end
56
-
57
- def trap_interrupt
58
- trap('INT') { exit!(1) }
59
- end
60
- end
61
- end
62
- end
63
-
64
- unless ARGV.first == 'new'
65
- eval File.binread('./Lopatafile') if File.exists?('./Lopatafile')
66
- end
67
-
1
+ require 'thor'
2
+ require_relative 'generators/app'
3
+ require_relative 'world'
4
+ require_relative 'loader'
5
+ require_relative '../lopata'
6
+ require_relative 'observers'
7
+ require_relative 'condition'
8
+
9
+ module Lopata
10
+ # @private
11
+ class Runner < Thor
12
+ desc 'test', 'Run tests'
13
+ option :env, default: :qa, aliases: 'e'
14
+ option :rerun, type: :boolean, aliases: 'r'
15
+ option :keep, type: :boolean, aliases: 'k'
16
+ option :text, aliases: 't'
17
+ option :list, type: :boolean, aliases: 'l'
18
+ def test(*args)
19
+ trap_interrupt
20
+ configure_from_options
21
+ Lopata::Loader.load_shared_steps
22
+ Lopata::Loader.load_scenarios(*args)
23
+ if options[:list]
24
+ list_scenarios
25
+ else
26
+ run_scenarios
27
+ end
28
+ end
29
+
30
+ default_task :test
31
+
32
+ register Generators::App, :new, 'lopata new project-name', 'Init new lopata projects'
33
+
34
+ def self.exit_on_failure?
35
+ true
36
+ end
37
+
38
+ no_commands do
39
+ def configure_from_options
40
+ Lopata.configure do |c|
41
+ c.env = options[:env].to_sym
42
+ c.keep = options[:keep]
43
+ c.load_environment
44
+ c.run_before_start_hooks
45
+ end
46
+ add_text_filter(options[:text]) if options[:text]
47
+ add_rerun_filter if options[:rerun]
48
+ end
49
+
50
+ def add_text_filter(text)
51
+ Lopata.configuration.filters << -> (scenario) { scenario.title.include?(text) }
52
+ end
53
+
54
+ def add_rerun_filter
55
+ to_rerun = Lopata::Client.new.to_rerun
56
+ Lopata.configuration.filters << -> (scenario) { to_rerun.include?(scenario.title) }
57
+ end
58
+
59
+ def trap_interrupt
60
+ trap('INT') { exit!(1) }
61
+ end
62
+
63
+ def list_scenarios
64
+ Lopata.world.scenarios.each { |s| puts s.title }
65
+ end
66
+
67
+ def run_scenarios
68
+ world = Lopata.world
69
+ world.notify_observers(:started, world)
70
+ world.scenarios.each { |s| s.run }
71
+ world.notify_observers(:finished, world)
72
+ end
73
+ end
74
+ end
75
+ end
76
+
77
+ unless ARGV.first == 'new'
78
+ eval File.binread('./Lopatafile') if File.exists?('./Lopatafile')
79
+ end
80
+