lopata 0.1.13 → 0.1.17

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
+