robotframework-robotlog2rqm 1.4.1__tar.gz → 1.5.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 (28) hide show
  1. {robotframework-robotlog2rqm-1.4.1 → robotframework_robotlog2rqm-1.5.0}/PKG-INFO +92 -37
  2. {robotframework-robotlog2rqm-1.4.1 → robotframework_robotlog2rqm-1.5.0}/README.rst +65 -11
  3. {robotframework-robotlog2rqm-1.4.1 → robotframework_robotlog2rqm-1.5.0}/RobotLog2RQM/CRQM.py +92 -9
  4. robotframework_robotlog2rqm-1.5.0/RobotLog2RQM/RobotLog2RQM.pdf +0 -0
  5. robotframework_robotlog2rqm-1.5.0/RobotLog2RQM/logger.py +180 -0
  6. {robotframework-robotlog2rqm-1.4.1 → robotframework_robotlog2rqm-1.5.0}/RobotLog2RQM/robotlog2rqm.py +11 -165
  7. robotframework_robotlog2rqm-1.5.0/RobotLog2RQM/rqmtool.py +316 -0
  8. {robotframework-robotlog2rqm-1.4.1 → robotframework_robotlog2rqm-1.5.0}/RobotLog2RQM/version.py +2 -3
  9. {robotframework-robotlog2rqm-1.4.1 → robotframework_robotlog2rqm-1.5.0}/robotframework_robotlog2rqm.egg-info/PKG-INFO +92 -37
  10. {robotframework-robotlog2rqm-1.4.1 → robotframework_robotlog2rqm-1.5.0}/robotframework_robotlog2rqm.egg-info/SOURCES.txt +2 -0
  11. {robotframework-robotlog2rqm-1.4.1 → robotframework_robotlog2rqm-1.5.0}/robotframework_robotlog2rqm.egg-info/entry_points.txt +1 -1
  12. robotframework-robotlog2rqm-1.4.1/RobotLog2RQM/RobotLog2RQM.pdf +0 -0
  13. {robotframework-robotlog2rqm-1.4.1 → robotframework_robotlog2rqm-1.5.0}/LICENSE +0 -0
  14. {robotframework-robotlog2rqm-1.4.1 → robotframework_robotlog2rqm-1.5.0}/RobotLog2RQM/RQM_templates/buildrecord.xml +0 -0
  15. {robotframework-robotlog2rqm-1.4.1 → robotframework_robotlog2rqm-1.5.0}/RobotLog2RQM/RQM_templates/configuration.xml +0 -0
  16. {robotframework-robotlog2rqm-1.4.1 → robotframework_robotlog2rqm-1.5.0}/RobotLog2RQM/RQM_templates/executionresult.xml +0 -0
  17. {robotframework-robotlog2rqm-1.4.1 → robotframework_robotlog2rqm-1.5.0}/RobotLog2RQM/RQM_templates/executionworkitem.xml +0 -0
  18. {robotframework-robotlog2rqm-1.4.1 → robotframework_robotlog2rqm-1.5.0}/RobotLog2RQM/RQM_templates/suiteexecutionrecord.xml +0 -0
  19. {robotframework-robotlog2rqm-1.4.1 → robotframework_robotlog2rqm-1.5.0}/RobotLog2RQM/RQM_templates/testcase.xml +0 -0
  20. {robotframework-robotlog2rqm-1.4.1 → robotframework_robotlog2rqm-1.5.0}/RobotLog2RQM/RQM_templates/testsuite.xml +0 -0
  21. {robotframework-robotlog2rqm-1.4.1 → robotframework_robotlog2rqm-1.5.0}/RobotLog2RQM/RQM_templates/testsuitelog.xml +0 -0
  22. {robotframework-robotlog2rqm-1.4.1 → robotframework_robotlog2rqm-1.5.0}/RobotLog2RQM/__init__.py +0 -0
  23. {robotframework-robotlog2rqm-1.4.1 → robotframework_robotlog2rqm-1.5.0}/RobotLog2RQM/__main__.py +0 -0
  24. {robotframework-robotlog2rqm-1.4.1 → robotframework_robotlog2rqm-1.5.0}/robotframework_robotlog2rqm.egg-info/dependency_links.txt +0 -0
  25. {robotframework-robotlog2rqm-1.4.1 → robotframework_robotlog2rqm-1.5.0}/robotframework_robotlog2rqm.egg-info/requires.txt +0 -0
  26. {robotframework-robotlog2rqm-1.4.1 → robotframework_robotlog2rqm-1.5.0}/robotframework_robotlog2rqm.egg-info/top_level.txt +0 -0
  27. {robotframework-robotlog2rqm-1.4.1 → robotframework_robotlog2rqm-1.5.0}/setup.cfg +0 -0
  28. {robotframework-robotlog2rqm-1.4.1 → robotframework_robotlog2rqm-1.5.0}/setup.py +0 -0
@@ -1,12 +1,10 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.4
2
2
  Name: robotframework-robotlog2rqm
3
- Version: 1.4.1
3
+ Version: 1.5.0
4
4
  Summary: Imports robot result(s) to IBM Rational Quality Manager (RQM)
5
5
  Home-page: https://github.com/test-fullautomation/robotframework-robotlog2rqm
6
6
  Author: Tran Duy Ngoan
7
7
  Author-email: Ngoan.TranDuy@vn.bosch.com
8
- License: UNKNOWN
9
- Platform: UNKNOWN
10
8
  Classifier: Programming Language :: Python :: 3
11
9
  Classifier: License :: OSI Approved :: Apache Software License
12
10
  Classifier: Operating System :: OS Independent
@@ -16,9 +14,22 @@ Classifier: Topic :: Software Development
16
14
  Requires-Python: >=3.0
17
15
  Description-Content-Type: text/markdown
18
16
  License-File: LICENSE
19
-
20
- RobotLog2RQM Description
21
- ========================
17
+ Requires-Dist: lxml
18
+ Requires-Dist: requests
19
+ Requires-Dist: colorama
20
+ Requires-Dist: robotframework
21
+ Dynamic: author
22
+ Dynamic: author-email
23
+ Dynamic: classifier
24
+ Dynamic: description
25
+ Dynamic: description-content-type
26
+ Dynamic: home-page
27
+ Dynamic: license-file
28
+ Dynamic: requires-dist
29
+ Dynamic: requires-python
30
+ Dynamic: summary
31
+
32
+ # RobotLog2RQM Description
22
33
 
23
34
  The Python package **RobotLog2RQM** provides ability to import [Robot
24
35
  Framework test
@@ -38,14 +49,13 @@ Manager](https://www.ibm.com/support/knowledgecenter/SSYMRC_6.0.2/com.ibm.ration
38
49
  **RobotLog2RQM** tool is operating system independent and only works
39
50
  with Python 3.
40
51
 
41
- How to install
42
- --------------
52
+ ## How to install
43
53
 
44
54
  **RobotLog2RQM** can be installed in two different ways.
45
55
 
46
56
  1. Installation via PyPi (recommended for users)
47
57
 
48
- ``` {.}
58
+ ```
49
59
  pip install RobotLog2RQM
50
60
  ```
51
61
 
@@ -57,7 +67,7 @@ How to install
57
67
  - Clone the **robotframework-robotlog2rqm** repository to your
58
68
  machine.
59
69
 
60
- ``` {.}
70
+ ```
61
71
  git clone https://github.com/test-fullautomation/robotframework-robotlog2rqm.git
62
72
  ```
63
73
 
@@ -72,7 +82,7 @@ How to install
72
82
  packages you can find in the file `requirements.txt` in the
73
83
  repository root folder. Use pip to install them:
74
84
 
75
- ``` {.}
85
+ ```
76
86
  pip install -r ./requirements.txt
77
87
  ```
78
88
 
@@ -91,7 +101,7 @@ How to install
91
101
  to find **LaTeX**. This is defined in the **GenPackageDoc**
92
102
  configuration file
93
103
 
94
- ``` {.}
104
+ ```
95
105
  packagedoc\packagedoc_config.json
96
106
  ```
97
107
 
@@ -103,7 +113,7 @@ How to install
103
113
 
104
114
  - Use the following command to install **RobotLog2RQM**:
105
115
 
106
- ``` {.}
116
+ ```
107
117
  python setup.py install
108
118
  ```
109
119
 
@@ -114,8 +124,7 @@ be available (under *Scripts* folder of Python on Windows and
114
124
  In case above location is added to **PATH** environment variable then
115
125
  you can run it directly as operation system\'s command.
116
126
 
117
- How to use
118
- ----------
127
+ ## How to use
119
128
 
120
129
  **RobotLog2RQM** tool requires the Robot Framework `output.xml` result
121
130
  file(s) which will be imported, RQM information(e.g. host url, project,
@@ -128,15 +137,15 @@ Use below command to get tools\'s usage:
128
137
 
129
138
  The usage should be showed as below:
130
139
 
131
- usage: RobotLog2RQM (RobotXMLResult to RQM importer) [-h] [-v] [--testsuite TESTSUITE] [--recursive]
132
- [--createmissing] [--updatetestcase] [--dryrun] [--stream STREAM] [--baseline BASELINE]
140
+ usage: RobotLog2RQM (RobotXMLResult to RQM importer) [-h] [-v] [--testsuite TESTSUITE] [--recursive]
141
+ [--createmissing] [--updatetestcase] [--dryrun] [--stream STREAM] [--baseline BASELINE]
133
142
  resultxmlfile host project user password testplan
134
143
 
135
- RobotLog2RQM imports XML result files (default: output.xml) generated by the
144
+ RobotLog2RQM imports XML result files (default: output.xml) generated by the
136
145
  Robot Framework into an IBM Rational Quality Manager.
137
146
 
138
147
  positional arguments:
139
- resultxmlfile absolute or relative path to the xml result file
148
+ resultxmlfile absolute or relative path to the xml result file
140
149
  or directory of result files to be imported.
141
150
  host RQM host url.
142
151
  project project on RQM.
@@ -148,19 +157,19 @@ The usage should be showed as below:
148
157
  -h, --help show this help message and exit
149
158
  -v, --version Version of the RobotLog2RQM importer.
150
159
  --testsuite TESTSUITE
151
- testsuite ID for this execution. If 'new', then create a new
160
+ testsuite ID for this execution. If 'new', then create a new
152
161
  testsuite for this execution.
153
- --recursive if set, then the path is searched recursively for
162
+ --recursive if set, then the path is searched recursively for
154
163
  log files to be imported.
155
- --createmissing if set, then all testcases without tcid are created
164
+ --createmissing if set, then all testcases without tcid are created
156
165
  when importing.
157
- --updatetestcase if set, then testcase information on RQM will be updated
166
+ --updatetestcase if set, then testcase information on RQM will be updated
158
167
  bases on robot testfile.
159
- --dryrun if set, then verify all input arguments
168
+ --dryrun if set, then verify all input arguments
160
169
  (includes RQM authentication) and show what would be done.
161
- --stream STREAM project stream. Note, requires Configuration Management (CM)
170
+ --stream STREAM project stream. Note, requires Configuration Management (CM)
162
171
  to be enabled for the project area.
163
- --baseline BASELINE project baseline. Note, requires Configuration Management (CM),
172
+ --baseline BASELINE project baseline. Note, requires Configuration Management (CM),
164
173
  or Baselines Only to be enabled for the project area.
165
174
 
166
175
  The below command is simple usage witth all required arguments to import
@@ -212,6 +221,58 @@ Then, open RQM with your favourite browser and you will see that the
212
221
  test case execution records and their results are imported in the given
213
222
  testplan ID.
214
223
 
224
+ # RQMTool Submodule
225
+
226
+ The package now includes a submodule **RQMTool** which provides a
227
+ standalone CLI to fetch test cases and test suites from IBM RQM test
228
+ plans.
229
+
230
+ RQMTool is accessible as a Python module:
231
+
232
+ python -m RobotLog2RQM.rqmtool --host <RQM_SERVER_URL> --project <PROJECT_AREA> \
233
+ --user <USERNAME> --password <PASSWORD> \
234
+ --testplan <TESTPLAN_ID> [--types <artifact_types>] \
235
+ [--format <csv|json>] [--output-dir <DIR>] \
236
+ [--basename <BASENAME>] [--dryrun]
237
+
238
+ Main features:
239
+
240
+ - Fetches selected artifact types ([testcase]{.title-ref} or
241
+ [testsuite]{.title-ref}) from a given test plan.
242
+ - Supports CSV or JSON export, with automatic filenames including the
243
+ test plan ID.
244
+
245
+ ## How to use RQMTool
246
+
247
+ RQMTool requires RQM information (host URL, project, credentials) and a
248
+ test plan ID. Use the [-h]{.title-ref} argument to see full usage:
249
+
250
+ python -m RobotLog2RQM.rqmtool -h
251
+
252
+ This will display all available command line options for RQMTool, such
253
+ as:
254
+
255
+ - [\--types]{.title-ref} : artifact types to fetch
256
+ ([testcase]{.title-ref}, [testsuite]{.title-ref}). Default: both.
257
+ - \`\--format\`: output format, either [csv]{.title-ref} or
258
+ [json]{.title-ref}.
259
+ - \`\--output-dir\`: directory to save exported files.
260
+ - \`\--basename\`: base name for output files.
261
+ - \`\--dryrun\`: validate inputs and RQM login without fetching data.
262
+
263
+ ## Example
264
+
265
+ Fetch all test cases and test suites from test plan ID 720 and export to
266
+ CSV:
267
+
268
+ python -m RobotLog2RQM.rqmtool --host https://sample-rqm-host.com \
269
+ --project ROBFW-AIO \
270
+ --user test_user \
271
+ --password test_pw \
272
+ --testplan 720 \
273
+ --types testcase,testsuite \
274
+ --format csv
275
+
215
276
  ### Sourcecode Documentation
216
277
 
217
278
  To understand more detail about the tool\'s features and how Robot test
@@ -219,8 +280,7 @@ cases and their results are reflected on RQM, please refer to
219
280
  [RobotLog2RQM tool's
220
281
  Documentation](https://github.com/test-fullautomation/robotframework-robotlog2rqm/blob/develop/RobotLog2RQM/RobotLog2RQM.pdf).
221
282
 
222
- Feedback
223
- --------
283
+ ## Feedback
224
284
 
225
285
  To give us a feedback, you can send an email to [Thomas
226
286
  Pollerspöck](mailto:Thomas.Pollerspoeck@de.bosch.com).
@@ -228,15 +288,13 @@ Pollerspöck](mailto:Thomas.Pollerspoeck@de.bosch.com).
228
288
  In case you want to report a bug or request any interesting feature,
229
289
  please don\'t hesitate to raise a ticket.
230
290
 
231
- Maintainers
232
- -----------
291
+ ## Maintainers
233
292
 
234
293
  [Thomas Pollerspöck](mailto:Thomas.Pollerspoeck@de.bosch.com)
235
294
 
236
295
  [Tran Duy Ngoan](mailto:Ngoan.TranDuy@vn.bosch.com)
237
296
 
238
- Contributors
239
- ------------
297
+ ## Contributors
240
298
 
241
299
  [Nguyen Huynh Tri Cuong](mailto:Cuong.NguyenHuynhTri@vn.bosch.com)
242
300
 
@@ -246,8 +304,7 @@ Contributors
246
304
 
247
305
  [Holger Queckenstedt](mailto:Holger.Queckenstedt@de.bosch.com)
248
306
 
249
- License
250
- -------
307
+ ## License
251
308
 
252
309
  Copyright 2020-2024 Robert Bosch GmbH
253
310
 
@@ -263,5 +320,3 @@ distributed under the License is distributed on an \"AS IS\" BASIS,
263
320
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
264
321
  See the License for the specific language governing permissions and
265
322
  limitations under the License.
266
-
267
-
@@ -112,15 +112,15 @@ The usage should be showed as below:
112
112
 
113
113
  ::
114
114
 
115
- usage: RobotLog2RQM (RobotXMLResult to RQM importer) [-h] [-v] [--testsuite TESTSUITE] [--recursive]
116
- [--createmissing] [--updatetestcase] [--dryrun] [--stream STREAM] [--baseline BASELINE]
115
+ usage: RobotLog2RQM (RobotXMLResult to RQM importer) [-h] [-v] [--testsuite TESTSUITE] [--recursive]
116
+ [--createmissing] [--updatetestcase] [--dryrun] [--stream STREAM] [--baseline BASELINE]
117
117
  resultxmlfile host project user password testplan
118
118
 
119
- RobotLog2RQM imports XML result files (default: output.xml) generated by the
119
+ RobotLog2RQM imports XML result files (default: output.xml) generated by the
120
120
  Robot Framework into an IBM Rational Quality Manager.
121
121
 
122
122
  positional arguments:
123
- resultxmlfile absolute or relative path to the xml result file
123
+ resultxmlfile absolute or relative path to the xml result file
124
124
  or directory of result files to be imported.
125
125
  host RQM host url.
126
126
  project project on RQM.
@@ -132,19 +132,19 @@ The usage should be showed as below:
132
132
  -h, --help show this help message and exit
133
133
  -v, --version Version of the RobotLog2RQM importer.
134
134
  --testsuite TESTSUITE
135
- testsuite ID for this execution. If 'new', then create a new
135
+ testsuite ID for this execution. If 'new', then create a new
136
136
  testsuite for this execution.
137
- --recursive if set, then the path is searched recursively for
137
+ --recursive if set, then the path is searched recursively for
138
138
  log files to be imported.
139
- --createmissing if set, then all testcases without tcid are created
139
+ --createmissing if set, then all testcases without tcid are created
140
140
  when importing.
141
- --updatetestcase if set, then testcase information on RQM will be updated
141
+ --updatetestcase if set, then testcase information on RQM will be updated
142
142
  bases on robot testfile.
143
- --dryrun if set, then verify all input arguments
143
+ --dryrun if set, then verify all input arguments
144
144
  (includes RQM authentication) and show what would be done.
145
- --stream STREAM project stream. Note, requires Configuration Management (CM)
145
+ --stream STREAM project stream. Note, requires Configuration Management (CM)
146
146
  to be enabled for the project area.
147
- --baseline BASELINE project baseline. Note, requires Configuration Management (CM),
147
+ --baseline BASELINE project baseline. Note, requires Configuration Management (CM),
148
148
  or Baselines Only to be enabled for the project area.
149
149
 
150
150
 
@@ -203,6 +203,60 @@ at ``https://sample-rqm-host.com``
203
203
  Then, open RQM with your favourite browser and you will see that the test case
204
204
  execution records and their results are imported in the given testplan ID.
205
205
 
206
+ RQMTool Submodule
207
+ =================
208
+
209
+ The package now includes a submodule **RQMTool** which provides a standalone CLI to fetch test cases
210
+ and test suites from IBM RQM test plans.
211
+
212
+ RQMTool is accessible as a Python module:
213
+
214
+ ::
215
+
216
+ python -m RobotLog2RQM.rqmtool --host <RQM_SERVER_URL> --project <PROJECT_AREA> \
217
+ --user <USERNAME> --password <PASSWORD> \
218
+ --testplan <TESTPLAN_ID> [--types <artifact_types>] \
219
+ [--format <csv|json>] [--output-dir <DIR>] \
220
+ [--basename <BASENAME>] [--dryrun]
221
+
222
+ Main features:
223
+
224
+ * Fetches selected artifact types (`testcase` or `testsuite`) from a given test plan.
225
+ * Supports CSV or JSON export, with automatic filenames including the test plan ID.
226
+
227
+ How to use RQMTool
228
+ ------------------
229
+
230
+ RQMTool requires RQM information (host URL, project, credentials) and a test plan ID.
231
+ Use the `-h` argument to see full usage:
232
+
233
+ ::
234
+
235
+ python -m RobotLog2RQM.rqmtool -h
236
+
237
+ This will display all available command line options for RQMTool, such as:
238
+
239
+ * `--types` : artifact types to fetch (`testcase`, `testsuite`). Default: both.
240
+ * `--format`: output format, either `csv` or `json`.
241
+ * `--output-dir`: directory to save exported files.
242
+ * `--basename`: base name for output files.
243
+ * `--dryrun`: validate inputs and RQM login without fetching data.
244
+
245
+ Example
246
+ -------
247
+
248
+ Fetch all test cases and test suites from test plan ID 720 and export to CSV:
249
+
250
+ ::
251
+
252
+ python -m RobotLog2RQM.rqmtool --host https://sample-rqm-host.com \
253
+ --project ROBFW-AIO \
254
+ --user test_user \
255
+ --password test_pw \
256
+ --testplan 720 \
257
+ --types testcase,testsuite \
258
+ --format csv
259
+
206
260
  Sourcecode Documentation
207
261
  ~~~~~~~~~~~~~~~~~~~~~~~~
208
262
 
@@ -147,7 +147,7 @@ Resource type mapping:
147
147
  "testresult" : "Execution result: {testcase}",
148
148
  "testsuite" : "{testsuite}",
149
149
  "tser" : "TSER: {testsuite}",
150
- "suiteresult" : "Testsuite result: {testsuite}"
150
+ "suiteresult" : "Testsuite result: {testsuite}"
151
151
  }
152
152
 
153
153
  def __init__(self, user, password, project, host):
@@ -309,7 +309,7 @@ Disconnect from RQM.
309
309
  self.session.close()
310
310
 
311
311
  def config(self, plan_id, build_name=None, config_name=None,
312
- createmissing=False, updatetestcase=False, suite_id=None,
312
+ createmissing=False, updatetestcase=False, suite_id=None,
313
313
  stream=None, baseline=None, naming_convention=None):
314
314
  """
315
315
  Configure RQMClient with testplan ID, build, configuration, createmissing, ...
@@ -371,7 +371,7 @@ Configure RQMClient with testplan ID, build, configuration, createmissing, ...
371
371
  self.updatetestcase = updatetestcase
372
372
  self.testplan.id = plan_id
373
373
  self.testsuite.id = suite_id
374
-
374
+
375
375
  # Add Configuration-Context header information due to given stream or baseline
376
376
  if stream:
377
377
  res = self.getAllByResource('stream')
@@ -386,7 +386,7 @@ Configure RQMClient with testplan ID, build, configuration, createmissing, ...
386
386
  self.headers['Configuration-Context'] = stream_id
387
387
  self.session.headers = self.headers
388
388
  break
389
-
389
+
390
390
  if not bFoundStream:
391
391
  raise Exception(f"Cannot found given stream '{stream}'")
392
392
  else:
@@ -404,7 +404,7 @@ Configure RQMClient with testplan ID, build, configuration, createmissing, ...
404
404
  self.headers['Configuration-Context'] = baseline_id
405
405
  self.session.headers = self.headers
406
406
  break
407
-
407
+
408
408
  if not bFoundBaseline:
409
409
  raise Exception(f"Cannot found given baseline '{baseline}'")
410
410
  else:
@@ -454,7 +454,7 @@ Configure RQMClient with testplan ID, build, configuration, createmissing, ...
454
454
 
455
455
  # get all team-areas for testcase template
456
456
  self.getAllTeamAreas()
457
-
457
+
458
458
 
459
459
  except Exception as error:
460
460
  raise Exception('Configure RQMClient failed: %s'%error)
@@ -849,6 +849,83 @@ Example:
849
849
  else:
850
850
  raise Exception(f"Could not get 'team-areas' of project '{self.projectname}'.")
851
851
 
852
+ def getTestsFromTestplan(self, testplan_id, artifact_types):
853
+ """
854
+ Get all test cases and test suites associated with a given test plan.
855
+
856
+ **Arguments:**
857
+
858
+ * ``testplan_id``
859
+
860
+ / *Condition*: required / *Type*: str /
861
+
862
+ The RQM test plan to get test artifact(s).
863
+
864
+ * ``artifact_types``
865
+
866
+ / *Condition*: required / *Type*: list /
867
+
868
+ List of artifact types (`testcase`, `testsuite`) for fetching.
869
+
870
+ **Returns:**
871
+
872
+ * / *Type*: dict /
873
+
874
+ A dictionary containing fetched artifacts:
875
+
876
+ .. code:: python
877
+
878
+ {
879
+ 'testcase': [{'id': ..., 'name': ..., 'url': ...}, ...],
880
+ 'testsuite': [{'id': ..., 'name': ..., 'url': ...}, ...]
881
+ }
882
+ """
883
+ ALLOW_ARTIFACT_TYPES = ['testcase', 'testsuite']
884
+ result = {}
885
+
886
+ if isinstance(artifact_types, str):
887
+ artifact_types = [artifact_types]
888
+ elif not isinstance(artifact_types, (list, tuple)):
889
+ raise TypeError(
890
+ f"Invalid type for 'artifact_types': expected str or list, got {type(artifact_types).__name__}."
891
+ )
892
+
893
+ for item in artifact_types:
894
+ artifact_type = item.lower()
895
+ if artifact_type not in ALLOW_ARTIFACT_TYPES:
896
+ raise ValueError(
897
+ f"Unsupported artifact type '{artifact_type}'. "
898
+ f"Please use one of the following: {', '.join(ALLOW_ARTIFACT_TYPES)}."
899
+ )
900
+ result[artifact_type] = []
901
+
902
+ res = self.getResourceByID('testplan', testplan_id)
903
+ if res.status_code != 200:
904
+ raise Exception(f"Failed to get testplan {testplan_id}: {res.reason}")
905
+
906
+ oTree = get_xml_tree(BytesIO(str(res.text).encode()), bdtd_validation=False)
907
+ root = oTree.getroot()
908
+ nsmap = root.nsmap
909
+
910
+ for item in artifact_types:
911
+ artifact_type = item.lower()
912
+ # Find all linked test artifact
913
+ for oTest in root.findall(f'.//ns2:{artifact_type}', nsmap):
914
+ href = oTest.attrib.get('href')
915
+ if href:
916
+ test_id = href.split('/')[-1]
917
+ # Get testcase name
918
+ test_res = self.getResourceByID(artifact_type, test_id)
919
+ if test_res.status_code == 200:
920
+ test_tree = get_xml_tree(BytesIO(str(test_res.text).encode()), bdtd_validation=False)
921
+ test_name = test_tree.find('ns4:title', test_tree.getroot().nsmap)
922
+ test_web_id = test_tree.find('ns2:webId', test_tree.getroot().nsmap)
923
+ test_url = test_tree.find('ns4:identifier', test_tree.getroot().nsmap)
924
+ result[artifact_type].append({'id': test_web_id.text,
925
+ 'name': test_name.text if test_name is not None else '',
926
+ 'url': test_url.text})
927
+
928
+ return result
852
929
 
853
930
  #
854
931
  # Methods to create XML template for resources
@@ -1096,7 +1173,7 @@ Return testcase execution record template from provided information.
1096
1173
  nsmap = root.nsmap
1097
1174
  # prepare required data for template
1098
1175
  TCERTittle = self.__genResourceName('tcer', testcaseName)
1099
-
1176
+
1100
1177
 
1101
1178
  # Check tcid is internalid or externalid
1102
1179
  testcaseURL = self.integrationURL('testcase', testcaseID)
@@ -1462,7 +1539,7 @@ Return testsuite execution record (TSER) template from provided configuration na
1462
1539
 
1463
1540
  def createTestsuiteResultTemplate(self, testsuiteID, testsuiteName, TSERID,
1464
1541
  lTCER, lTCResults, resultState, startTime='',
1465
- endTime='', duration='', sOwnerID=''):
1542
+ endTime='', duration='', sOwnerID='', buildrecordID=''):
1466
1543
  """
1467
1544
  Return testsuite execution result template from provided configuration name.
1468
1545
 
@@ -1581,7 +1658,7 @@ Return testsuite execution result template from provided configuration name.
1581
1658
  oState.text = prefixState + 'inconclusive'
1582
1659
  if resultState.lower() in self.RESULT_STATES:
1583
1660
  oState.text = prefixState +resultState.lower()
1584
-
1661
+
1585
1662
  for idx, sTCER in enumerate(lTCER):
1586
1663
  sTCERURL = self.integrationURL('executionworkitem', sTCER)
1587
1664
  oSuiteElem = etree.Element('{http://jazz.net/xmlns/alm/qm/v0.1/tsl/v0.1/}suiteelement', nsmap=nsmap)
@@ -1599,6 +1676,12 @@ Return testsuite execution result template from provided configuration name.
1599
1676
  oExecutionResult.set('href', sTCResultURL)
1600
1677
  root.append(oExecutionResult)
1601
1678
 
1679
+ if buildrecordID:
1680
+ oBuildRecord = etree.Element('{http://jazz.net/xmlns/alm/qm/v0.1/}buildrecord', nsmap=nsmap)
1681
+ buildrecordURL = self.integrationURL('buildrecord', buildrecordID)
1682
+ oBuildRecord.set('href', buildrecordURL)
1683
+ root.append(oBuildRecord)
1684
+
1602
1685
  # return xml template as string
1603
1686
  sTSResultxml = etree.tostring(oTree)
1604
1687
  return sTSResultxml