testrail-api-module 0.1.0__tar.gz

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.
Files changed (37) hide show
  1. testrail_api_module-0.1.0/LICENSE +21 -0
  2. testrail_api_module-0.1.0/PKG-INFO +10 -0
  3. testrail_api_module-0.1.0/README.md +9 -0
  4. testrail_api_module-0.1.0/pyproject.toml +21 -0
  5. testrail_api_module-0.1.0/setup.cfg +4 -0
  6. testrail_api_module-0.1.0/src/testrail_api_module/__init__.py +57 -0
  7. testrail_api_module-0.1.0/src/testrail_api_module/_common.py +115 -0
  8. testrail_api_module-0.1.0/src/testrail_api_module/attachments.py +187 -0
  9. testrail_api_module-0.1.0/src/testrail_api_module/bdd.py +34 -0
  10. testrail_api_module-0.1.0/src/testrail_api_module/case_fields.py +42 -0
  11. testrail_api_module-0.1.0/src/testrail_api_module/case_types.py +4 -0
  12. testrail_api_module-0.1.0/src/testrail_api_module/cases.py +229 -0
  13. testrail_api_module-0.1.0/src/testrail_api_module/configurations.py +4 -0
  14. testrail_api_module-0.1.0/src/testrail_api_module/datasets.py +4 -0
  15. testrail_api_module-0.1.0/src/testrail_api_module/groups.py +4 -0
  16. testrail_api_module-0.1.0/src/testrail_api_module/milestones.py +4 -0
  17. testrail_api_module-0.1.0/src/testrail_api_module/plans.py +4 -0
  18. testrail_api_module-0.1.0/src/testrail_api_module/priorities.py +4 -0
  19. testrail_api_module-0.1.0/src/testrail_api_module/projects.py +4 -0
  20. testrail_api_module-0.1.0/src/testrail_api_module/reports.py +4 -0
  21. testrail_api_module-0.1.0/src/testrail_api_module/result_fields.py +4 -0
  22. testrail_api_module-0.1.0/src/testrail_api_module/results.py +91 -0
  23. testrail_api_module-0.1.0/src/testrail_api_module/roles.py +4 -0
  24. testrail_api_module-0.1.0/src/testrail_api_module/runs.py +4 -0
  25. testrail_api_module-0.1.0/src/testrail_api_module/sections.py +4 -0
  26. testrail_api_module-0.1.0/src/testrail_api_module/shared_steps.py +4 -0
  27. testrail_api_module-0.1.0/src/testrail_api_module/statuses.py +4 -0
  28. testrail_api_module-0.1.0/src/testrail_api_module/suites.py +4 -0
  29. testrail_api_module-0.1.0/src/testrail_api_module/templates.py +4 -0
  30. testrail_api_module-0.1.0/src/testrail_api_module/tests.py +41 -0
  31. testrail_api_module-0.1.0/src/testrail_api_module/users.py +4 -0
  32. testrail_api_module-0.1.0/src/testrail_api_module/variables.py +4 -0
  33. testrail_api_module-0.1.0/src/testrail_api_module.egg-info/PKG-INFO +10 -0
  34. testrail_api_module-0.1.0/src/testrail_api_module.egg-info/SOURCES.txt +35 -0
  35. testrail_api_module-0.1.0/src/testrail_api_module.egg-info/dependency_links.txt +1 -0
  36. testrail_api_module-0.1.0/src/testrail_api_module.egg-info/requires.txt +1 -0
  37. testrail_api_module-0.1.0/src/testrail_api_module.egg-info/top_level.txt +1 -0
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Matt Troutman
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.
@@ -0,0 +1,10 @@
1
+ Metadata-Version: 2.4
2
+ Name: testrail_api_module
3
+ Version: 0.1.0
4
+ Summary: A simple wrapper for the TestRail API
5
+ Author: Christian Thompson
6
+ Author-email: Matt Troutman <github@trtmn.com>
7
+ Project-URL: Homepage, https://github.com/trtmn/testrail_api_module
8
+ License-File: LICENSE
9
+ Requires-Dist: requests
10
+ Dynamic: license-file
@@ -0,0 +1,9 @@
1
+ # testrail_api_module
2
+
3
+ A simple wrapper for the TestRail API.
4
+
5
+ ## Description
6
+
7
+ This project provides a simple and easy-to-use wrapper for the TestRail API, allowing you to interact with TestRail programmatically.
8
+
9
+ ## •further usage info goes here•
@@ -0,0 +1,21 @@
1
+ [build-system]
2
+ requires = ["setuptools", "wheel"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "testrail_api_module"
7
+ version = "0.1.0"
8
+ description = "A simple wrapper for the TestRail API"
9
+ authors = [
10
+ { name = "Matt Troutman", email = "github@trtmn.com" },
11
+ { name = "Christian Thompson"}
12
+ ]
13
+ dependencies = [
14
+ "requests",
15
+ ]
16
+
17
+ [tool.setuptools.packages.find]
18
+ where = ["src"]
19
+
20
+ [project.urls]
21
+ Homepage = "https://github.com/trtmn/testrail_api_module"
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,57 @@
1
+ # src/testrail_api_module/__init__.py
2
+ """
3
+ This package provides functionalities to interact with the TestRail API, including managing attachments, cases, tests, and results.
4
+
5
+ Attributes:
6
+ __version__ (str): The version of the package.
7
+ __author__ (str): The authors of the package.
8
+ __all__ (list): A list of modules to be imported when `from testrail_api_module import *` is used.
9
+ """
10
+ import os
11
+ __version__ = '0.1.0'
12
+ __author__ = 'Matt Troutman / Christian Thompson'
13
+ package_version = __version__
14
+ """The version of the package, used for compatibility checks and logging."""
15
+
16
+ authors = __author__
17
+ """authors of the package, used for documentation and attribution."""
18
+
19
+ # Import all modules in the package
20
+ __all__ = [
21
+ '_common',
22
+ 'attachments',
23
+ 'bdd',
24
+ 'case_fields',
25
+ 'case_types',
26
+ 'cases',
27
+ 'configurations',
28
+ 'datasets',
29
+ 'groups',
30
+ 'milestones',
31
+ 'plans',
32
+ 'priorities',
33
+ 'projects',
34
+ 'reports',
35
+ 'result_fields',
36
+ 'results',
37
+ 'roles',
38
+ 'runs',
39
+ 'sections',
40
+ 'shared_steps',
41
+ 'statuses',
42
+ 'suites',
43
+ 'templates',
44
+ 'tests',
45
+ 'users',
46
+ 'variables'
47
+ ]
48
+
49
+ def __import_all_modules__():
50
+ for _x in __all__:
51
+ _local_name = f".{_x}"
52
+ exec(f"from {_local_name} import *", globals())
53
+
54
+ __import_all_modules__()
55
+ del __import_all_modules__
56
+
57
+
@@ -0,0 +1,115 @@
1
+ """
2
+ `_common.py` serves as a foundational module for the TestRail API package, providing a base class for API requests and a function to set API credentials.
3
+ """
4
+ import requests
5
+ import json
6
+
7
+
8
+ import os
9
+
10
+ def set_testrail_api_credentials(baseurl=None, username=None, password=None):
11
+ """
12
+ Set the TestRail API credentials as environment variables.
13
+
14
+ Args:
15
+ baseurl (str): The base URL for the TestRail API.
16
+ username (str): The username for TestRail API authentication.
17
+ password (str): The password for TestRail API authentication.
18
+ """
19
+ if baseurl is not None:
20
+ os.environ["TESTRAIL_API_BASEURL"] = baseurl
21
+ if username is not None:
22
+ os.environ["TESTRAIL_API_USERNAME"] = username
23
+ if password is not None:
24
+ os.environ["TESTRAIL_API_PASSWORD"] = password
25
+
26
+ def get_testrail_api_credentials():
27
+ """
28
+ Get the TestRail API credentials from environment variables.
29
+
30
+ Returns:
31
+ tuple: A tuple containing the baseurl, username, and password.
32
+
33
+ Raises:
34
+ ValueError: If any of the required credentials are not set.
35
+ """
36
+ baseurl = os.getenv("TESTRAIL_API_BASEURL")
37
+ username = os.getenv("TESTRAIL_API_USERNAME")
38
+ password = os.getenv("TESTRAIL_API_PASSWORD")
39
+
40
+ if baseurl is None:
41
+ raise ValueError("The base URL for the TestRail API is required. Set it as an environment variable or pass it as an argument.")
42
+ if username is None:
43
+ raise ValueError("The username for TestRail API authentication is required. Set it as an environment variable or pass it as an argument.")
44
+ if password is None:
45
+ raise ValueError("The password for TestRail API authentication is required. Set it as an environment variable or pass it as an argument.")
46
+
47
+ return baseurl, username, password
48
+
49
+ class ApiConstructor:
50
+ """
51
+ A class to construct and make API requests to TestRail.
52
+ """
53
+
54
+ def __init__(self) -> object:
55
+ """
56
+ Initializes the ApiConstructor with default values for run_id, case_id, project_id,
57
+ baseurl, username, and password.
58
+ """
59
+ self.run_id = None # Actual run id in demo project
60
+ """The run ID for the TestRail run. This is required."""
61
+
62
+ self.case_id = None # Actual case id in demo project
63
+ """The case ID for the TestRail case. This is required."""
64
+
65
+ self.project_id = None
66
+ """The project ID for the TestRail project. This is required."""
67
+
68
+ self.baseurl = get_testrail_api_credentials()[0] #Required!
69
+ """The base URL for the TestRail API (e.g., "https://your_testrail_instance.testrail.io"). This is required.
70
+ Can be set in the constructor or as an environment variable.
71
+ use testrail_api_module._common.set_testrail_api_credentials()"""
72
+
73
+ self.username = get_testrail_api_credentials()[1] #Required!
74
+ """The username for TestRail API authentication. This is required.
75
+ Can be set in the constructor or as an environment variable.
76
+ use testrail_api_module._common.set_testrail_api_credentials()"""
77
+
78
+ self.password = get_testrail_api_credentials()[2] #Required!
79
+ """The password for TestRail API authentication. This is required.
80
+ Can be set in the constructor or as an environment variable.
81
+ use testrail_api_module._common.set_testrail_api_credentials()"""
82
+
83
+ def api_request(self, method, endpoint, data=None):
84
+ """
85
+ Make an API request to TestRail.
86
+
87
+ Args:
88
+ method (str): The HTTP method to use for the request (e.g., 'GET', 'POST').
89
+ endpoint (str): The API endpoint to send the request to.
90
+ data (dict, optional): The data to send with the request, if any.
91
+
92
+ Returns:
93
+ dict: The JSON response from the API if the request is successful.
94
+ None: If the request fails.
95
+ """
96
+ # Confirm that all 3 required variables are set
97
+ if not self.baseurl:
98
+ raise ValueError("The base URL for the TestRail API is required. See documentation for more info")
99
+ if not self.username:
100
+ raise ValueError("The username for TestRail API authentication is required. See documentation for more info")
101
+ if not self.password:
102
+ raise ValueError("The password for TestRail API authentication is required. See documentation for more info")
103
+
104
+ url = f"{self.baseurl}/index.php?/api/v2/{endpoint}"
105
+ headers = {"Content-Type": "application/json"}
106
+ response = requests.request(method, url, headers=headers, data=json.dumps(data), auth=(self.username, self.password))
107
+ if response.status_code == 200:
108
+ return response.json()
109
+ else:
110
+ print(f"Failed to {method} {endpoint}. Response:", response.text)
111
+ return None
112
+
113
+ if __name__ == '__main__':
114
+ set_testrail_api_credentials(baseurl="https://your_testrail_instance.testrail.io", username="your_username", password="your_password")
115
+ print(get_testrail_api_credentials())
@@ -0,0 +1,187 @@
1
+ from . import _common
2
+ _api = _common.ApiConstructor()
3
+ """
4
+ This module provides functionalities to interact with attachments in TestRail.
5
+ """
6
+
7
+
8
+ def add_attachment_to_case(case_id, file_path):
9
+ """
10
+ Add an attachment to a specific test case.
11
+
12
+ Args:
13
+ case_id (str): The ID of the test case.
14
+ file_path (str): The path to the file to be attached.
15
+
16
+ Returns:
17
+ dict: The response from the API.
18
+ """
19
+ files = {'attachment': open(file_path, 'rb')}
20
+ headers = {'Content-Type': 'multipart/form-data'}
21
+ response = _api.api_request('POST', f'add_attachment_to_case/{case_id}', files=files, headers=headers)
22
+ return response
23
+
24
+ def add_attachment_to_plan(plan_id, file_path):
25
+ """
26
+ Add an attachment to a specific test plan.
27
+
28
+ Args:
29
+ plan_id (str): The ID of the test plan.
30
+ file_path (str): The path to the file to be attached.
31
+
32
+ Returns:
33
+ dict: The response from the API.
34
+ """
35
+ files = {'attachment': open(file_path, 'rb')}
36
+ headers = {'Content-Type': 'multipart/form-data'}
37
+ response = _api.api_request('POST', f'add_attachment_to_plan/{plan_id}', files=files, headers=headers)
38
+ return response
39
+
40
+ def add_attachment_to_plan_entry(plan_id, entry_id, file_path):
41
+ """
42
+ Add an attachment to a specific test plan entry.
43
+
44
+ Args:
45
+ plan_id (str): The ID of the test plan.
46
+ entry_id (str): The ID of the test plan entry.
47
+ file_path (str): The path to the file to be attached.
48
+
49
+ Returns:
50
+ dict: The response from the API.
51
+ """
52
+ files = {'attachment': open(file_path, 'rb')}
53
+ headers = {'Content-Type': 'multipart/form-data'}
54
+ response = _api.api_request('POST', f'add_attachment_to_plan_entry/{plan_id}/{entry_id}', files=files, headers=headers)
55
+ return response
56
+
57
+ def add_attachment_to_result(result_id, file_path):
58
+ """
59
+ Add an attachment to a specific test result.
60
+
61
+ Args:
62
+ result_id (str): The ID of the test result.
63
+ file_path (str): The path to the file to be attached.
64
+
65
+ Returns:
66
+ dict: The response from the API.
67
+ """
68
+ files = {'attachment': open(file_path, 'rb')}
69
+ headers = {'Content-Type': 'multipart/form-data'}
70
+ response = _api.api_request('POST', f'add_attachment_to_result/{result_id}', files=files, headers=headers)
71
+ return response
72
+
73
+ def add_attachment_to_run(run_id, file_path):
74
+ """
75
+ Add an attachment to a specific test run.
76
+
77
+ Args:
78
+ run_id (str): The ID of the test run.
79
+ file_path (str): The path to the file to be attached.
80
+
81
+ Returns:
82
+ dict: The response from the API.
83
+ """
84
+ files = {'attachment': open(file_path, 'rb')}
85
+ headers = {'Content-Type': 'multipart/form-data'}
86
+ response = _api.api_request('POST', f'add_attachment_to_run/{run_id}', files=files, headers=headers)
87
+ return response
88
+
89
+ def get_attachments_for_case(case_id, limit=250, offset=0):
90
+ """
91
+ Get all attachments for a specific test case.
92
+
93
+ Args:
94
+ case_id (str): The ID of the test case.
95
+ limit (int, optional): The maximum number of attachments to return (default is 250).
96
+ offset (int, optional): The number of attachments to skip before starting to collect the result set (default is 0).
97
+
98
+ Returns:
99
+ dict: The response from the API.
100
+ """
101
+ response = _api.api_request('GET', f'get_attachments_for_case/{case_id}&limit={limit}&offset={offset}')
102
+ return response
103
+
104
+ def get_attachments_for_plan(plan_id, limit=250, offset=0):
105
+ """
106
+ Get all attachments for a specific test plan.
107
+
108
+ Args:
109
+ plan_id (str): The ID of the test plan.
110
+ limit (int, optional): The maximum number of attachments to return (default is 250).
111
+ offset (int, optional): The number of attachments to skip before starting to collect the result set (default is 0).
112
+
113
+ Returns:
114
+ dict: The response from the API.
115
+ """
116
+ response = _api.api_request('GET', f'get_attachments_for_plan/{plan_id}&limit={limit}&offset={offset}')
117
+ return response
118
+
119
+ def get_attachments_for_plan_entry(plan_id, entry_id, limit=250, offset=0):
120
+ """
121
+ Get all attachments for a specific test plan entry.
122
+
123
+ Args:
124
+ plan_id (str): The ID of the test plan.
125
+ entry_id (str): The ID of the test plan entry.
126
+ limit (int, optional): The maximum number of attachments to return (default is 250).
127
+ offset (int, optional): The number of attachments to skip before starting to collect the result set (default is 0).
128
+
129
+ Returns:
130
+ dict: The response from the API.
131
+ """
132
+ response = _api.api_request('GET', f'get_attachments_for_plan_entry/{plan_id}/{entry_id}&limit={limit}&offset={offset}')
133
+ return response
134
+
135
+ def get_attachments_for_run(run_id, limit=250, offset=0):
136
+ """
137
+ Get all attachments for a specific test run.
138
+
139
+ Args:
140
+ run_id (str): The ID of the test run.
141
+ limit (int, optional): The maximum number of attachments to return (default is 250).
142
+ offset (int, optional): The number of attachments to skip before starting to collect the result set (default is 0).
143
+
144
+ Returns:
145
+ dict: The response from the API.
146
+ """
147
+ response = _api.api_request('GET', f'get_attachments_for_run/{run_id}?limit={limit}&offset={offset}')
148
+ return response
149
+
150
+ def get_attachments_for_test(test_id):
151
+ """
152
+ Get all attachments for a specific test.
153
+
154
+ Args:
155
+ test_id (str): The ID of the test.
156
+
157
+ Returns:
158
+ dict: The response from the API.
159
+ """
160
+ response = _api.api_request('GET', f'get_attachments_for_test/{test_id}')
161
+ return response
162
+
163
+ def get_attachment(attachment_id):
164
+ """
165
+ Get details of a specific attachment.
166
+
167
+ Args:
168
+ attachment_id (str): The ID of the attachment.
169
+
170
+ Returns:
171
+ dict: The response from the API.
172
+ """
173
+ response = _api.api_request('GET', f'get_attachment/{attachment_id}')
174
+ return response
175
+
176
+ def delete_attachment(attachment_id):
177
+ """
178
+ Delete a specific attachment.
179
+
180
+ Args:
181
+ attachment_id (str): The ID of the attachment.
182
+
183
+ Returns:
184
+ dict: The response from the API.
185
+ """
186
+ response = _api.api_request('POST', f'delete_attachment/{attachment_id}')
187
+ return response
@@ -0,0 +1,34 @@
1
+ from . import _common
2
+ _api = _common.ApiConstructor()
3
+ """
4
+ This module provides functionalities to interact with BDD scenarios in TestRail.
5
+ """
6
+
7
+ def get_bdd(case_id):
8
+ """
9
+ Export a BDD scenario from a test case as a .feature file.
10
+
11
+ Args:
12
+ case_id (int): The ID of the test case.
13
+
14
+ Returns:
15
+ dict: The response from the API.
16
+ """
17
+ return _api.api_request('GET', f'get_bdd/{case_id}')
18
+
19
+ def add_bdd(section_id, feature_file):
20
+ """
21
+ Import/upload a BDD scenario from a test case as a .feature file.
22
+
23
+ Args:
24
+ section_id (int): The ID of the section.
25
+ feature_file (str): The path to the .feature file.
26
+
27
+ Returns:
28
+ dict: The response from the API.
29
+ """
30
+ with open(feature_file, 'r') as file:
31
+ data = {
32
+ "file": file.read()
33
+ }
34
+ return _api.api_request('POST', f'add_bdd/{section_id}', data)
@@ -0,0 +1,42 @@
1
+ # src/testrail_api_module/case_fields.py
2
+ """
3
+ This module provides functionalities to interact with test case fields in TestRail.
4
+ """
5
+ from . import _common
6
+ _api = _common.ApiConstructor()
7
+
8
+ def get_case_fields():
9
+ """
10
+ Get all available test case fields.
11
+
12
+ Returns:
13
+ list: A list of dictionaries containing the details of each test case field.
14
+ """
15
+ return _api.api_request('GET', 'get_case_fields')
16
+
17
+ def add_case_field(field_type, name, label, description=None, include_all=False, template_ids=None, configs=None):
18
+ """
19
+ Create a new test case custom field.
20
+
21
+ Args:
22
+ field_type (str): The type identifier for the new custom field.
23
+ name (str): The name for the new custom field.
24
+ label (str): The label for the new custom field.
25
+ description (str, optional): The description for the new custom field.
26
+ include_all (bool, optional): Flag to include the new custom field for all templates.
27
+ template_ids (list, optional): IDs of templates the new custom field will apply to if include_all is False.
28
+ configs (list, optional): A list of configuration objects for the new custom field.
29
+
30
+ Returns:
31
+ dict: The response from the API.
32
+ """
33
+ data = {
34
+ "type": field_type,
35
+ "name": name,
36
+ "label": label,
37
+ "description": description,
38
+ "include_all": include_all,
39
+ "template_ids": template_ids,
40
+ "configs": configs
41
+ }
42
+ return _api.api_request('POST', 'add_case_field', data)
@@ -0,0 +1,4 @@
1
+ """
2
+ This hasn't been implemented yet.
3
+
4
+ """
@@ -0,0 +1,229 @@
1
+ from . import _common
2
+ _api = _common.ApiConstructor()
3
+
4
+
5
+ def add_case(section_id, title, template_id=None, type_id=None, priority_id=None, estimate=None, milestone_id=None, refs=None):
6
+ """
7
+ Add a new test case to a specific section.
8
+
9
+ Args:
10
+ section_id (str): The ID of the section.
11
+ title (str): The title of the test case.
12
+ template_id (int, optional): The ID of the template.
13
+ type_id (int, optional): The ID of the type.
14
+ priority_id (int, optional): The ID of the priority.
15
+ estimate (str, optional): The estimate for the test case.
16
+ milestone_id (int, optional): The ID of the milestone.
17
+ refs (str, optional): A comma-separated list of references.
18
+
19
+ Returns:
20
+ dict: The response from the API.
21
+ """
22
+ data = {
23
+ "title": title,
24
+ "template_id": template_id,
25
+ "type_id": type_id,
26
+ "priority_id": priority_id,
27
+ "estimate": estimate,
28
+ "milestone_id": milestone_id,
29
+ "refs": refs
30
+ }
31
+ return _api.api_request('POST', f'add_case/{section_id}', data)
32
+
33
+ def get_case(case_id):
34
+ """
35
+ Get details of a specific test case.
36
+
37
+ Args:
38
+ case_id (str): The ID of the test case.
39
+
40
+ Returns:
41
+ dict: The response from the API.
42
+ """
43
+ return _api.api_request('GET', f'get_case/{case_id}')
44
+
45
+ def get_cases(project_id, suite_id=None, section_id=None, filters=None):
46
+ """
47
+ Get all test cases for a specific project, optionally filtered by suite, section, and other filters.
48
+
49
+ Args:
50
+ project_id (str): The ID of the project.
51
+ suite_id (str, optional): The ID of the suite.
52
+ section_id (str, optional): The ID of the section.
53
+ filters (dict, optional): Additional filters for the request.
54
+
55
+ Returns:
56
+ list: A list of dictionaries containing the details of each test case.
57
+ """
58
+ endpoint = f'get_cases/{project_id}'
59
+ if suite_id:
60
+ endpoint += f'&suite_id={suite_id}'
61
+ if section_id:
62
+ endpoint += f'&section_id={section_id}'
63
+ if filters:
64
+ for key, value in filters.items():
65
+ endpoint += f'&{key}={value}'
66
+ return _api.api_request('GET', endpoint)
67
+
68
+ def update_case(case_id, title=None, template_id=None, type_id=None, priority_id=None, estimate=None, milestone_id=None, refs=None):
69
+ """
70
+ Update an existing test case.
71
+
72
+ Args:
73
+ case_id (str): The ID of the test case.
74
+ title (str, optional): The title of the test case.
75
+ template_id (int, optional): The ID of the template.
76
+ type_id (int, optional): The ID of the type.
77
+ priority_id (int, optional): The ID of the priority.
78
+ estimate (str, optional): The estimate for the test case.
79
+ milestone_id (int, optional): The ID of the milestone.
80
+ refs (str, optional): A comma-separated list of references.
81
+
82
+ Returns:
83
+ dict: The response from the API.
84
+ """
85
+ data = {
86
+ "title": title,
87
+ "template_id": template_id,
88
+ "type_id": type_id,
89
+ "priority_id": priority_id,
90
+ "estimate": estimate,
91
+ "milestone_id": milestone_id,
92
+ "refs": refs
93
+ }
94
+ return _api.api_request('POST', f'update_case/{case_id}', data)
95
+
96
+ def delete_case(case_id):
97
+ """
98
+ Delete a specific test case.
99
+
100
+ Args:
101
+ case_id (str): The ID of the test case.
102
+
103
+ Returns:
104
+ dict: The response from the API.
105
+ """
106
+ return _api.api_request('POST', f'delete_case/{case_id}')
107
+
108
+ def get_case_fields():
109
+ """
110
+ Get all available test case fields.
111
+
112
+ Returns:
113
+ list: A list of dictionaries containing the details of each test case field.
114
+ """
115
+ return _api.api_request('GET', 'get_case_fields')
116
+
117
+ def get_case_types():
118
+ """
119
+ Get all available test case types.
120
+
121
+ Returns:
122
+ list: A list of dictionaries containing the details of each test case type.
123
+ """
124
+ return _api.api_request('GET', 'get_case_types')
125
+
126
+ def get_history_for_case(case_id, limit=None, offset=None):
127
+ """
128
+ Get the history for a specific test case.
129
+
130
+ Args:
131
+ case_id (str): The ID of the test case.
132
+ limit (int, optional): The maximum number of history entries to return.
133
+ offset (int, optional): The number of history entries to skip before starting to collect the result set.
134
+
135
+ Returns:
136
+ list: A list of dictionaries containing the history of the test case.
137
+ """
138
+ endpoint = f'get_history_for_case/{case_id}'
139
+ if limit:
140
+ endpoint += f'&limit={limit}'
141
+ if offset:
142
+ endpoint += f'&offset={offset}'
143
+ return _api.api_request('GET', endpoint)
144
+
145
+ def copy_cases_to_section(section_id, case_ids=None):
146
+ """
147
+ Copy test cases to a specific section.
148
+
149
+ Args:
150
+ section_id (str): The ID of the section.
151
+ case_ids (list, optional): A list of test case IDs to copy.
152
+
153
+ Returns:
154
+ dict: The response from the API.
155
+ """
156
+ data = {
157
+ "case_ids": case_ids
158
+ }
159
+ return _api.api_request('POST', f'copy_cases_to_section/{section_id}', data)
160
+
161
+ def update_cases(suite_id, case_ids, section_id=None, title=None, template_id=None, type_id=None, priority_id=None, estimate=None, milestone_id=None, refs=None):
162
+ """
163
+ Update multiple test cases.
164
+
165
+ Args:
166
+ suite_id (str): The ID of the suite.
167
+ case_ids (list): A list of test case IDs to update.
168
+ section_id (str, optional): The ID of the section.
169
+ title (str, optional): The title of the test cases.
170
+ template_id (int, optional): The ID of the template.
171
+ type_id (int, optional): The ID of the type.
172
+ priority_id (int, optional): The ID of the priority.
173
+ estimate (str, optional): The estimate for the test cases.
174
+ milestone_id (int, optional): The ID of the milestone.
175
+ refs (str, optional): A comma-separated list of references.
176
+
177
+ Returns:
178
+ dict: The response from the API.
179
+ """
180
+ data = {
181
+ "case_ids": case_ids,
182
+ "section_id": section_id,
183
+ "title": title,
184
+ "template_id": template_id,
185
+ "type_id": type_id,
186
+ "priority_id": priority_id,
187
+ "estimate": estimate,
188
+ "milestone_id": milestone_id,
189
+ "refs": refs
190
+ }
191
+ return _api.api_request('POST', f'update_cases/{suite_id}', data)
192
+
193
+ def move_cases_to_section(section_id, suite_id, case_ids):
194
+ """
195
+ Move test cases to a specific section.
196
+
197
+ Args:
198
+ section_id (str): The ID of the section.
199
+ suite_id (str): The ID of the suite.
200
+ case_ids (list): A list of test case IDs to move.
201
+
202
+ Returns:
203
+ dict: The response from the API.
204
+ """
205
+ data = {
206
+ "suite_id": suite_id,
207
+ "case_ids": case_ids
208
+ }
209
+ return _api.api_request('POST', f'move_cases_to_section/{section_id}', data)
210
+
211
+ def delete_cases(suite_id, case_ids, project_id, soft=0):
212
+ """
213
+ Delete multiple test cases.
214
+
215
+ Args:
216
+ suite_id (str): The ID of the suite.
217
+ case_ids (list): A list of test case IDs to delete.
218
+ project_id (str): The ID of the project.
219
+ soft (int, optional): Whether to perform a soft delete (default is 0).
220
+
221
+ Returns:
222
+ dict: The response from the API.
223
+ """
224
+ data = {
225
+ "case_ids": case_ids,
226
+ "project_id": project_id,
227
+ "soft": soft
228
+ }
229
+ return _api.api_request('POST', f'delete_cases/{suite_id}', data)
@@ -0,0 +1,4 @@
1
+ """
2
+ This hasn't been implemented yet.
3
+
4
+ """
@@ -0,0 +1,4 @@
1
+ """
2
+ This hasn't been implemented yet.
3
+
4
+ """
@@ -0,0 +1,4 @@
1
+ """
2
+ This hasn't been implemented yet.
3
+
4
+ """
@@ -0,0 +1,4 @@
1
+ """
2
+ This hasn't been implemented yet.
3
+
4
+ """
@@ -0,0 +1,4 @@
1
+ """
2
+ This hasn't been implemented yet.
3
+
4
+ """
@@ -0,0 +1,4 @@
1
+ """
2
+ This hasn't been implemented yet.
3
+
4
+ """
@@ -0,0 +1,4 @@
1
+ """
2
+ This hasn't been implemented yet.
3
+
4
+ """
@@ -0,0 +1,4 @@
1
+ """
2
+ This hasn't been implemented yet.
3
+
4
+ """
@@ -0,0 +1,4 @@
1
+ """
2
+ This hasn't been implemented yet.
3
+
4
+ """
@@ -0,0 +1,91 @@
1
+ import logging as _logging
2
+ from . import _common
3
+ _api = _common.ApiConstructor()
4
+
5
+ # Print initializing message for file_name
6
+ print("{0} is initializing...".format(__file__))
7
+
8
+ def add(run_id=None, case_id=None, status_id=None, comment=None, version=None, elapsed=None, defects=None, assignedto_id=None):
9
+ """
10
+ Add a test result for a specific test case in a test run.
11
+
12
+ Args:
13
+ run_id (str): The ID of the test run.
14
+ case_id (str): The ID of the test case.
15
+ status_id (int): The status ID of the test result.
16
+ comment (str): A comment for the test result.
17
+ version (str): The version of the software under test.
18
+ elapsed (str): The time taken to execute the test.
19
+ defects (str): A comma-separated list of defects.
20
+ assignedto_id (int): The ID of the user the test is assigned to.
21
+
22
+ Returns:
23
+ bool: True if the test result was added successfully, False otherwise.
24
+ """
25
+ data = {
26
+ "status_id": status_id,
27
+ "comment": comment,
28
+ "version": version,
29
+ "elapsed": elapsed,
30
+ "defects": defects,
31
+ "assignedto_id": assignedto_id
32
+ }
33
+ response = _api.api_request('POST', f'add_result_for_case/{run_id}/{case_id}', data)
34
+ print("Test result added successfully." if response else "Failed to add test result.")
35
+ if response is not None:
36
+ _logging.info(f"Test result added successfully. Response: {response}")
37
+ return True
38
+ else:
39
+ _logging.error(f"Failed to add test result. Response: {response}")
40
+ return False
41
+
42
+ def get_plans(project_id):
43
+ """
44
+ Get all test plans for a specific project.
45
+
46
+ Args:
47
+ project_id (str): The ID of the project.
48
+
49
+ Returns:
50
+ list: A list of dictionaries containing the name, ID, and description of each test plan.
51
+ """
52
+ response = _api.api_request('GET', f'get_plans/{project_id}')
53
+ return [{"name": plan["name"], "id": plan["id"], "description": plan["description"]} for plan in response['plans']] if response else []
54
+
55
+ def get_run_ids_from_plan(plan_id):
56
+ """
57
+ Get all test run IDs from a specific test plan.
58
+
59
+ Args:
60
+ plan_id (str): The ID of the test plan.
61
+
62
+ Returns:
63
+ list: A list of dictionaries containing the name, ID, and description of each test run.
64
+ """
65
+ response = _api.api_request('GET', f'get_plan/{plan_id}')
66
+ return [{"name": run["name"], "id": run["id"], "description": run["description"]} for entry in response['entries'] for run in entry['runs']] if response else []
67
+
68
+ def get_run(run_id):
69
+ """
70
+ Get details of a specific test run.
71
+
72
+ Args:
73
+ run_id (str): The ID of the test run.
74
+
75
+ Returns:
76
+ dict: A dictionary containing the details of the test run.
77
+ """
78
+ return _api.api_request('GET', f'get_run/{run_id}')
79
+
80
+ def get_case_ids_from_run(run_id):
81
+ """
82
+ Get all test case IDs from a specific test run.
83
+
84
+ Args:
85
+ run_id (str): The ID of the test run.
86
+
87
+ Returns:
88
+ list: A list of test case IDs.
89
+ """
90
+ response = _api.api_request('GET', f'get_tests/{run_id}')
91
+ return [test['case_id'] for test in response['tests']] if response else []
@@ -0,0 +1,4 @@
1
+ """
2
+ This hasn't been implemented yet.
3
+
4
+ """
@@ -0,0 +1,4 @@
1
+ """
2
+ This hasn't been implemented yet.
3
+
4
+ """
@@ -0,0 +1,4 @@
1
+ """
2
+ This hasn't been implemented yet.
3
+
4
+ """
@@ -0,0 +1,4 @@
1
+ """
2
+ This hasn't been implemented yet.
3
+
4
+ """
@@ -0,0 +1,4 @@
1
+ """
2
+ This hasn't been implemented yet.
3
+
4
+ """
@@ -0,0 +1,4 @@
1
+ """
2
+ This hasn't been implemented yet.
3
+
4
+ """
@@ -0,0 +1,4 @@
1
+ """
2
+ This hasn't been implemented yet.
3
+
4
+ """
@@ -0,0 +1,41 @@
1
+ from . import _common
2
+ _api = _common.ApiConstructor()
3
+ """
4
+
5
+ """
6
+ # Print initializing message for file_name
7
+ print("{0} is initializing...".format(__file__))
8
+
9
+ def get_test(test_id):
10
+ """
11
+ Get details of a specific test.
12
+
13
+ Args:
14
+ test_id (str): The ID of the test.
15
+
16
+ Returns:
17
+ dict: A dictionary containing the details of the test.
18
+ """
19
+ return _api.api_request('GET', f'get_test/{test_id}')
20
+
21
+ def get_tests(run_id, status_id=None, limit=None, offset=None):
22
+ """
23
+ Get all tests for a specific test run, optionally filtered by status, limit, and offset.
24
+
25
+ Args:
26
+ run_id (str): The ID of the test run.
27
+ status_id (int, optional): The status ID to filter the tests.
28
+ limit (int, optional): The maximum number of tests to return.
29
+ offset (int, optional): The number of tests to skip before starting to collect the result set.
30
+
31
+ Returns:
32
+ list: A list of dictionaries containing the details of each test.
33
+ """
34
+ endpoint = f'get_tests/{run_id}'
35
+ if status_id:
36
+ endpoint += f'&status_id={status_id}'
37
+ if limit:
38
+ endpoint += f'&limit={limit}'
39
+ if offset:
40
+ endpoint += f'&offset={offset}'
41
+ return _api.api_request('GET', endpoint)
@@ -0,0 +1,4 @@
1
+ """
2
+ This hasn't been implemented yet.
3
+
4
+ """
@@ -0,0 +1,4 @@
1
+ """
2
+ This hasn't been implemented yet.
3
+
4
+ """
@@ -0,0 +1,10 @@
1
+ Metadata-Version: 2.4
2
+ Name: testrail_api_module
3
+ Version: 0.1.0
4
+ Summary: A simple wrapper for the TestRail API
5
+ Author: Christian Thompson
6
+ Author-email: Matt Troutman <github@trtmn.com>
7
+ Project-URL: Homepage, https://github.com/trtmn/testrail_api_module
8
+ License-File: LICENSE
9
+ Requires-Dist: requests
10
+ Dynamic: license-file
@@ -0,0 +1,35 @@
1
+ LICENSE
2
+ README.md
3
+ pyproject.toml
4
+ src/testrail_api_module/__init__.py
5
+ src/testrail_api_module/_common.py
6
+ src/testrail_api_module/attachments.py
7
+ src/testrail_api_module/bdd.py
8
+ src/testrail_api_module/case_fields.py
9
+ src/testrail_api_module/case_types.py
10
+ src/testrail_api_module/cases.py
11
+ src/testrail_api_module/configurations.py
12
+ src/testrail_api_module/datasets.py
13
+ src/testrail_api_module/groups.py
14
+ src/testrail_api_module/milestones.py
15
+ src/testrail_api_module/plans.py
16
+ src/testrail_api_module/priorities.py
17
+ src/testrail_api_module/projects.py
18
+ src/testrail_api_module/reports.py
19
+ src/testrail_api_module/result_fields.py
20
+ src/testrail_api_module/results.py
21
+ src/testrail_api_module/roles.py
22
+ src/testrail_api_module/runs.py
23
+ src/testrail_api_module/sections.py
24
+ src/testrail_api_module/shared_steps.py
25
+ src/testrail_api_module/statuses.py
26
+ src/testrail_api_module/suites.py
27
+ src/testrail_api_module/templates.py
28
+ src/testrail_api_module/tests.py
29
+ src/testrail_api_module/users.py
30
+ src/testrail_api_module/variables.py
31
+ src/testrail_api_module.egg-info/PKG-INFO
32
+ src/testrail_api_module.egg-info/SOURCES.txt
33
+ src/testrail_api_module.egg-info/dependency_links.txt
34
+ src/testrail_api_module.egg-info/requires.txt
35
+ src/testrail_api_module.egg-info/top_level.txt
@@ -0,0 +1 @@
1
+ testrail_api_module