test_rail-api 0.4.0

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.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 46276f27c1fc6c5bb81ad20d5b6f32fa83898dfb
4
+ data.tar.gz: 48849b393aadc4e1e2774bcef2b1f56b8455a81a
5
+ SHA512:
6
+ metadata.gz: 869cf0734b672613ddbc0ae5d803cc8630a1971fff0c03c40a2256f3a531600f2e95f17f4905cb06f3cfb79fdc20366c90256bcddc2f437a39e1d86d26e6293c
7
+ data.tar.gz: 788cc15eeaf18360eb8a5e319065853a2ed85da6c5490402c3581195da109021e3dfc59dd7c4fc07dec459a181588ced7754dff522c6e32a66e7f2519d7a10ab
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2015 BBC
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
22
+
@@ -0,0 +1,50 @@
1
+ $: << File.dirname(__FILE__)
2
+ require 'net/http'
3
+ require 'net/https'
4
+ require 'json'
5
+ require "virtus"
6
+ require "test_rail/configuration"
7
+ require "test_rail/api"
8
+ require "test_rail/initialize_with_api"
9
+ require 'test_rail/project'
10
+ require 'test_rail/section'
11
+ require 'test_rail/suite'
12
+ require 'test_rail/test_case'
13
+ require 'test_rail/plan'
14
+ require 'test_rail/run'
15
+ require 'test_rail/test'
16
+ require 'test_rail/case_type'
17
+ require 'test_rail/priority'
18
+
19
+ module TestRail
20
+
21
+ NO_CONFIG_ERROR = <<eos
22
+ A configuration block must first be provided.
23
+ e.g:
24
+ TestRail.configure do |config|
25
+ config.user = "user"
26
+ config.password = "password"
27
+ config.namespace = "namespace"
28
+ end
29
+ eos
30
+
31
+ class << self
32
+ attr_accessor :configuration, :api
33
+
34
+ def configure
35
+ self.configuration = Configuration.new
36
+ yield(configuration)
37
+ end
38
+
39
+ def method_missing(method, *args, &block)
40
+ raise TestRail::NO_CONFIG_ERROR if configuration.nil?
41
+ api.send(method, *args, &block)
42
+ end
43
+
44
+ private
45
+
46
+ def api
47
+ @api ||= TestRail::API.new(configuration.to_hash)
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,355 @@
1
+ module TestRail
2
+ class API
3
+ attr_accessor :server
4
+
5
+ TESTRAIL = 'testrail.com'
6
+ HEADERS = { "Content-Type" => "application/json" }
7
+
8
+ STATUSES = {
9
+ :passed => 1,
10
+ :pass => 1,
11
+ :blocked => 2,
12
+ :untested => 3,
13
+ :retest => 4,
14
+ :failed => 5,
15
+ :fail => 5
16
+ }
17
+
18
+
19
+ # Initialize a new tesrail interface
20
+ # TestRail.new( :user => 'your@email.com',
21
+ # :password => 'passw0rd',
22
+ # :namespace => 'yourteam' )
23
+ def initialize(args)
24
+ raise "Need to provide arguments to constructor" if !args
25
+ @user = args[:user] or raise "Missing username (:user => 'email@address.com')"
26
+ @password = args[:password] or raise "Missing password (:password => 'abc123')"
27
+ @namespace = args[:namespace] or raise "Missing namespace (:namespace => 'testteam')"
28
+
29
+ @server = @namespace + "." + TESTRAIL
30
+ @host = URI('https://' + @server)
31
+ @api = "/index.php?/api/v2/"
32
+ @port = 443
33
+
34
+ end
35
+
36
+ #
37
+ # Project API calls
38
+ #
39
+
40
+ # Return a list of projects
41
+ def get_projects
42
+ list = get('get_projects')
43
+ list.collect do |item|
44
+ TestRail::Project.new(item.merge({ :api => self }))
45
+ end
46
+ end
47
+
48
+ # Return a specific project by id
49
+ # api.get_project( :id => 1 )
50
+ def get_project(args)
51
+ id = args[:id] or raise "Missing id (:id => 1)"
52
+ project = get('get_project', [id])
53
+ TestRail::Project.new(project.merge({ :api => self }))
54
+ end
55
+
56
+ # Search for a project by name
57
+ # testrail.find_project(:name => 'Amazing project')
58
+ def find_project(args)
59
+ name = args[:name] or raise "Missing name (:name => 'Amazing Project')"
60
+ projects = get_projects
61
+ projectexists = projects.select { |p| p.name == name }.first
62
+ if (!projectexists)
63
+ raise "Project Not Found."
64
+ end
65
+ return projectexists
66
+ end
67
+
68
+ #
69
+ # Suite API calls
70
+ #
71
+
72
+ # Add a new suite
73
+ # (If suite already exists, a new one is created with the same name)
74
+ # api.add_suite( :project_id => 1, :name => 'Cucumber features', :description => 'BDD Tests' )
75
+ # Returns the suite object
76
+ def add_suite(args)
77
+ project_id = args[:project_id] or raise 'Missing project id (:project_id => 1)'
78
+ name = args[:name] or raise 'Missing name (:name => "Cucumber features")'
79
+ description = args[:description]
80
+
81
+ suite = post('add_suite', [project_id], { :name => name, :description => description })
82
+ TestRail::Suite.new(suite.merge({ :api => self }))
83
+ end
84
+
85
+ # Get a list of suites for a project
86
+ # api.get_suites( :project_id => 1 )
87
+ # Returns a list of suite objects
88
+ def get_suites(args)
89
+ id = args[:project_id] or raise "Missing project id (:project_id => 1)"
90
+ list = get('get_suites', [id])
91
+ list.collect do |item|
92
+ TestRail::Suite.new(item.merge({ :api => self }))
93
+ end
94
+ end
95
+
96
+ # Get an existing suite by id
97
+ # testrail.get_suite( :id => 1 )
98
+ # Returns the suite object
99
+ def get_suite(args)
100
+ id = args[:id] or raise "Missing suite id (:id => 1)"
101
+ suite = get('get_suite', [id])
102
+ TestRail::Suite.new(suite.merge({ :api => self }))
103
+ end
104
+
105
+ def update_suite(args)
106
+ id = args[:id] or raise "Missing suite id (:id => 1)"
107
+ name = args[:name]
108
+ description = args[:description]
109
+
110
+ suite = post('update_suite', [id], { :name => name, :description => description })
111
+ TestRail::Suite.new(suite.merge({ :api => self }))
112
+ end
113
+
114
+ #
115
+ # Section API Calls
116
+ #
117
+ def add_section(args)
118
+ project_id = args[:project_id] or raise 'Missing project id (:project_id => 1)'
119
+ name = args[:name] or raise 'Missing name (:name => "UI features")'
120
+ suite_id = args[:suite_id] or raise 'Missing suite id (:suite_id => 1)'
121
+ parent_id = args[:parent_id]
122
+
123
+ section = post('add_section', [project_id], { :suite_id => suite_id, :name => name, :parent_id => parent_id })
124
+ TestRail::Section.new(section.merge({ :api => self, :project_id => project_id, :suite_id => suite_id }))
125
+ end
126
+
127
+ def get_sections(args)
128
+ project_id = args[:project_id] or raise 'Missing project id (:project_id => 1)'
129
+ suite_id = args[:suite_id] or raise 'Missing suite id (:suite_id => 1)'
130
+ list = get('get_sections', [project_id], { :suite_id => suite_id })
131
+ list.collect do |item|
132
+ TestRail::Section.new(item.merge({ :api => self, :project_id => project_id }))
133
+ end
134
+ end
135
+
136
+ def update_section(args)
137
+ section_id = args[:section_id] or raise 'Missing section id (:section_id => 1)'
138
+ project_id = args[:project_id] or raise 'Missing project id (:project_id => 1)'
139
+ name = args[:name] or raise 'Missing name (:name => "UI features")'
140
+ suite_id = args[:suite_id] or raise 'Missing suite id (:suite_id => 1)'
141
+ parent_id = args[:parent_id]
142
+
143
+ section = post('update_section', [section_id], { :suite_id => suite_id, :name => name, :parent_id => parent_id })
144
+ TestRail::Section.new(section.merge({ :api => self, :project_id => project_id }))
145
+ end
146
+
147
+ #
148
+ # Testcase API
149
+ #
150
+ def get_cases(args)
151
+ project_id = args[:project_id] or raise 'Missing project id (:project_id => 1)'
152
+ suite_id = args[:suite_id] or raise 'Missing suite id (:suite_id => 1)'
153
+ section_id = args[:section_id]
154
+ list = get('get_cases', [project_id], { :suite_id => suite_id, :section_id => section_id })
155
+ list.collect do |item|
156
+ TestRail::TestCase.new(item.merge({ :api => self }))
157
+ end
158
+ end
159
+
160
+ def get_case(args)
161
+ case_id = args[:case_id] or raise 'Missing test case id (:case_id => 1)'
162
+ testcase = get('get_case', [case_id])
163
+ TestRail::TestCase.new(testcase.merge({ :api => self }))
164
+ end
165
+
166
+ def add_case(args)
167
+ section_id = args[:section_id] or raise 'Missing section id (:section_id => 1)'
168
+ title = args[:title] or raise 'Missing title (:title => "Use logs in")'
169
+ steps = args[:steps]
170
+ type_id = args[:type_id]
171
+ priority_id = args[:priority_id]
172
+
173
+ test_case = post('add_case', [section_id],
174
+ { :title => title, :custom_steps => steps,
175
+ :type_id => type_id, :priority_id => priority_id })
176
+
177
+ TestRail::TestCase.new(test_case.merge({ :api => self }))
178
+ end
179
+
180
+ def update_case(args)
181
+ case_id = args[:case_id] or raise "Missing case id (:case_id => 1)"
182
+
183
+ new_values = {}
184
+
185
+ new_values[:title] = args[:title] if args[:title]
186
+ new_values[:custom_steps] = args[:steps] if args[:steps]
187
+ new_values[:priority_id] = args[:priority_id] if args[:priority_id]
188
+ new_values[:type_id] = args[:type_id] if args[:type_id]
189
+
190
+ test_case = post('update_case', [case_id], new_values )
191
+
192
+ TestRail::TestCase.new(test_case.merge({ :api => self }))
193
+ end
194
+
195
+ #
196
+ # Results API
197
+ #
198
+ def add_result_for_case(args)
199
+ run_id = args[:run_id] or raise "Missing test run id (:run_id => 1)"
200
+ case_id = args[:case_id] or raise "Missing test case id (:case_id => 1)"
201
+
202
+ status_id = args[:status_id]
203
+ if !status_id
204
+ status_id = STATUSES[args[:status].to_sym]
205
+ raise "Couldn't determine result status '#{args[:status]}'" if !status_id
206
+ end
207
+
208
+ result = {
209
+ :status_id => status_id,
210
+ :comment => args[:comment],
211
+ :version => args[:version],
212
+ :elapsed => args[:elapsed]
213
+ }
214
+
215
+ test_rail_result = post('add_result_for_case', [run_id, case_id], result)
216
+ #TODO new this into a relevant TestRails object
217
+ end
218
+
219
+ # Given a run id, retrieve a plan
220
+ def get_run(args)
221
+ run_id = args[:run_id] or raise "Missing run id ( :run_id => 1)"
222
+
223
+ result = get('get_run', [run_id])
224
+ TestRail::Run.new(result.merge({ :api => self }))
225
+ end
226
+
227
+ # Creates a new run
228
+ # api.add_run( :project_id => project_id, :suite_id => suite_id )
229
+ # Optional parameters:
230
+ # name: Name to give the run
231
+ # description: Description of the run
232
+ def add_run(args)
233
+ project_id = args[:project_id] or raise "Missing project id ( :project_id => 1)"
234
+ suite_id = args[:suite_id] or raise "Missing suite id ( :suite_id => 1)"
235
+
236
+ params = {
237
+ :suite_id => suite_id,
238
+ :name => args[:name],
239
+ :description => args[:description]
240
+ }
241
+
242
+ result = post('add_run', [project_id], params)
243
+ TestRail::Run.new(result.merge({ :api => self }))
244
+ end
245
+
246
+ # Given a plan id, returns a plan (and populates internal run objects)
247
+ def get_plan(args)
248
+ plan_id = args[:plan_id] or raise "Missing plan id (:plan_id => 1)"
249
+
250
+ result = get('get_plan', [plan_id])
251
+
252
+ raw_runs = result['entries'].collect { |e| e['runs'] }.flatten
253
+ runs = raw_runs.each.collect { |r| TestRail::Run.new(r.merge({ :api => self })) }
254
+
255
+ plan = TestRail::Plan.new(result.merge({ :api => self, :runs => runs }))
256
+
257
+ plan
258
+ end
259
+
260
+ def get_tests(args)
261
+ run_id = args[:run_id] or raise "Missing run id (:run_id => 1)"
262
+ list = get('get_tests', [run_id])
263
+
264
+ list.collect do |item|
265
+ TestRail::Test.new(item.merge({ :api => self }))
266
+ end
267
+ end
268
+
269
+ # Get all the case types defined for this testrail instance
270
+ def get_case_types
271
+ result = get('get_case_types')
272
+
273
+ result.collect do |type|
274
+ TestRail::CaseType.new(type.merge({ :api => self }))
275
+ end
276
+ end
277
+
278
+ # Get all the priorities defined for this testrail instance
279
+ def get_priorities
280
+ result = get('get_priorities')
281
+
282
+ result.collect do |priority|
283
+ TestRail::Priority.new(priority.merge({ :api => self }))
284
+ end
285
+ end
286
+
287
+
288
+ #
289
+ # Private methods
290
+ #
291
+ private
292
+
293
+ # Creates and caches an http object that is used by the get and
294
+ # post commands
295
+ def http
296
+ if !@http
297
+ path = @host.to_s + @api
298
+ uri = URI.parse(path)
299
+
300
+ proxy_env = ENV['HTTP_PROXY']
301
+
302
+ if proxy_env
303
+ proxy_uri = URI(proxy_env)
304
+ proxy = Net::HTTP::Proxy(proxy_uri.host, proxy_uri.port)
305
+ @http = proxy.new(uri.host, uri.port)
306
+ else
307
+ @http = Net::HTTP.new(uri.host, uri.port)
308
+ end
309
+ @http.use_ssl = true
310
+ @http.verify_mode = OpenSSL::SSL::VERIFY_NONE
311
+ end
312
+
313
+ @http
314
+ end
315
+
316
+ def get(call, array_args=[], hash_args={})
317
+ send_request('get', call, array_args, hash_args, nil)
318
+ end
319
+
320
+ def post(call, array_args=[], post_args={})
321
+ send_request('post', call, array_args, nil, post_args)
322
+ end
323
+
324
+ # get request
325
+ def send_request(protocol, call, array_args = [], hash_args = {}, post_data = {})
326
+ path = @host.to_s + @api + call
327
+ if array_args
328
+ path += '/' + array_args.join('/')
329
+ end
330
+ if hash_args
331
+ path += '&' + hash_args.map { |k, v| "#{k.to_s}=#{v}" }.join('&')
332
+ end
333
+ uri = URI.parse(path)
334
+
335
+ request = nil
336
+ if protocol == 'get'
337
+ request = Net::HTTP::Get.new(uri.request_uri, HEADERS)
338
+ else
339
+ request = Net::HTTP::Post.new(uri.request_uri, HEADERS)
340
+ request.body = post_data.to_json
341
+ end
342
+ request.basic_auth(@user, @password)
343
+
344
+ response = http.request(request)
345
+
346
+ body = JSON.parse(response.body)
347
+
348
+ if response.code && response.code.to_i == 200
349
+ return body
350
+ else
351
+ raise body["error"].to_s
352
+ end
353
+ end
354
+ end
355
+ end
@@ -0,0 +1,11 @@
1
+ module TestRail
2
+ class CaseType
3
+ include Virtus.model
4
+ include InitializeWithApi
5
+
6
+ attribute :id
7
+ attribute :name
8
+ attribute :is_default
9
+
10
+ end
11
+ end
@@ -0,0 +1,10 @@
1
+ module TestRail
2
+
3
+ class Configuration
4
+ attr_accessor :user, :password, :namespace
5
+
6
+ def to_hash
7
+ { user: user, password: password, namespace: namespace }
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,10 @@
1
+ module TestRail
2
+ module InitializeWithApi
3
+
4
+ # Takes params and assigns the provided api then uses the inherited (usually Virtus) initializer
5
+ def initialize(params)
6
+ @api = params[:api]
7
+ super params
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,25 @@
1
+ module TestRail
2
+ class Plan
3
+ include Virtus.model
4
+
5
+ attribute :id
6
+ attribute :name
7
+ attribute :description
8
+ attribute :milestone_id
9
+ attribute :assignedto_id
10
+ attribute :is_completed
11
+ attribute :completed_on
12
+ attribute :project_id
13
+ attribute :created_on
14
+ attribute :created_by
15
+ attribute :url
16
+ attribute :entries
17
+ attribute :runs, Array
18
+
19
+ class << self
20
+ def find_by_id(plan_id)
21
+ TestRail.get_plan(plan_id: plan_id)
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,13 @@
1
+ module TestRail
2
+ class Priority
3
+ include Virtus.model
4
+ include InitializeWithApi
5
+
6
+ attribute :id
7
+ attribute :name
8
+ attribute :is_default
9
+ attribute :short_name
10
+ attribute :priority
11
+
12
+ end
13
+ end
@@ -0,0 +1,42 @@
1
+ module TestRail
2
+ class Project
3
+ include Virtus.model
4
+ include InitializeWithApi
5
+
6
+ attribute :id
7
+ attribute :name
8
+ attribute :announcement
9
+ attribute :show_announcement
10
+ attribute :is_completed
11
+ attribute :completed_on
12
+ attribute :url
13
+
14
+ # Return a list of suites belonging to this project
15
+ def suites
16
+ @api.get_suites( :project_id => @id )
17
+ end
18
+
19
+ # Create a new suite for this project
20
+ def new_suite( args )
21
+ @api.add_suite( args.merge({:project_id => id}) )
22
+ end
23
+
24
+ # Find a suite in this project based on the suite name
25
+ # project.find_suite( :name => "My Suite" )
26
+ def find_suite( args )
27
+ name = args[:name] or raise "Need to provide the name of a suite"
28
+ suites.select{ |s| s.name == name }.first
29
+ end
30
+
31
+ # Find or create a suite in this project based on the suite name
32
+ # project.find_or_create_suite( :name => "My Suite" )
33
+ def find_or_create_suite( args )
34
+ name = args[:name] or raise "Need to provide the name of a suite"
35
+ suite = self.find_suite( args )
36
+ if suite.nil?
37
+ suite = new_suite( args )
38
+ end
39
+ suite
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,17 @@
1
+ module TestRail
2
+ class Result
3
+ include Virtus.model
4
+
5
+ attribute :id
6
+ attribute :test_id
7
+ attribute :status_id
8
+ attribute :comment
9
+ attribute :version
10
+ attribute :elapsed
11
+ attribute :created_by
12
+ attribute :created_on
13
+ attribute :assignedto_id
14
+ attribute :defects
15
+
16
+ end
17
+ end
@@ -0,0 +1,31 @@
1
+ module TestRail
2
+ class Run
3
+ include Virtus.model
4
+ include InitializeWithApi
5
+
6
+ attribute :id
7
+ attribute :suite_id
8
+ attribute :name
9
+ attribute :description
10
+ attribute :milestone_id
11
+ attribute :assignedto_id
12
+ attribute :include_all
13
+ attribute :is_completed
14
+ attribute :completed_on
15
+ attribute :config
16
+ attribute :url
17
+ attribute :passed_count
18
+ attribute :blocked_count
19
+ attribute :untested_count
20
+ attribute :retest_count
21
+ attribute :failed_count
22
+
23
+ def tests
24
+ @api.get_tests(:run_id => id)
25
+ end
26
+
27
+ def suite
28
+ @api.get_suite(:id => suite_id)
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,65 @@
1
+ module TestRail
2
+ class Section
3
+ include Virtus.model
4
+ include InitializeWithApi
5
+
6
+ attribute :id
7
+ attribute :name
8
+ attribute :project_id
9
+ attribute :parent_id
10
+ attribute :url
11
+ attribute :suite_id
12
+
13
+ def update
14
+ @api.update_section( :section_id => @id, :name => name, :project_id => @project_id, :suite_id => @suite_id, :parent_id => @id)
15
+ end
16
+
17
+ # Get a list of sub-sections
18
+ def sub_sections
19
+ sections = @api.get_sections( :project_id => @project_id, :suite_id => @suite_id )
20
+ sections.reject{ |s| s.parent_id != @id }
21
+ end
22
+
23
+ # Get a list of test-cases
24
+ def test_cases
25
+ @api.get_cases( :project_id => @project_id, :suite_id => @suite_id, :section_id => @id )
26
+ end
27
+
28
+ def new_test_case(args)
29
+ @api.add_case(args.merge({:section_id => @id }))
30
+ end
31
+
32
+ def find_test_case( args )
33
+ title = args[:title] or raise "Need to provide the title of a test case"
34
+ test_cases.select{ |c| c.title == title }.first
35
+ end
36
+
37
+ def find_or_create_test_case( args )
38
+ title = args[:title] or raise "Need to provide the title of a test case"
39
+ test_case = self.find_test_case( args )
40
+ if test_case.nil?
41
+ test_case = new_test_case( args )
42
+ end
43
+ test_case
44
+ end
45
+
46
+ # suite.add_section( :name => 'Section name )
47
+ def add_section( args )
48
+ @api.add_section( :project_id => project_id, :parent_id => @id, :suite_id => @suite_id, :name => args[:name] )
49
+ end
50
+
51
+ def find_section( args )
52
+ name = args[:name] or raise "Need to provide the sub-section name (:name => 'subsection01')"
53
+ sub_sections.select{ |s| s.name == name }.first
54
+ end
55
+
56
+ def find_or_create_section( args )
57
+ name = args[:name] or raise "Need to provide the sub-section name (:name => 'subsection01')"
58
+ section = self.find_section( args )
59
+ if section.nil?
60
+ section = add_section( args )
61
+ end
62
+ section
63
+ end
64
+ end
65
+ end
@@ -0,0 +1,44 @@
1
+ module TestRail
2
+ class Suite
3
+ include Virtus.model
4
+ include InitializeWithApi
5
+
6
+ attribute :id
7
+ attribute :name
8
+ attribute :description
9
+ attribute :project_id
10
+ attribute :url
11
+
12
+ # Save changes made to this object back in testrail
13
+ # suite.description = "New description"
14
+ # suite.update
15
+ def update
16
+ @api.update_suite( :id => @id, :name => @name, :description => @description)
17
+ end
18
+
19
+ # Get a list of sections for this suite
20
+ def sections
21
+ sections = @api.get_sections( :project_id => @project_id, :suite_id => @id )
22
+ sections.reject{ |s| s.parent_id != nil }
23
+ end
24
+
25
+ # suite.add_section( :name => 'Section name )
26
+ def add_section( args)
27
+ @api.add_section( :project_id => project_id, :suite_id => @id, :name => args[:name] )
28
+ end
29
+
30
+ def find_section( args )
31
+ name = args[:name] or raise "Need to provide the section name"
32
+ sections.select{ |s| s.name == name }.first
33
+ end
34
+
35
+ def find_or_create_section( args )
36
+ name = args[:name] or raise "Need to provide the section name"
37
+ section = self.find_section( args )
38
+ if section.nil?
39
+ section = add_section( args )
40
+ end
41
+ section
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,18 @@
1
+ module TestRail
2
+ class Test
3
+ include Virtus.model
4
+
5
+ attribute :id
6
+ attribute :case_id
7
+ attribute :status_id
8
+ attribute :assignedto_id
9
+ attribute :run_id
10
+ attribute :title
11
+ attribute :type_id
12
+ attribute :priority_id
13
+ attribute :estimate
14
+ attribute :estimate_forcast
15
+ attribute :custom_steps
16
+
17
+ end
18
+ end
@@ -0,0 +1,27 @@
1
+ module TestRail
2
+ class TestCase
3
+ include Virtus.model
4
+ include InitializeWithApi
5
+
6
+ attribute :id
7
+ attribute :title
8
+ attribute :type_id
9
+ attribute :priority_id
10
+ attribute :estimate
11
+ attribute :milestone_id
12
+ attribute :refs
13
+ attribute :url
14
+
15
+ # Save changes made to this object back in testrail
16
+ def update
17
+ @api.update_case( :case_id => @id, :title => @title )
18
+ end
19
+
20
+ def add_result( args )
21
+ run_id = args[:run_id] or raise "Need to provide a run ID to store result against"
22
+ status = args[:status] or raise "Need to provide a result status (e.g. :status => :passed)"
23
+ version = args[:version]
24
+ @api.add_result_for_case( :case_id => id, :run_id => run_id, :status => status, :version => version )
25
+ end
26
+ end
27
+ end
metadata ADDED
@@ -0,0 +1,116 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: test_rail-api
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.4.0
5
+ platform: ruby
6
+ authors:
7
+ - BBC
8
+ - David Buckhurst
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2014-05-05 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: json
16
+ requirement: !ruby/object:Gem::Requirement
17
+ requirements:
18
+ - - "~>"
19
+ - !ruby/object:Gem::Version
20
+ version: '1.0'
21
+ type: :runtime
22
+ prerelease: false
23
+ version_requirements: !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - "~>"
26
+ - !ruby/object:Gem::Version
27
+ version: '1.0'
28
+ - !ruby/object:Gem::Dependency
29
+ name: virtus
30
+ requirement: !ruby/object:Gem::Requirement
31
+ requirements:
32
+ - - "~>"
33
+ - !ruby/object:Gem::Version
34
+ version: '1.0'
35
+ type: :runtime
36
+ prerelease: false
37
+ version_requirements: !ruby/object:Gem::Requirement
38
+ requirements:
39
+ - - "~>"
40
+ - !ruby/object:Gem::Version
41
+ version: '1.0'
42
+ - !ruby/object:Gem::Dependency
43
+ name: rspec
44
+ requirement: !ruby/object:Gem::Requirement
45
+ requirements:
46
+ - - "~>"
47
+ - !ruby/object:Gem::Version
48
+ version: '2.14'
49
+ type: :development
50
+ prerelease: false
51
+ version_requirements: !ruby/object:Gem::Requirement
52
+ requirements:
53
+ - - "~>"
54
+ - !ruby/object:Gem::Version
55
+ version: '2.14'
56
+ - !ruby/object:Gem::Dependency
57
+ name: faker
58
+ requirement: !ruby/object:Gem::Requirement
59
+ requirements:
60
+ - - "~>"
61
+ - !ruby/object:Gem::Version
62
+ version: '1.0'
63
+ type: :development
64
+ prerelease: false
65
+ version_requirements: !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - "~>"
68
+ - !ruby/object:Gem::Version
69
+ version: '1.0'
70
+ description: Ruby Client for v2 TestRail API
71
+ email: david.buckhurst@bbc.co.uk
72
+ executables: []
73
+ extensions: []
74
+ extra_rdoc_files: []
75
+ files:
76
+ - LICENSE
77
+ - lib/test_rail.rb
78
+ - lib/test_rail/api.rb
79
+ - lib/test_rail/case_type.rb
80
+ - lib/test_rail/configuration.rb
81
+ - lib/test_rail/initialize_with_api.rb
82
+ - lib/test_rail/plan.rb
83
+ - lib/test_rail/priority.rb
84
+ - lib/test_rail/project.rb
85
+ - lib/test_rail/result.rb
86
+ - lib/test_rail/run.rb
87
+ - lib/test_rail/section.rb
88
+ - lib/test_rail/suite.rb
89
+ - lib/test_rail/test.rb
90
+ - lib/test_rail/test_case.rb
91
+ homepage: https://github.com/bbc/test_rail-api
92
+ licenses:
93
+ - MIT
94
+ metadata: {}
95
+ post_install_message:
96
+ rdoc_options: []
97
+ require_paths:
98
+ - lib
99
+ required_ruby_version: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ required_rubygems_version: !ruby/object:Gem::Requirement
105
+ requirements:
106
+ - - ">="
107
+ - !ruby/object:Gem::Version
108
+ version: '0'
109
+ requirements: []
110
+ rubyforge_project:
111
+ rubygems_version: 2.4.8
112
+ signing_key:
113
+ specification_version: 4
114
+ summary: Test Rail API
115
+ test_files: []
116
+ has_rdoc: