onlyoffice_testrail_wrapper 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (28) hide show
  1. checksums.yaml +7 -0
  2. data/lib/onlyoffice_testrail_wrapper.rb +10 -0
  3. data/lib/onlyoffice_testrail_wrapper/helpers/hash_helper.rb +21 -0
  4. data/lib/onlyoffice_testrail_wrapper/helpers/rspec_helper.rb +24 -0
  5. data/lib/onlyoffice_testrail_wrapper/helpers/ruby_helper.rb +10 -0
  6. data/lib/onlyoffice_testrail_wrapper/helpers/string_helper.rb +12 -0
  7. data/lib/onlyoffice_testrail_wrapper/helpers/system_helper.rb +17 -0
  8. data/lib/onlyoffice_testrail_wrapper/mock/rspec_example_mock.rb +40 -0
  9. data/lib/onlyoffice_testrail_wrapper/name.rb +9 -0
  10. data/lib/onlyoffice_testrail_wrapper/rspec_extension.rb +14 -0
  11. data/lib/onlyoffice_testrail_wrapper/testrail.rb +187 -0
  12. data/lib/onlyoffice_testrail_wrapper/testrail_case.rb +67 -0
  13. data/lib/onlyoffice_testrail_wrapper/testrail_helper.rb +173 -0
  14. data/lib/onlyoffice_testrail_wrapper/testrail_helper/testrail_helper_rspec_metadata.rb +55 -0
  15. data/lib/onlyoffice_testrail_wrapper/testrail_helper/testrail_status_helper.rb +18 -0
  16. data/lib/onlyoffice_testrail_wrapper/testrail_milestone.rb +23 -0
  17. data/lib/onlyoffice_testrail_wrapper/testrail_plan.rb +92 -0
  18. data/lib/onlyoffice_testrail_wrapper/testrail_plan_entry.rb +16 -0
  19. data/lib/onlyoffice_testrail_wrapper/testrail_project.rb +227 -0
  20. data/lib/onlyoffice_testrail_wrapper/testrail_project/testrail_project_plan_helper.rb +65 -0
  21. data/lib/onlyoffice_testrail_wrapper/testrail_result.rb +47 -0
  22. data/lib/onlyoffice_testrail_wrapper/testrail_run.rb +147 -0
  23. data/lib/onlyoffice_testrail_wrapper/testrail_section.rb +109 -0
  24. data/lib/onlyoffice_testrail_wrapper/testrail_suite.rb +113 -0
  25. data/lib/onlyoffice_testrail_wrapper/testrail_test.rb +40 -0
  26. data/lib/onlyoffice_testrail_wrapper/testrail_tools/testrail_tools.rb +119 -0
  27. data/lib/onlyoffice_testrail_wrapper/version.rb +7 -0
  28. metadata +237 -0
@@ -0,0 +1,55 @@
1
+ # frozen_string_literal: true
2
+
3
+ module OnlyofficeTestrailWrapper
4
+ # Module for working with rspec metadata
5
+ module TestrailHelperRspecMetadata
6
+ # @return [String] version of tested app
7
+ def version
8
+ return @version if @version
9
+ return @plan.name if @plan&.name
10
+
11
+ 'Unknown'
12
+ end
13
+
14
+ # @return [String] example execution time in seconds
15
+ def example_time_in_seconds(example)
16
+ execution_time = (Time.now - example.metadata[:execution_result].started_at).to_i
17
+ execution_time = 1 if execution_time.zero? # Testrail cannot receive 0 as elapsed time
18
+ "#{execution_time}s"
19
+ end
20
+
21
+ # Fill default values for custom fields
22
+ # @param [RSpec::Core::Example] example with metadata
23
+ # @return [Hash] custom fields
24
+ def init_custom_fields(example)
25
+ custom_fields = {}
26
+ # TODO: Fix dependencies from other project
27
+ return custom_fields if defined?(AppManager).nil?
28
+
29
+ custom_fields[:elapsed] = example_time_in_seconds(example)
30
+ custom_fields[:version] = version
31
+ custom_fields[:custom_host] = SystemHelper.hostname
32
+ custom_fields[:custom_screenshot_link] = screenshot_link if example.exception
33
+ custom_fields
34
+ end
35
+
36
+ # @return [String] link to screenshot
37
+ # empty string if not supported
38
+ def screenshot_link
39
+ return AppManager.create_screenshots if AppManager.respond_to?(:create_screenshots)
40
+
41
+ ''
42
+ end
43
+
44
+ def parse_pending_comment(pending_message)
45
+ return [:pending, 'There is problem with initialization of @bugzilla_helper', nil] if @bugzilla_helper.nil?
46
+
47
+ bug_id = @bugzilla_helper.bug_id_from_string(pending_message)
48
+ return [:pending, pending_message] if bug_id.nil?
49
+
50
+ bug_status = @bugzilla_helper.bug_status(bug_id)
51
+ status = bug_status.include?('VERIFIED') ? :failed : :pending
52
+ [status, "#{pending_message}\nBug has status: #{bug_status}, test was failed", bug_id]
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ module OnlyofficeTestrailWrapper
4
+ module TestrailStatusHelper
5
+ # check the statuses is exist
6
+ # @param [Array] status with symbols
7
+ def check_status_exist(status)
8
+ status = [status] unless status.is_a?(Array)
9
+ status.each do |current_status|
10
+ unless current_status.is_a?(Symbol)
11
+ raise "Founded status '#{current_status}' is a '#{current_status.class}'! " \
12
+ 'All statuses must be symbols'
13
+ end
14
+ raise 'One or some statuses is not found. Pls, check it' unless TestrailResult::RESULT_STATUSES.key?(current_status)
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ module OnlyofficeTestrailWrapper
4
+ class TestrailMilestone
5
+ attr_accessor :id, :name, :description, :is_completed
6
+
7
+ def initialize(name = '', description = '', is_completed = false, id = nil)
8
+ @id = id.to_i
9
+ @name = name
10
+ @description = description
11
+ @is_completed = is_completed
12
+ end
13
+
14
+ def update(is_completed = false, name = @name, description = @description)
15
+ HashHelper.parse_to_class_variable(Testrail2.http_post("index.php?/api/v2/update_milestone/#{@id}", name: name, description: description,
16
+ is_completed: is_completed), TestrailMilestone)
17
+ end
18
+
19
+ def delete
20
+ Testrail2.http_post "index.php?/api/v2/delete_milestone/#{@id}", {}
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,92 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'testrail_plan_entry'
4
+
5
+ module OnlyofficeTestrailWrapper
6
+ class TestrailPlan
7
+ # @return [Integer] Id of test plan
8
+ attr_accessor :id
9
+ # @return [String] test run name
10
+ attr_accessor :name
11
+ # @return [Integer] Id of project
12
+ attr_accessor :project_id
13
+ # @return [String] test plan description
14
+ attr_accessor :description
15
+ # @return [Array] test plan entries(Suites)
16
+ attr_accessor :entries
17
+ # @return [Integer] milestone id
18
+ attr_accessor :milestone_id
19
+ # @return [True, False] Completed this test plan or not
20
+ attr_accessor :is_completed
21
+ # @return [String] url to current test plan
22
+ attr_reader :url
23
+
24
+ def initialize(name = '', entries = [], description = '', milestone_id = nil, id = nil)
25
+ @name = name
26
+ @entries = entries
27
+ @description = description
28
+ @milestone_id = milestone_id
29
+ @id = id
30
+ end
31
+
32
+ def add_entry(name, suite_id, include_all = true, case_ids = [], assigned_to = nil)
33
+ entry = HashHelper.parse_to_class_variable(Testrail2.http_post("index.php?/api/v2/add_plan_entry/#{@id}", suite_id: suite_id, name: StringHelper.warnstrip!(name.to_s),
34
+ include_all: include_all, case_ids: case_ids, assigned_to: assigned_to), TestrailPlanEntry)
35
+ OnlyofficeLoggerHelper.log "Added plan entry: #{name.to_s.strip}"
36
+ entry.runs.each_with_index { |run, index| entry.runs[index] = HashHelper.parse_to_class_variable(run, TestrailRun) }
37
+ entry
38
+ end
39
+
40
+ def delete_entry(entry_id)
41
+ Testrail2.http_post "index.php?/api/v2/delete_plan_entry/#{@id}/#{entry_id}", {}
42
+ end
43
+
44
+ def delete
45
+ Testrail2.http_post "index.php?/api/v2/delete_plan/#{@id}", {}
46
+ OnlyofficeLoggerHelper.log "Deleted plan: #{@name}"
47
+ nil
48
+ end
49
+
50
+ def tests_results
51
+ run_results = {}
52
+ @entries.each do |current_entrie|
53
+ current_entrie.runs.each do |current_run|
54
+ current_run.pull_tests_results
55
+ run_results.merge!(current_run.name => current_run.test_results)
56
+ end
57
+ end
58
+ run_results
59
+ end
60
+
61
+ # Get run from plan
62
+ # @param run_name [String] run to find
63
+ # @return TestrailRun
64
+ def run(run_name)
65
+ @entries.each do |entry|
66
+ run = entry.runs.first
67
+ return run if run.name == run_name
68
+ end
69
+ nil
70
+ end
71
+
72
+ # Get all runs in current plan
73
+ # @return [Array, TestrailRuns]
74
+ def runs
75
+ runs = []
76
+ @entries.each do |entry|
77
+ runs << entry.runs.first
78
+ end
79
+ runs
80
+ end
81
+
82
+ # Generate array of durations of runs
83
+ # @return [Array] array of durations, sorted by descrease
84
+ def plan_durations
85
+ durations_hash = {}
86
+ runs.each do |current_run|
87
+ durations_hash[current_run.name] = current_run.duration
88
+ end
89
+ durations_hash.sort_by { |_, time| time }.reverse
90
+ end
91
+ end
92
+ end
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ module OnlyofficeTestrailWrapper
4
+ class TestrailPlanEntry
5
+ attr_accessor :suite_id, :name, :assigned_to, :include_all, :case_ids, :runs
6
+
7
+ def initialize(params = {})
8
+ @suite_id = params.fetch(:suite_id, nil)
9
+ @name = params.fetch(:name, '')
10
+ @include_all = params.fetch(:include_all, true)
11
+ @case_ids = params.fetch(:case_ids, [])
12
+ @assigned_to = params.fetch(:assigned_to, nil)
13
+ @runs = params.fetch(:runs, [])
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,227 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'testrail_suite'
4
+ require_relative 'testrail_run'
5
+ require_relative 'testrail_plan'
6
+ require_relative 'testrail_milestone'
7
+ require_relative 'testrail_project/testrail_project_plan_helper'
8
+
9
+ module OnlyofficeTestrailWrapper
10
+ # @author Roman.Zagudaev
11
+ # Class for working with Test Projects
12
+ class TestrailProject
13
+ include TestrailProjectPlanHelper
14
+ # @return [Integer] Id of project
15
+ attr_accessor :id
16
+ # @return [String] Name of project
17
+ attr_accessor :name
18
+ # @return [String] announcement string
19
+ attr_accessor :announcement
20
+ # @return [true, false] is show announcement option enabled
21
+ attr_accessor :show_announcement
22
+ # @return [true, false] is project completed
23
+ attr_accessor :is_completed
24
+ # @return [String] Date, when test completed
25
+ attr_accessor :completed_on
26
+ # @return [String] url to project
27
+ attr_accessor :url
28
+ # @return [Array<String>] name of suites
29
+ attr_accessor :suites_names
30
+ # @return [Array<String>] name of runs
31
+ attr_accessor :runs_names
32
+ # @return [Array<String>] name of planes
33
+ attr_accessor :plans_names
34
+ # @return [Array<String>] name of milestones
35
+ attr_accessor :milestones_names
36
+
37
+ # Default constructor
38
+ # @param id [id] id of project, default = nil
39
+ # @param name [String] name of project, default = nil
40
+ # @param announcement [String] announcement of project, default = nil
41
+ # @param is_completed [true, false] is project completed, default = nil
42
+ # @return [TestRunTestRail] new Test run
43
+ def initialize(name = '', announcement = nil, show_announcement = true, is_completed = false, id = nil)
44
+ @id = id.to_i
45
+ @name = name
46
+ @announcement = announcement
47
+ @show_announcement = show_announcement
48
+ @is_completed = is_completed
49
+ @suites_names = {}
50
+ @runs_names = {}
51
+ @plans_names = {}
52
+ @milestones_names = {}
53
+ end
54
+
55
+ def update(is_completed = false, name = @name, announcement = @announcement, show_announcement = @show_announcement)
56
+ @testrail.projects_names.delete[@name]
57
+ @testrail.projects_names[StringHelper.warnstrip!(name.to_s)] = @id
58
+ updated_project = HashHelper.parse_to_class_variable(Testrail2.http_post("index.php?/api/v2/update_project/#{@id}", name: name, announcement: announcement,
59
+ show_announcement: show_announcement, is_completed: is_completed), TestrailProject)
60
+ OnlyofficeLoggerHelper.log "Updated project: #{updated_project.name}"
61
+ updated_project
62
+ end
63
+
64
+ def delete
65
+ Testrail2.http_post "index.php?/api/v2/delete_project/#{@id}", {}
66
+ OnlyofficeLoggerHelper.log "Deleted project: #{@name}"
67
+ @testrail.projects_names.delete @name
68
+ end
69
+
70
+ # region: SUITE
71
+
72
+ def suite(name_or_id)
73
+ case name_or_id.class.to_s
74
+ when 'Fixnum'
75
+ get_suite_by_id name_or_id
76
+ when 'String'
77
+ init_suite_by_name name_or_id
78
+ else
79
+ raise 'Wrong argument. Must be name [String] or id [Integer]'
80
+ end
81
+ end
82
+
83
+ # Get all test runs of project
84
+ # @return [Array, TestrailSuite] array with runs
85
+ def get_suites
86
+ suites = Testrail2.http_get("index.php?/api/v2/get_suites/#{@id}")
87
+ @suites_names = HashHelper.get_hash_from_array_with_two_parameters(suites, 'name', 'id') if @suites_names.empty?
88
+ suites
89
+ end
90
+
91
+ # Get Test Suite by it's name
92
+ # @param [String] name name of test suite
93
+ # @return [TestrailSuite] test suite
94
+ def get_suite_by_name(name)
95
+ get_suites if @suites_names.empty?
96
+ @suites_names[StringHelper.warnstrip!(name)].nil? ? nil : get_suite_by_id(@suites_names[name])
97
+ end
98
+
99
+ def get_suite_by_id(id)
100
+ suite = HashHelper.parse_to_class_variable(Testrail2.http_get("index.php?/api/v2/get_suite/#{id}"), TestrailSuite)
101
+ suite.instance_variable_set('@project', self)
102
+ OnlyofficeLoggerHelper.log("Initialized suite: #{suite.name}")
103
+ suite
104
+ end
105
+
106
+ # Init suite by it's name
107
+ # @param [String] name name of suit
108
+ # @return [TestrailSuite] suite with this name
109
+ def init_suite_by_name(name)
110
+ found_suite = get_suite_by_name name
111
+ found_suite.nil? ? create_new_suite(name) : found_suite
112
+ end
113
+
114
+ # Create new test suite in project
115
+ # @param [String] name name of suite
116
+ # @param [String] description description of suite (default = nil)
117
+ # @return [TestrailSuite] created suite
118
+ def create_new_suite(name, description = '')
119
+ new_suite = HashHelper.parse_to_class_variable(Testrail2.http_post("index.php?/api/v2/add_suite/#{@id}", name: StringHelper.warnstrip!(name), description: description), TestrailSuite)
120
+ new_suite.instance_variable_set('@project', self)
121
+ OnlyofficeLoggerHelper.log "Created new suite: #{new_suite.name}"
122
+ @suites_names[new_suite.name] = new_suite.id
123
+ new_suite
124
+ end
125
+
126
+ # endregion
127
+
128
+ # region: RUN
129
+
130
+ def test_run(name_or_id)
131
+ case name_or_id.class.to_s
132
+ when 'Fixnum'
133
+ get_run_by_id name_or_id
134
+ when 'String'
135
+ init_run_by_name name_or_id
136
+ else
137
+ raise 'Wrong argument. Must be name [String] or id [Integer]'
138
+ end
139
+ end
140
+
141
+ # Get all test runs of project
142
+ # @return [Array, TestRunTestrail] array of test runs
143
+ def get_runs(filters = {})
144
+ get_url = "index.php?/api/v2/get_runs/#{@id}"
145
+ filters.each { |key, value| get_url += "&#{key}=#{value}" }
146
+ runs = Testrail2.http_get(get_url)
147
+ @runs_names = HashHelper.get_hash_from_array_with_two_parameters(runs, 'name', 'id') if @runs_names.empty?
148
+ runs
149
+ end
150
+
151
+ # Get Test Run by it's name
152
+ # @param [String] name name of test run
153
+ # @return [TestRunTestRail] test run
154
+ def get_run_by_name(name)
155
+ get_runs if @runs_names.empty?
156
+ @runs_names[StringHelper.warnstrip!(name)].nil? ? nil : get_run_by_id(@runs_names[name])
157
+ end
158
+
159
+ def get_run_by_id(id)
160
+ run = HashHelper.parse_to_class_variable(Testrail2.http_get("index.php?/api/v2/get_run/#{id}"), TestrailRun)
161
+ OnlyofficeLoggerHelper.log("Initialized run: #{run.name}")
162
+ run.instance_variable_set('@project', self)
163
+ run
164
+ end
165
+
166
+ def init_run_by_name(name, suite_id = nil)
167
+ found_run = get_run_by_name name
168
+ suite_id = get_suite_by_name(name).id if suite_id.nil?
169
+ found_run.nil? ? create_new_run(name, suite_id) : found_run
170
+ end
171
+
172
+ def create_new_run(name, suite_id, description = '')
173
+ new_run = HashHelper.parse_to_class_variable(Testrail2.http_post("index.php?/api/v2/add_run/#{@id}", name: StringHelper.warnstrip!(name), description: description, suite_id: suite_id), TestrailRun)
174
+ OnlyofficeLoggerHelper.log "Created new run: #{new_run.name}"
175
+ new_run.instance_variable_set('@project', self)
176
+ @runs_names[new_run.name] = new_run.id
177
+ new_run
178
+ end
179
+
180
+ # endregion
181
+
182
+ # region: MILESTONE
183
+
184
+ def milestone(name_or_id)
185
+ case name_or_id.class.to_s
186
+ when 'Fixnum'
187
+ get_milestone_by_id name_or_id
188
+ when 'String'
189
+ init_milestone_by_name name_or_id
190
+ else
191
+ raise 'Wrong argument. Must be name [String] or id [Integer]'
192
+ end
193
+ end
194
+
195
+ def init_milestone_by_name(name)
196
+ found_milestone = get_milestone_by_name name
197
+ found_milestone.nil? ? create_new_milestone(name) : found_milestone
198
+ end
199
+
200
+ def get_milestone_by_id(id)
201
+ milestone = HashHelper.parse_to_class_variable(Testrail2.http_get("index.php?/api/v2/get_milestone/#{id}"), TestrailMilestone)
202
+ OnlyofficeLoggerHelper.log("Initialized milestone: #{milestone.name}")
203
+ milestone
204
+ end
205
+
206
+ def get_milestone_by_name(name)
207
+ get_milestones if @milestones_names.empty?
208
+ @milestones_names[StringHelper.warnstrip!(name.to_s)].nil? ? nil : get_milestone_by_id(@milestones_names[name])
209
+ end
210
+
211
+ def get_milestones
212
+ milestones = Testrail2.http_get("index.php?/api/v2/get_milestones/#{@id}")
213
+ @milestones_names = HashHelper.get_hash_from_array_with_two_parameters(milestones, 'name', 'id') if @milestones_names.empty?
214
+ milestones
215
+ end
216
+
217
+ # @param [String] name of milestone
218
+ # @param [String] description of milestone
219
+ def create_new_milestone(name, description = '')
220
+ new_milestone = HashHelper.parse_to_class_variable(Testrail2.http_post("index.php?/api/v2/add_milestone/#{@id}", :name => StringHelper.warnstrip!(name.to_s), description => description), TestrailMilestone)
221
+ OnlyofficeLoggerHelper.log "Created new milestone: #{new_milestone.name}"
222
+ new_milestone
223
+ end
224
+
225
+ # endregion
226
+ end
227
+ end
@@ -0,0 +1,65 @@
1
+ # frozen_string_literal: true
2
+
3
+ module OnlyofficeTestrailWrapper
4
+ # Mehtods to help working with Plan in Project
5
+ module TestrailProjectPlanHelper
6
+ def plan(name_or_id)
7
+ case name_or_id.class.to_s
8
+ when 'Fixnum'
9
+ get_plan_by_id name_or_id
10
+ when 'String'
11
+ init_plan_by_name name_or_id
12
+ else
13
+ raise 'Wrong argument. Must be name [String] or id [Integer]'
14
+ end
15
+ end
16
+
17
+ def init_plan_by_name(name)
18
+ found_plan = get_plan_by_name name
19
+ found_plan.nil? ? create_new_plan(name) : found_plan
20
+ end
21
+
22
+ def get_plan_by_id(id)
23
+ plan = HashHelper.parse_to_class_variable(Testrail2.http_get("index.php?/api/v2/get_plan/#{id}"), TestrailPlan)
24
+ OnlyofficeLoggerHelper.log("Initialized plan: #{plan.name}")
25
+ plan.entries.each_with_index do |test_entry, index|
26
+ entry = HashHelper.parse_to_class_variable(test_entry, TestrailPlanEntry)
27
+ entry.runs.each_with_index { |run, i| entry.runs[i] = HashHelper.parse_to_class_variable(run, TestrailRun) }
28
+ plan.entries[index] = entry
29
+ end
30
+ plan.instance_variable_set '@project', self
31
+ plan
32
+ end
33
+
34
+ def get_plan_by_name(name)
35
+ get_plans if @plans_names.empty?
36
+ @plans_names[StringHelper.warnstrip!(name.to_s)].nil? ? nil : get_plan_by_id(@plans_names[name])
37
+ end
38
+
39
+ # Get list of all TestPlans
40
+ # @param filters [Hash] filter conditions
41
+ # @return [Array, TestrailPlan] test plans
42
+ def get_plans(filters = {})
43
+ get_url = "index.php?/api/v2/get_plans/#{@id}"
44
+ filters.each { |key, value| get_url += "&#{key}=#{value}" }
45
+ plans = Testrail2.http_get(get_url)
46
+ @plans_names = HashHelper.get_hash_from_array_with_two_parameters(plans, 'name', 'id') if @plans_names.empty?
47
+ plans
48
+ end
49
+
50
+ # @param [String] name of test plan
51
+ # @param [String] description
52
+ # @param [Integer] milestone_id
53
+ def create_new_plan(name, entries = [], description = '', milestone_id = nil)
54
+ new_plan = HashHelper.parse_to_class_variable(Testrail2.http_post("index.php?/api/v2/add_plan/#{@id}", name: StringHelper.warnstrip!(name), description: description,
55
+ milestone_id: milestone_id, entries: entries), TestrailPlan)
56
+ OnlyofficeLoggerHelper.log "Created new plan: #{new_plan.name}"
57
+ new_plan.entries.each_with_index do |entry, i|
58
+ new_plan.entries[i] = HashHelper.parse_to_class_variable(entry, TestrailPlanEntry)
59
+ new_plan.entries[i].runs.each_with_index { |run, j| new_plan.entries[i].runs[j] = HashHelper.parse_to_class_variable(run, TestrailRun) }
60
+ end
61
+ @plans_names[new_plan.name] = new_plan.id
62
+ new_plan
63
+ end
64
+ end
65
+ end