robotframework-robotlog2rqm 1.2.4__py3-none-any.whl → 1.4.0__py3-none-any.whl
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.
- RobotLog2RQM/CRQM.py +198 -4
- RobotLog2RQM/RQM_templates/testsuite.xml +27 -0
- RobotLog2RQM/RobotLog2RQM.pdf +0 -0
- RobotLog2RQM/robotlog2rqm.py +147 -28
- RobotLog2RQM/version.py +2 -2
- {robotframework_robotlog2rqm-1.2.4.dist-info → robotframework_robotlog2rqm-1.4.0.dist-info}/METADATA +29 -22
- {robotframework_robotlog2rqm-1.2.4.dist-info → robotframework_robotlog2rqm-1.4.0.dist-info}/RECORD +11 -10
- {robotframework_robotlog2rqm-1.2.4.dist-info → robotframework_robotlog2rqm-1.4.0.dist-info}/WHEEL +1 -1
- {robotframework_robotlog2rqm-1.2.4.dist-info → robotframework_robotlog2rqm-1.4.0.dist-info}/LICENSE +0 -0
- {robotframework_robotlog2rqm-1.2.4.dist-info → robotframework_robotlog2rqm-1.4.0.dist-info}/entry_points.txt +0 -0
- {robotframework_robotlog2rqm-1.2.4.dist-info → robotframework_robotlog2rqm-1.4.0.dist-info}/top_level.txt +0 -0
RobotLog2RQM/CRQM.py
CHANGED
|
@@ -195,7 +195,12 @@ Constructor of class ``CRQMClient``.
|
|
|
195
195
|
self.configuration = None
|
|
196
196
|
self.createmissing = None
|
|
197
197
|
self.updatetestcase= None
|
|
198
|
-
self.testsuite =
|
|
198
|
+
self.testsuite = {
|
|
199
|
+
"id": None,
|
|
200
|
+
"name": None
|
|
201
|
+
}
|
|
202
|
+
self.stream = None
|
|
203
|
+
self.baseline = None
|
|
199
204
|
|
|
200
205
|
def login(self):
|
|
201
206
|
"""
|
|
@@ -285,7 +290,8 @@ Disconnect from RQM.
|
|
|
285
290
|
self.session.close()
|
|
286
291
|
|
|
287
292
|
def config(self, plan_id, build_name=None, config_name=None,
|
|
288
|
-
createmissing=False, updatetestcase=False,suite_id=None
|
|
293
|
+
createmissing=False, updatetestcase=False, suite_id=None,
|
|
294
|
+
stream=None, baseline=None):
|
|
289
295
|
"""
|
|
290
296
|
Configure RQMClient with testplan ID, build, configuration, createmissing, ...
|
|
291
297
|
|
|
@@ -340,8 +346,45 @@ Configure RQMClient with testplan ID, build, configuration, createmissing, ...
|
|
|
340
346
|
try:
|
|
341
347
|
self.createmissing = createmissing
|
|
342
348
|
self.updatetestcase = updatetestcase
|
|
343
|
-
self.testsuite = suite_id
|
|
344
349
|
self.testplan = plan_id
|
|
350
|
+
self.testsuite['id'] = suite_id
|
|
351
|
+
|
|
352
|
+
# Add Configuration-Context header information due to given stream or baseline
|
|
353
|
+
if stream:
|
|
354
|
+
res = self.getAllByResource('stream')
|
|
355
|
+
if res['success']:
|
|
356
|
+
dStreams = res['data']
|
|
357
|
+
bFoundStream = False
|
|
358
|
+
for stream_id, stream_name in dStreams.items():
|
|
359
|
+
if stream_name == stream:
|
|
360
|
+
self.stream = stream_id
|
|
361
|
+
bFoundStream = True
|
|
362
|
+
self.headers['Configuration-Context'] = stream_id
|
|
363
|
+
self.session.headers = self.headers
|
|
364
|
+
break
|
|
365
|
+
|
|
366
|
+
if not bFoundStream:
|
|
367
|
+
raise Exception(f"Cannot found given stream '{stream}'")
|
|
368
|
+
else:
|
|
369
|
+
raise Exception("Get all streams failed. Reason: %s"%res['message'])
|
|
370
|
+
elif baseline:
|
|
371
|
+
res = self.getAllByResource('baseline')
|
|
372
|
+
if res['success']:
|
|
373
|
+
dBaselines = res['data']
|
|
374
|
+
bFoundBaseline = False
|
|
375
|
+
for baseline_id, baseline_name in dBaselines.items():
|
|
376
|
+
if baseline_name == baseline:
|
|
377
|
+
self.baseline = baseline_id
|
|
378
|
+
bFoundBaseline = True
|
|
379
|
+
self.headers['Configuration-Context'] = baseline_id
|
|
380
|
+
self.session.headers = self.headers
|
|
381
|
+
break
|
|
382
|
+
|
|
383
|
+
if not bFoundBaseline:
|
|
384
|
+
raise Exception(f"Cannot found given baseline '{baseline}'")
|
|
385
|
+
else:
|
|
386
|
+
raise Exception("Get all baselines failed. Reason: %s"%res['message'])
|
|
387
|
+
|
|
345
388
|
# Verify testplan ID
|
|
346
389
|
res_plan = self.getResourceByID('testplan', plan_id)
|
|
347
390
|
if res_plan.status_code != 200:
|
|
@@ -371,8 +414,17 @@ Configure RQMClient with testplan ID, build, configuration, createmissing, ...
|
|
|
371
414
|
raise Exception("Cannot create configuration '%s': %s"%
|
|
372
415
|
(config_name, res_conf['message']))
|
|
373
416
|
|
|
417
|
+
# Verify testsuite if given
|
|
418
|
+
if (suite_id != None) and (suite_id != "new"):
|
|
419
|
+
res_suite = self.getResourceByID('testsuite', suite_id)
|
|
420
|
+
if res_suite.status_code != 200:
|
|
421
|
+
raise Exception('Testsuite with ID %s is not existing!'%str(suite_id))
|
|
422
|
+
oTestsuite = get_xml_tree(BytesIO(str(res_suite.text).encode()), bdtd_validation=False)
|
|
423
|
+
self.testsuite['name'] = oTestsuite.find('ns4:title', oTestsuite.getroot().nsmap).text
|
|
424
|
+
|
|
374
425
|
# get all team-areas for testcase template
|
|
375
426
|
self.getAllTeamAreas()
|
|
427
|
+
|
|
376
428
|
|
|
377
429
|
except Exception as error:
|
|
378
430
|
raise Exception('Configure RQMClient failed: %s'%error)
|
|
@@ -1323,7 +1375,7 @@ Return testsuite execution record (TSER) template from provided configuration na
|
|
|
1323
1375
|
return sTSxml
|
|
1324
1376
|
|
|
1325
1377
|
def createTestsuiteResultTemplate(self, testsuiteID, testsuiteName, TSERID,
|
|
1326
|
-
lTCER, lTCResults, startTime='',
|
|
1378
|
+
lTCER, lTCResults, resultState, startTime='',
|
|
1327
1379
|
endTime='', duration='', sOwnerID=''):
|
|
1328
1380
|
"""
|
|
1329
1381
|
Return testsuite execution result template from provided configuration name.
|
|
@@ -1395,6 +1447,7 @@ Return testsuite execution result template from provided configuration name.
|
|
|
1395
1447
|
sTSResultxml = ''
|
|
1396
1448
|
sTemplatePath = os.path.join(self.templatesDir, 'testsuitelog.xml')
|
|
1397
1449
|
oTree = get_xml_tree(sTemplatePath, bdtd_validation=False)
|
|
1450
|
+
prefixState = 'com.ibm.rqm.execution.common.state.'
|
|
1398
1451
|
|
|
1399
1452
|
# prepare required data for template
|
|
1400
1453
|
resultTittle = 'Testsuite result: ' + testsuiteName
|
|
@@ -1438,6 +1491,11 @@ Return testsuite execution result template from provided configuration name.
|
|
|
1438
1491
|
oStarttime.text = str(startTime).replace(' ', 'T')
|
|
1439
1492
|
oEndtime.text = str(endTime).replace(' ', 'T')
|
|
1440
1493
|
oTotalRunTime.text = str(duration)
|
|
1494
|
+
# set default RQM state as inconclusive
|
|
1495
|
+
oState.text = prefixState + 'inconclusive'
|
|
1496
|
+
if resultState.lower() in self.RESULT_STATES:
|
|
1497
|
+
oState.text = prefixState +resultState.lower()
|
|
1498
|
+
|
|
1441
1499
|
for idx, sTCER in enumerate(lTCER):
|
|
1442
1500
|
sTCERURL = self.integrationURL('executionworkitem', sTCER)
|
|
1443
1501
|
oSuiteElem = etree.Element('{http://jazz.net/xmlns/alm/qm/v0.1/tsl/v0.1/}suiteelement', nsmap=nsmap)
|
|
@@ -1459,6 +1517,79 @@ Return testsuite execution result template from provided configuration name.
|
|
|
1459
1517
|
sTSResultxml = etree.tostring(oTree)
|
|
1460
1518
|
return sTSResultxml
|
|
1461
1519
|
|
|
1520
|
+
def createTestsuiteTemplate(self, testsuiteName, sDescription='', sOwnerID='', sTStemplate=None):
|
|
1521
|
+
"""
|
|
1522
|
+
Return testcase template from provided information.
|
|
1523
|
+
|
|
1524
|
+
**Arguments:**
|
|
1525
|
+
|
|
1526
|
+
* ``testsuiteName``
|
|
1527
|
+
|
|
1528
|
+
/ *Condition*: required / *Type*: str /
|
|
1529
|
+
|
|
1530
|
+
Testsuite name.
|
|
1531
|
+
|
|
1532
|
+
* ``sDescription``
|
|
1533
|
+
|
|
1534
|
+
/ *Condition*: optional / *Type*: str / *Default*: '' /
|
|
1535
|
+
|
|
1536
|
+
Testsuite description.
|
|
1537
|
+
|
|
1538
|
+
* ``sOwnerID``
|
|
1539
|
+
|
|
1540
|
+
/ *Condition*: optional / *Type*: str / *Default*: '' /
|
|
1541
|
+
|
|
1542
|
+
User ID of testsuite owner.
|
|
1543
|
+
|
|
1544
|
+
* ``sTStemplate``
|
|
1545
|
+
|
|
1546
|
+
/ *Condition*: optional / *Type*: str / *Default*: None /
|
|
1547
|
+
|
|
1548
|
+
Existing testsuite template as xml string.
|
|
1549
|
+
|
|
1550
|
+
If not provided, template file under `RQM_templates` is used as default.
|
|
1551
|
+
|
|
1552
|
+
**Returns:**
|
|
1553
|
+
|
|
1554
|
+
* ``sTSxml``
|
|
1555
|
+
|
|
1556
|
+
/ *Type*: str /
|
|
1557
|
+
|
|
1558
|
+
The xml testsuite template as string.
|
|
1559
|
+
"""
|
|
1560
|
+
sTSxml = ''
|
|
1561
|
+
if not sTStemplate:
|
|
1562
|
+
sTemplatePath = os.path.join(self.templatesDir ,'testsuite.xml')
|
|
1563
|
+
oTree = get_xml_tree(sTemplatePath, bdtd_validation=False)
|
|
1564
|
+
else:
|
|
1565
|
+
oTree = get_xml_tree(BytesIO(sTStemplate.encode()),bdtd_validation=False)
|
|
1566
|
+
|
|
1567
|
+
root = oTree.getroot()
|
|
1568
|
+
nsmap = root.nsmap
|
|
1569
|
+
|
|
1570
|
+
# prepare required data for template
|
|
1571
|
+
testerURL = self.userURL(self.userID)
|
|
1572
|
+
|
|
1573
|
+
# find nodes to change data
|
|
1574
|
+
oTittle = oTree.find('ns4:title', nsmap)
|
|
1575
|
+
oDescription = oTree.find('ns4:description', nsmap)
|
|
1576
|
+
oOwner = oTree.find('ns6:owner', nsmap)
|
|
1577
|
+
|
|
1578
|
+
# change nodes's data
|
|
1579
|
+
oTittle.text = testsuiteName
|
|
1580
|
+
oDescription.text = sDescription
|
|
1581
|
+
|
|
1582
|
+
# Incase not specify owner in template or input data, set it as provided user in cli
|
|
1583
|
+
if sOwnerID:
|
|
1584
|
+
oOwner.text = sOwnerID
|
|
1585
|
+
oOwner.attrib['{%s}resource' % nsmap['ns1']] = self.userURL(sOwnerID)
|
|
1586
|
+
elif not oOwner.text:
|
|
1587
|
+
oOwner.text = self.userID
|
|
1588
|
+
oOwner.attrib['{%s}resource' % nsmap['ns1']] = testerURL
|
|
1589
|
+
|
|
1590
|
+
# return xml template as string
|
|
1591
|
+
sTSxml = etree.tostring(oTree)
|
|
1592
|
+
return sTSxml
|
|
1462
1593
|
#
|
|
1463
1594
|
# Methods to create RQM resources
|
|
1464
1595
|
#
|
|
@@ -1827,3 +1958,66 @@ Link list of test cases to provided testsuite ID
|
|
|
1827
1958
|
else:
|
|
1828
1959
|
returnObj['message'] = "No testcase for linking."
|
|
1829
1960
|
return returnObj
|
|
1961
|
+
|
|
1962
|
+
def addTestsuite2Testplan(self, testplanID, testsuiteID=None):
|
|
1963
|
+
"""
|
|
1964
|
+
Add testsuite ID to provided testplan ID
|
|
1965
|
+
|
|
1966
|
+
**Arguments:**
|
|
1967
|
+
|
|
1968
|
+
* ``testplanID``
|
|
1969
|
+
|
|
1970
|
+
/ *Condition*: required / *Type*: str /
|
|
1971
|
+
|
|
1972
|
+
Testplan ID to link given testsuite ID.
|
|
1973
|
+
|
|
1974
|
+
* ``testsuiteID``
|
|
1975
|
+
|
|
1976
|
+
/ *Condition*: optional / *Type*: str / *Default*: None /
|
|
1977
|
+
|
|
1978
|
+
Testsuite to be linked with given testplan.
|
|
1979
|
+
|
|
1980
|
+
If not provide, `testsuite['id']` value will be used as id of testsuite.
|
|
1981
|
+
|
|
1982
|
+
**Returns:**
|
|
1983
|
+
|
|
1984
|
+
* ``returnObj``
|
|
1985
|
+
|
|
1986
|
+
/ *Type*: dict /
|
|
1987
|
+
|
|
1988
|
+
Response dictionary which contains status and error message.
|
|
1989
|
+
|
|
1990
|
+
Example:
|
|
1991
|
+
|
|
1992
|
+
.. code:: python
|
|
1993
|
+
|
|
1994
|
+
{
|
|
1995
|
+
'success' : False,
|
|
1996
|
+
'message': ''
|
|
1997
|
+
}
|
|
1998
|
+
|
|
1999
|
+
"""
|
|
2000
|
+
returnObj = {'success' : False, 'message': ''}
|
|
2001
|
+
if testsuiteID == None:
|
|
2002
|
+
testsuiteID = self.testsuite['id']
|
|
2003
|
+
if testsuiteID:
|
|
2004
|
+
resTestplanData = self.getResourceByID('testplan', testplanID)
|
|
2005
|
+
oTree = get_xml_tree(BytesIO(str(resTestplanData.text).encode()),bdtd_validation=False)
|
|
2006
|
+
# RQM XML response using namespace for nodes
|
|
2007
|
+
# use namespace mapping from root for access response XML
|
|
2008
|
+
root = oTree.getroot()
|
|
2009
|
+
|
|
2010
|
+
sTestsuiteURL = self.integrationURL('testsuite', testsuiteID)
|
|
2011
|
+
oTS = etree.Element('{http://jazz.net/xmlns/alm/qm/v0.1/}testsuite', nsmap=root.nsmap)
|
|
2012
|
+
oTS.set('href', sTestsuiteURL)
|
|
2013
|
+
root.append(oTS)
|
|
2014
|
+
|
|
2015
|
+
# Update test plan data with linked testsuite and PUT to RQM
|
|
2016
|
+
resUpdateTestplan = self.updateResourceByID('testplan', testplanID, etree.tostring(oTree))
|
|
2017
|
+
if resUpdateTestplan.status_code == 200:
|
|
2018
|
+
returnObj['success'] = True
|
|
2019
|
+
else:
|
|
2020
|
+
returnObj['message'] = str(resUpdateTestplan.reason)
|
|
2021
|
+
else:
|
|
2022
|
+
returnObj['message'] = "No testsuite for adding."
|
|
2023
|
+
return returnObj
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
+
<ns2:testsuite xmlns:ns2="http://jazz.net/xmlns/alm/qm/v0.1/"
|
|
3
|
+
xmlns:ns1="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
|
4
|
+
xmlns:ns3="http://schema.ibm.com/vega/2008/"
|
|
5
|
+
xmlns:ns4="http://purl.org/dc/elements/1.1/"
|
|
6
|
+
xmlns:ns5="http://jazz.net/xmlns/prod/jazz/process/0.6/"
|
|
7
|
+
xmlns:ns6="http://jazz.net/xmlns/alm/v0.1/"
|
|
8
|
+
xmlns:ns7="http://purl.org/dc/terms/"
|
|
9
|
+
xmlns:ns8="http://jazz.net/xmlns/alm/qm/v0.1/testscript/v0.1/"
|
|
10
|
+
xmlns:ns9="http://jazz.net/xmlns/alm/qm/v0.1/executionworkitem/v0.1"
|
|
11
|
+
xmlns:ns10="http://open-services.net/ns/core#"
|
|
12
|
+
xmlns:ns11="http://open-services.net/ns/qm#"
|
|
13
|
+
xmlns:ns12="http://jazz.net/xmlns/prod/jazz/rqm/process/1.0/"
|
|
14
|
+
xmlns:ns13="http://www.w3.org/2002/07/owl#"
|
|
15
|
+
xmlns:ns14="http://jazz.net/xmlns/alm/qm/qmadapter/v0.1"
|
|
16
|
+
xmlns:ns15="http://jazz.net/xmlns/alm/qm/qmadapter/task/v0.1"
|
|
17
|
+
xmlns:ns16="http://jazz.net/xmlns/alm/qm/v0.1/executionresult/v0.1"
|
|
18
|
+
xmlns:ns17="http://jazz.net/xmlns/alm/qm/v0.1/catalog/v0.1"
|
|
19
|
+
xmlns:ns18="http://jazz.net/xmlns/alm/qm/v0.1/tsl/v0.1/"
|
|
20
|
+
xmlns:ns20="http://jazz.net/xmlns/alm/qm/styleinfo/v0.1/"
|
|
21
|
+
xmlns:ns21="http://www.w3.org/1999/XSL/Transform">
|
|
22
|
+
<ns4:title></ns4:title>
|
|
23
|
+
<ns4:description></ns4:description>
|
|
24
|
+
<ns4:creator></ns4:creator>
|
|
25
|
+
<ns6:owner></ns6:owner>
|
|
26
|
+
<ns2:testplan href=""/>
|
|
27
|
+
</ns2:testsuite>
|
RobotLog2RQM/RobotLog2RQM.pdf
CHANGED
|
Binary file
|
RobotLog2RQM/robotlog2rqm.py
CHANGED
|
@@ -158,7 +158,7 @@ Write log message to console/file output.
|
|
|
158
158
|
return
|
|
159
159
|
|
|
160
160
|
@classmethod
|
|
161
|
-
def log_warning(cls, msg):
|
|
161
|
+
def log_warning(cls, msg, indent=0):
|
|
162
162
|
"""
|
|
163
163
|
Write warning message to console/file output.
|
|
164
164
|
|
|
@@ -170,14 +170,20 @@ Write warning message to console/file output.
|
|
|
170
170
|
|
|
171
171
|
Warning message which is written to output.
|
|
172
172
|
|
|
173
|
+
* ``indent``
|
|
174
|
+
|
|
175
|
+
/ *Condition*: optional / *Type*: int / *Default*: 0 /
|
|
176
|
+
|
|
177
|
+
Offset indent.
|
|
178
|
+
|
|
173
179
|
**Returns:**
|
|
174
180
|
|
|
175
181
|
(*no returns*)
|
|
176
182
|
"""
|
|
177
|
-
cls.log(cls.prefix_warn+str(msg), cls.color_warn)
|
|
183
|
+
cls.log(cls.prefix_warn+str(msg), cls.color_warn, indent)
|
|
178
184
|
|
|
179
185
|
@classmethod
|
|
180
|
-
def log_error(cls, msg, fatal_error=False):
|
|
186
|
+
def log_error(cls, msg, fatal_error=False, indent=0):
|
|
181
187
|
"""
|
|
182
188
|
Write error message to console/file output.
|
|
183
189
|
|
|
@@ -193,6 +199,12 @@ Write error message to console/file output.
|
|
|
193
199
|
|
|
194
200
|
If set, tool will terminate after logging error message.
|
|
195
201
|
|
|
202
|
+
* ``indent``
|
|
203
|
+
|
|
204
|
+
/ *Condition*: optional / *Type*: int / *Default*: 0 /
|
|
205
|
+
|
|
206
|
+
Offset indent.
|
|
207
|
+
|
|
196
208
|
**Returns:**
|
|
197
209
|
|
|
198
210
|
(*no returns*)
|
|
@@ -201,7 +213,7 @@ Write error message to console/file output.
|
|
|
201
213
|
if fatal_error:
|
|
202
214
|
prefix = cls.prefix_fatalerror
|
|
203
215
|
|
|
204
|
-
cls.log(prefix+str(msg), cls.color_error)
|
|
216
|
+
cls.log(prefix+str(msg), cls.color_error, indent)
|
|
205
217
|
if fatal_error:
|
|
206
218
|
cls.log(f"{sys.argv[0]} has been stopped!", cls.color_error)
|
|
207
219
|
exit(1)
|
|
@@ -281,9 +293,12 @@ Avalable arguments in command line:
|
|
|
281
293
|
- `user` : user for RQM login.
|
|
282
294
|
- `password` : user password for RQM login.
|
|
283
295
|
- `testplan` : RQM testplan ID.
|
|
296
|
+
- `--testsuite` : RQM testsuite ID. If value is 'new', then create a new testsuite for this execution.
|
|
284
297
|
- `--recursive` : if True, then the path is searched recursively for log files to be imported.
|
|
285
298
|
- `--createmissing` : if True, then all testcases without tcid are created when importing.
|
|
286
299
|
- `--dryrun` : if True, then verify all input arguments (includes RQM authentication) and show what would be done.
|
|
300
|
+
- `--stream` : project stream. Note, requires Configuration Management (CM) to be enabled for the project area.
|
|
301
|
+
- `--baseline` : project baseline. Note, requires Configuration Management (CM), or Baselines Only to be enabled for the project area.
|
|
287
302
|
|
|
288
303
|
**Arguments:**
|
|
289
304
|
|
|
@@ -312,6 +327,8 @@ Avalable arguments in command line:
|
|
|
312
327
|
cmdParser.add_argument('password', type=str, help='password for RQM login.')
|
|
313
328
|
cmdParser.add_argument('testplan', type=str,
|
|
314
329
|
help='testplan ID for this execution.')
|
|
330
|
+
cmdParser.add_argument('--testsuite', type=str,
|
|
331
|
+
help="testsuite ID for this execution. If 'new', then create a new testsuite for this execution.")
|
|
315
332
|
cmdParser.add_argument('--recursive',action="store_true",
|
|
316
333
|
help='if set, then the path is searched recursively for log files to be imported.')
|
|
317
334
|
cmdParser.add_argument('--createmissing', action="store_true",
|
|
@@ -320,6 +337,10 @@ Avalable arguments in command line:
|
|
|
320
337
|
help='if set, then testcase information on RQM will be updated bases on robot testfile.')
|
|
321
338
|
cmdParser.add_argument('--dryrun',action="store_true",
|
|
322
339
|
help='if set, then verify all input arguments (includes RQM authentication) and show what would be done.')
|
|
340
|
+
cmdParser.add_argument('--stream', type=str,
|
|
341
|
+
help='project stream. Note, requires Configuration Management (CM) to be enabled for the project area.')
|
|
342
|
+
cmdParser.add_argument('--baseline', type=str,
|
|
343
|
+
help='project baseline. Note, requires Configuration Management (CM), or Baselines Only to be enabled for the project area.')
|
|
323
344
|
|
|
324
345
|
return cmdParser.parse_args()
|
|
325
346
|
|
|
@@ -395,7 +416,7 @@ Extract metadata from suite result bases on DEFAULT_METADATA.
|
|
|
395
416
|
|
|
396
417
|
return dMetadata
|
|
397
418
|
|
|
398
|
-
def process_suite(RQMClient, suite):
|
|
419
|
+
def process_suite(RQMClient, suite, log_indent=0):
|
|
399
420
|
"""
|
|
400
421
|
Process robot suite for importing to RQM.
|
|
401
422
|
|
|
@@ -413,15 +434,21 @@ Process robot suite for importing to RQM.
|
|
|
413
434
|
|
|
414
435
|
Robot suite object.
|
|
415
436
|
|
|
437
|
+
* ``log_indent``
|
|
438
|
+
|
|
439
|
+
/ *Condition*: optional / *Type*: int / *Default*: 0 /
|
|
440
|
+
|
|
441
|
+
Indent for logging message.
|
|
442
|
+
|
|
416
443
|
**Returns:**
|
|
417
444
|
|
|
418
445
|
(*no returns*)
|
|
419
446
|
"""
|
|
420
447
|
if len(list(suite.suites)) > 0:
|
|
421
448
|
for subsuite in suite.suites:
|
|
422
|
-
process_suite(RQMClient, subsuite)
|
|
449
|
+
process_suite(RQMClient, subsuite, log_indent=log_indent+2)
|
|
423
450
|
else:
|
|
424
|
-
Logger.log(f"Process suite: {suite.name}")
|
|
451
|
+
Logger.log(f"Process suite: {suite.name}", indent=log_indent)
|
|
425
452
|
|
|
426
453
|
# update missing metadata from parent suite
|
|
427
454
|
if suite.parent and suite.parent.metadata:
|
|
@@ -431,9 +458,9 @@ Process robot suite for importing to RQM.
|
|
|
431
458
|
|
|
432
459
|
if len(list(suite.tests)) > 0:
|
|
433
460
|
for test in suite.tests:
|
|
434
|
-
process_test(RQMClient, test)
|
|
461
|
+
process_test(RQMClient, test, log_indent=log_indent+2)
|
|
435
462
|
|
|
436
|
-
def process_test(RQMClient, test):
|
|
463
|
+
def process_test(RQMClient, test, log_indent=0):
|
|
437
464
|
"""
|
|
438
465
|
Process robot test for importing to RQM.
|
|
439
466
|
|
|
@@ -451,11 +478,17 @@ Process robot test for importing to RQM.
|
|
|
451
478
|
|
|
452
479
|
Robot test object.
|
|
453
480
|
|
|
481
|
+
* ``log_indent``
|
|
482
|
+
|
|
483
|
+
/ *Condition*: optional / *Type*: int / *Default*: 0 /
|
|
484
|
+
|
|
485
|
+
Indent for logging message.
|
|
486
|
+
|
|
454
487
|
**Returns:**
|
|
455
488
|
|
|
456
489
|
(*no returns*)
|
|
457
490
|
"""
|
|
458
|
-
Logger.log(f"Process test: {test.name}")
|
|
491
|
+
Logger.log(f"Process test: {test.name}", indent=log_indent)
|
|
459
492
|
|
|
460
493
|
# Avoid create resources with dryrun
|
|
461
494
|
if Logger.dryrun:
|
|
@@ -485,7 +518,7 @@ Process robot test for importing to RQM.
|
|
|
485
518
|
try:
|
|
486
519
|
_tc_result = DRESULT_MAPPING[test.status]
|
|
487
520
|
except Exception:
|
|
488
|
-
Logger.log_error(f"Invalid Robotframework result state '{test.status}' of test '{_tc_name}'.")
|
|
521
|
+
Logger.log_error(f"Invalid Robotframework result state '{test.status}' of test '{_tc_name}'.", indent=log_indent)
|
|
489
522
|
return
|
|
490
523
|
_tc_message = test.message
|
|
491
524
|
_tc_start_time = convert_to_datetime(test.starttime)
|
|
@@ -509,19 +542,19 @@ Process robot test for importing to RQM.
|
|
|
509
542
|
res = RQMClient.createResource('testcase', oTCTemplate)
|
|
510
543
|
if res['success']:
|
|
511
544
|
_tc_id = res['id']
|
|
512
|
-
Logger.log(f"Create testcase '{_tc_name}' with ID '{_tc_id}' successfully!")
|
|
545
|
+
Logger.log(f"Create testcase '{_tc_name}' with ID '{_tc_id}' successfully!", indent=log_indent)
|
|
513
546
|
RQMClient.dMappingTCID[_tc_id] = _tc_name
|
|
514
547
|
else:
|
|
515
|
-
Logger.log_error(f"Create testcase '{_tc_name}' failed. Reason: {res['message']}")
|
|
548
|
+
Logger.log_error(f"Create testcase '{_tc_name}' failed. Reason: {res['message']}", indent=log_indent)
|
|
516
549
|
return
|
|
517
550
|
else:
|
|
518
|
-
Logger.log_error(f"There is no 'tcid' information for importing test '{_tc_name}'.")
|
|
551
|
+
Logger.log_error(f"There is no 'tcid' information for importing test '{_tc_name}'.", indent=log_indent)
|
|
519
552
|
return
|
|
520
553
|
else:
|
|
521
554
|
# If more than 1 tcid are defined in [Tags], the first one is used.
|
|
522
555
|
if len(lTCIDTags) > 1:
|
|
523
556
|
_tc_id = lTCIDTags[0]
|
|
524
|
-
Logger.log_warning(f"More than 1 'tcid-' tags in test '{_tc_name}', '{_tc_id}' is used.")
|
|
557
|
+
Logger.log_warning(f"More than 1 'tcid-' tags in test '{_tc_name}', '{_tc_id}' is used.", indent=log_indent)
|
|
525
558
|
|
|
526
559
|
# If --updatetestcase is set. Test case with provided tcid will be updated on RQM:
|
|
527
560
|
# Get existing resource of testcase from RQM.
|
|
@@ -538,9 +571,9 @@ Process robot test for importing to RQM.
|
|
|
538
571
|
_tc_link,
|
|
539
572
|
sTCtemplate=str(resTC.text))
|
|
540
573
|
RQMClient.updateResourceByID('testcase', _tc_id, oTCTemplate)
|
|
541
|
-
Logger.log(f"Update testcase '{_tc_name}' with ID '{_tc_id}' successfully!")
|
|
574
|
+
Logger.log(f"Update testcase '{_tc_name}' with ID '{_tc_id}' successfully!", indent=log_indent)
|
|
542
575
|
else:
|
|
543
|
-
Logger.log_error(f"Update testcase with ID '{_tc_id}' failed. Please check whether it is existing on RQM.")
|
|
576
|
+
Logger.log_error(f"Update testcase with ID '{_tc_id}' failed. Please check whether it is existing on RQM.", indent=log_indent)
|
|
544
577
|
return
|
|
545
578
|
|
|
546
579
|
# Create TCER:
|
|
@@ -555,11 +588,11 @@ Process robot test for importing to RQM.
|
|
|
555
588
|
res = RQMClient.createResource('executionworkitem', oTCERTemplate)
|
|
556
589
|
_tc_tcer_id = res['id']
|
|
557
590
|
if res['success']:
|
|
558
|
-
Logger.log(f"Created TCER with ID '{_tc_tcer_id}' successfully.")
|
|
591
|
+
Logger.log(f"Created TCER with ID '{_tc_tcer_id}' successfully.", indent=log_indent+2)
|
|
559
592
|
elif (res['status_code'] == 303 or res['status_code'] == 200) and res['id'] != '':
|
|
560
|
-
Logger.log_warning(f"TCER for testcase '{_tc_id}' and testplan '{_tc_testplan_id}' is existing with ID: '{_tc_tcer_id}'")
|
|
593
|
+
Logger.log_warning(f"TCER for testcase '{_tc_id}' and testplan '{_tc_testplan_id}' is existing with ID: '{_tc_tcer_id}'", indent=log_indent+2)
|
|
561
594
|
else:
|
|
562
|
-
Logger.log_error(f"Create TCER failed. Please check whether test case with ID '{_tc_id}' is existing on RQM or not. Reason: {res['message']}.")
|
|
595
|
+
Logger.log_error(f"Create TCER failed. Please check whether test case with ID '{_tc_id}' is existing on RQM or not. Reason: {res['message']}.", indent=log_indent+2)
|
|
563
596
|
return
|
|
564
597
|
|
|
565
598
|
if _tc_tcer_id not in RQMClient.lTCERIDs:
|
|
@@ -584,10 +617,10 @@ Process robot test for importing to RQM.
|
|
|
584
617
|
_tc_team)
|
|
585
618
|
res = RQMClient.createResource('executionresult', oTCResultTemplate)
|
|
586
619
|
if res['success']:
|
|
587
|
-
Logger.log(f"Create result for test '{_tc_name}' successfully!")
|
|
620
|
+
Logger.log(f"Create result for test '{_tc_name}' successfully!", indent=log_indent+4)
|
|
588
621
|
_tc_result_id = res['id']
|
|
589
622
|
else:
|
|
590
|
-
Logger.log_error(f"Create result for test '{_tc_name}' failed. Reason: {res['message']}.")
|
|
623
|
+
Logger.log_error(f"Create result for test '{_tc_name}' failed. Reason: {res['message']}.", indent=log_indent+4)
|
|
591
624
|
return
|
|
592
625
|
if _tc_result_id not in RQMClient.lTCResultIDs:
|
|
593
626
|
RQMClient.lTCResultIDs.append(_tc_result_id)
|
|
@@ -595,6 +628,10 @@ Process robot test for importing to RQM.
|
|
|
595
628
|
# Append lTestcaseIDs (for linking testplan/testsuite)
|
|
596
629
|
if _tc_id not in RQMClient.lTestcaseIDs:
|
|
597
630
|
RQMClient.lTestcaseIDs.append(_tc_id)
|
|
631
|
+
|
|
632
|
+
# Collect starttime and endtime for testsuite log creation
|
|
633
|
+
RQMClient.lStartTimes.append(_tc_start_time)
|
|
634
|
+
RQMClient.lEndTimes.append(_tc_end_time)
|
|
598
635
|
|
|
599
636
|
def RobotLog2RQM(args=None):
|
|
600
637
|
"""
|
|
@@ -622,11 +659,13 @@ Flow to import Robot results to RQM:
|
|
|
622
659
|
* `user` : user for RQM login.
|
|
623
660
|
* `password` : user password for RQM login.
|
|
624
661
|
* `testplan` : RQM testplan ID.
|
|
662
|
+
* `testsuite` : testsuite ID for this execution. If 'new', then create a new testsuite for this execution.
|
|
625
663
|
* `recursive` : if True, then the path is searched recursively for log files to be imported.
|
|
626
664
|
* `createmissing` : if True, then all testcases without tcid are created when importing.
|
|
627
665
|
* `updatetestcase` : if True, then testcases information on RQM will be updated bases on robot testfile.
|
|
628
666
|
* `dryrun` : if True, then verify all input arguments (includes RQM authentication) and show what would be done.
|
|
629
|
-
|
|
667
|
+
* `stream` : project stream. Note, requires Configuration Management (CM) to be enabled for the project area.
|
|
668
|
+
* `baseline` : project baseline. Note, requires Configuration Management (CM), or Baselines Only to be enabled for the project area.
|
|
630
669
|
**Returns:**
|
|
631
670
|
|
|
632
671
|
(*no returns*)
|
|
@@ -676,6 +715,7 @@ Flow to import Robot results to RQM:
|
|
|
676
715
|
try:
|
|
677
716
|
bSuccess = RQMClient.login()
|
|
678
717
|
if bSuccess:
|
|
718
|
+
Logger.log()
|
|
679
719
|
Logger.log(f"Login RQM as user '{args.user}' successfully!")
|
|
680
720
|
else:
|
|
681
721
|
Logger.log_error("Could not login to RQM: 'Unkown reason'.")
|
|
@@ -694,14 +734,85 @@ Flow to import Robot results to RQM:
|
|
|
694
734
|
metadata_info['version_sw'] = None
|
|
695
735
|
metadata_info['project'] = None
|
|
696
736
|
RQMClient.config(args.testplan, metadata_info['version_sw'],
|
|
697
|
-
metadata_info['project'], args.createmissing, args.updatetestcase
|
|
737
|
+
metadata_info['project'], args.createmissing, args.updatetestcase,
|
|
738
|
+
args.testsuite, stream=args.stream, baseline=args.baseline)
|
|
739
|
+
|
|
740
|
+
if args.testsuite == "new":
|
|
741
|
+
# Create new testsuite
|
|
742
|
+
if not args.dryrun:
|
|
743
|
+
testsuite_data = RQMClient.createTestsuiteTemplate(result.suite.name, result.suite.doc)
|
|
744
|
+
res_testsuite = RQMClient.createResource('testsuite', testsuite_data)
|
|
745
|
+
else:
|
|
746
|
+
# for dryrun
|
|
747
|
+
res_testsuite = {'success': True, 'id': 1111}
|
|
748
|
+
|
|
749
|
+
if res_testsuite['success']:
|
|
750
|
+
_ts_id = res_testsuite['id']
|
|
751
|
+
Logger.log(f"Create testsuite '{result.suite.name}' with ID '{_ts_id}' successfully!")
|
|
752
|
+
RQMClient.testsuite['id'] = _ts_id
|
|
753
|
+
RQMClient.testsuite['name'] = result.suite.name
|
|
754
|
+
else:
|
|
755
|
+
Logger.log_error(f"Create testsuite '{result.suite.name}' failed. Reason: {res_testsuite['message']}", fatal_error=True)
|
|
756
|
+
|
|
698
757
|
# Process suite for importing
|
|
699
758
|
process_suite(RQMClient, result.suite)
|
|
700
759
|
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
760
|
+
if RQMClient.testsuite['id']:
|
|
761
|
+
if not args.dryrun:
|
|
762
|
+
# Create testsuite execution record if requires
|
|
763
|
+
testsuite_record_data = RQMClient.createTSERTemplate(RQMClient.testsuite['id'], RQMClient.testsuite['name'], args.testplan, RQMClient.configuration)
|
|
764
|
+
res_TSER = RQMClient.createResource('suiteexecutionrecord', testsuite_record_data)
|
|
765
|
+
sTSERID = res_TSER['id']
|
|
766
|
+
Logger.log()
|
|
767
|
+
if res_TSER['success']:
|
|
768
|
+
Logger.log(f"Create TSER with id {sTSERID} successfully!")
|
|
769
|
+
elif (res_TSER['status_code'] == 303 or res_TSER['status_code'] == 200) and res_TSER['id'] != '':
|
|
770
|
+
### incase executionworkitem is existing, cannot create new one
|
|
771
|
+
### Use the existing ID for new result
|
|
772
|
+
Logger.log_warning(f"TSER for testsuite {RQMClient.testsuite['id']} is existing.\nAdd this execution result to existing TSER id: {sTSERID}")
|
|
773
|
+
else:
|
|
774
|
+
Logger.log_error(f"Create TSER failed, {res_TSER['message']}")
|
|
775
|
+
|
|
776
|
+
# Create new testsuite result and link all TCERs
|
|
777
|
+
testsuite_result_data = RQMClient.createTestsuiteResultTemplate(RQMClient.testsuite['id'],
|
|
778
|
+
RQMClient.testsuite['name'],
|
|
779
|
+
sTSERID,
|
|
780
|
+
RQMClient.lTCERIDs,
|
|
781
|
+
RQMClient.lTCResultIDs,
|
|
782
|
+
DRESULT_MAPPING[result.suite.status]
|
|
783
|
+
)
|
|
784
|
+
res_TSLog = RQMClient.createResource('testsuitelog', testsuite_result_data)
|
|
785
|
+
sSuiteResultID = res_TSLog['id']
|
|
786
|
+
if res_TSLog['success']:
|
|
787
|
+
Logger.log(f"Created testsuite result with id {sSuiteResultID} successfully.", indent=2)
|
|
788
|
+
else:
|
|
789
|
+
Logger.log_error(f"Create testsuite result failed, {res_TSLog['message']}", indent=2)
|
|
790
|
+
else:
|
|
791
|
+
Logger.log(f"Create TSER")
|
|
792
|
+
Logger.log(f"Created testsuite result")
|
|
793
|
+
|
|
794
|
+
# Link all imported testcase ID(s) with testsuite
|
|
795
|
+
try:
|
|
796
|
+
RQMClient.linkListTestcase2Testsuite(RQMClient.testsuite['id'])
|
|
797
|
+
Logger.log(f"Link all imported test cases with testsuite {RQMClient.testsuite['id']} successfully.")
|
|
798
|
+
except Exception as reason:
|
|
799
|
+
Logger.log_error(f"Link all imported test cases with testsuite failed.\nReason: {reason}", fatal_error=True)
|
|
800
|
+
|
|
801
|
+
# Add testsuite to given testplan
|
|
802
|
+
try:
|
|
803
|
+
RQMClient.addTestsuite2Testplan(args.testplan)
|
|
804
|
+
Logger.log(f"Add testsuite {RQMClient.testsuite['id']} to testplan {args.testplan} successfully.")
|
|
805
|
+
except Exception as reason:
|
|
806
|
+
Logger.log_error(f"Add testsuite to testplan failed.\nReason: {reason}", fatal_error=True)
|
|
704
807
|
|
|
808
|
+
else:
|
|
809
|
+
# Link all imported testcase ID(s) with testplan
|
|
810
|
+
try:
|
|
811
|
+
RQMClient.linkListTestcase2Testplan(args.testplan)
|
|
812
|
+
Logger.log(f"Link all imported test cases with testplan {args.testplan} successfully.")
|
|
813
|
+
except Exception as reason:
|
|
814
|
+
Logger.log_error(f"Link all imported test cases with testplan failed.\nReason: {reason}", fatal_error=True)
|
|
815
|
+
|
|
705
816
|
# Update testcase(s) with generated ID(s)
|
|
706
817
|
# Under developing
|
|
707
818
|
|
|
@@ -710,7 +821,15 @@ Flow to import Robot results to RQM:
|
|
|
710
821
|
|
|
711
822
|
# 5. Disconnect from RQM
|
|
712
823
|
RQMClient.disconnect()
|
|
713
|
-
|
|
824
|
+
|
|
825
|
+
testcnt_msg = f"All {len(RQMClient.lTestcaseIDs)}"
|
|
826
|
+
extended_msg = ""
|
|
827
|
+
if (len(RQMClient.lTestcaseIDs) > len(RQMClient.lTCResultIDs)):
|
|
828
|
+
testcnt_msg = f"{len(RQMClient.lTCResultIDs)} of {len(RQMClient.lTestcaseIDs)}"
|
|
829
|
+
extended_msg = f" {len(RQMClient.lTestcaseIDs)-len(RQMClient.lTCResultIDs)} test results are skipped because of errors."
|
|
830
|
+
|
|
831
|
+
Logger.log()
|
|
832
|
+
Logger.log(f"{testcnt_msg} test results are imported to RQM successfully.{extended_msg}")
|
|
714
833
|
|
|
715
834
|
if __name__=="__main__":
|
|
716
835
|
RobotLog2RQM()
|
RobotLog2RQM/version.py
CHANGED
{robotframework_robotlog2rqm-1.2.4.dist-info → robotframework_robotlog2rqm-1.4.0.dist-info}/METADATA
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: robotframework-robotlog2rqm
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.4.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
|
|
@@ -132,33 +132,40 @@ Use below command to get tools\'s usage:
|
|
|
132
132
|
|
|
133
133
|
The usage should be showed as below:
|
|
134
134
|
|
|
135
|
-
usage: RobotLog2RQM (RobotXMLResult to RQM importer) [-h] [-v] [--recursive]
|
|
136
|
-
|
|
137
|
-
|
|
135
|
+
usage: RobotLog2RQM (RobotXMLResult to RQM importer) [-h] [-v] [--testsuite TESTSUITE] [--recursive]
|
|
136
|
+
[--createmissing] [--updatetestcase] [--dryrun] [--stream STREAM] [--baseline BASELINE]
|
|
137
|
+
resultxmlfile host project user password testplan
|
|
138
138
|
|
|
139
|
-
RobotLog2RQM imports XML result files (default: output.xml) generated by the
|
|
139
|
+
RobotLog2RQM imports XML result files (default: output.xml) generated by the
|
|
140
140
|
Robot Framework into an IBM Rational Quality Manager.
|
|
141
141
|
|
|
142
142
|
positional arguments:
|
|
143
|
-
resultxmlfile
|
|
144
|
-
|
|
145
|
-
host
|
|
146
|
-
project
|
|
147
|
-
user
|
|
148
|
-
password
|
|
149
|
-
testplan
|
|
143
|
+
resultxmlfile absolute or relative path to the xml result file
|
|
144
|
+
or directory of result files to be imported.
|
|
145
|
+
host RQM host url.
|
|
146
|
+
project project on RQM.
|
|
147
|
+
user user for RQM login.
|
|
148
|
+
password password for RQM login.
|
|
149
|
+
testplan testplan ID for this execution.
|
|
150
150
|
|
|
151
151
|
optional arguments:
|
|
152
|
-
-h, --help
|
|
153
|
-
-v, --version
|
|
154
|
-
--
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
152
|
+
-h, --help show this help message and exit
|
|
153
|
+
-v, --version Version of the RobotLog2RQM importer.
|
|
154
|
+
--testsuite TESTSUITE
|
|
155
|
+
testsuite ID for this execution. If 'new', then create a new
|
|
156
|
+
testsuite for this execution.
|
|
157
|
+
--recursive if set, then the path is searched recursively for
|
|
158
|
+
log files to be imported.
|
|
159
|
+
--createmissing if set, then all testcases without tcid are created
|
|
160
|
+
when importing.
|
|
161
|
+
--updatetestcase if set, then testcase information on RQM will be updated
|
|
162
|
+
bases on robot testfile.
|
|
163
|
+
--dryrun if set, then verify all input arguments
|
|
164
|
+
(includes RQM authentication) and show what would be done.
|
|
165
|
+
--stream STREAM project stream. Note, requires Configuration Management (CM)
|
|
166
|
+
to be enabled for the project area.
|
|
167
|
+
--baseline BASELINE project baseline. Note, requires Configuration Management (CM),
|
|
168
|
+
or Baselines Only to be enabled for the project area.
|
|
162
169
|
|
|
163
170
|
The below command is simple usage witth all required arguments to import
|
|
164
171
|
Robot Framework results into RQM:
|
{robotframework_robotlog2rqm-1.2.4.dist-info → robotframework_robotlog2rqm-1.4.0.dist-info}/RECORD
RENAMED
|
@@ -1,19 +1,20 @@
|
|
|
1
|
-
RobotLog2RQM/CRQM.py,sha256=
|
|
2
|
-
RobotLog2RQM/RobotLog2RQM.pdf,sha256=
|
|
1
|
+
RobotLog2RQM/CRQM.py,sha256=GbxmrYflkWbY0Fo2BVh3GjMlnXcrGAH43ML-wKBXZgQ,61275
|
|
2
|
+
RobotLog2RQM/RobotLog2RQM.pdf,sha256=NThOpMfAIV1uVVREK1vCrUv2a6dyBNB35fKsi_RB8dA,317424
|
|
3
3
|
RobotLog2RQM/__init__.py,sha256=YKDTJjDsnQkr5X-gjjO8opwKUVKm6kc8sIUpURYMk48,596
|
|
4
4
|
RobotLog2RQM/__main__.py,sha256=JabttEncy80antJWeGVmjoXyiF1DyXxkxdW4xLuHzT0,681
|
|
5
|
-
RobotLog2RQM/robotlog2rqm.py,sha256=
|
|
6
|
-
RobotLog2RQM/version.py,sha256=
|
|
5
|
+
RobotLog2RQM/robotlog2rqm.py,sha256=ZcLWAtxdNQU8emzwodaV2pl62VKatpVJOo5CF-JDw64,29645
|
|
6
|
+
RobotLog2RQM/version.py,sha256=5VtcZiEhD8N84tPIQQGf2bUl3sghf68iEDTEdA4K7Q8,917
|
|
7
7
|
RobotLog2RQM/RQM_templates/buildrecord.xml,sha256=uGot7pNOjPR8do0JsJi0Lz3OCU9NMhODRd428QgvHh4,1498
|
|
8
8
|
RobotLog2RQM/RQM_templates/configuration.xml,sha256=NrFDv51fuGhgeMiZuRhQ5q_UJ0u_pWzdxisIF5AJs74,1378
|
|
9
9
|
RobotLog2RQM/RQM_templates/executionresult.xml,sha256=WTp4qDk29peBc0ll6GHVXX_kF_YBsOVjy9vBzoz7_2k,2160
|
|
10
10
|
RobotLog2RQM/RQM_templates/executionworkitem.xml,sha256=3GYO-nvXcG-HDQZnDzGwYZSQOWAUNckT3_GUa8Ze2Eo,1511
|
|
11
11
|
RobotLog2RQM/RQM_templates/suiteexecutionrecord.xml,sha256=9GAs2WqZMkFJSNEZULm9BJvQy02dl_2JMecpQPHGTPA,1389
|
|
12
12
|
RobotLog2RQM/RQM_templates/testcase.xml,sha256=zovFKj-37QHn2S8mMA_9RnAJ3zBmDJkJj31yelsnFFI,2167
|
|
13
|
+
RobotLog2RQM/RQM_templates/testsuite.xml,sha256=r2ijEsyPoE7qzCtUxgIHDOEcqUveDN4SMf9HSE9b0ZU,1326
|
|
13
14
|
RobotLog2RQM/RQM_templates/testsuitelog.xml,sha256=l-NlaCyk6Ben76PElXKOHfMlEvyQ-e9MOZ6-F9HvwDQ,1920
|
|
14
|
-
robotframework_robotlog2rqm-1.
|
|
15
|
-
robotframework_robotlog2rqm-1.
|
|
16
|
-
robotframework_robotlog2rqm-1.
|
|
17
|
-
robotframework_robotlog2rqm-1.
|
|
18
|
-
robotframework_robotlog2rqm-1.
|
|
19
|
-
robotframework_robotlog2rqm-1.
|
|
15
|
+
robotframework_robotlog2rqm-1.4.0.dist-info/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
|
|
16
|
+
robotframework_robotlog2rqm-1.4.0.dist-info/METADATA,sha256=ulY-9zs6RoMKgk0mx9QkVt_QEvSxkMy2DpqbuxJTeZc,9951
|
|
17
|
+
robotframework_robotlog2rqm-1.4.0.dist-info/WHEEL,sha256=eOLhNAGa2EW3wWl_TU484h7q1UNgy0JXjjoqKoxAAQc,92
|
|
18
|
+
robotframework_robotlog2rqm-1.4.0.dist-info/entry_points.txt,sha256=-Xug2kDJW2LtcSADEVPtCwa337twCy2iGh5aK7xApHA,73
|
|
19
|
+
robotframework_robotlog2rqm-1.4.0.dist-info/top_level.txt,sha256=jb_Gt6W44FoOLtGfBe7RzqCLaquhihkEWvSI1zjXDHc,13
|
|
20
|
+
robotframework_robotlog2rqm-1.4.0.dist-info/RECORD,,
|
{robotframework_robotlog2rqm-1.2.4.dist-info → robotframework_robotlog2rqm-1.4.0.dist-info}/LICENSE
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|