Skip to content

Commit 98c1110

Browse files
authored
Merge pull request #47 from eficode/feat/rf-metadata
Add support for RF metadata from handlers. Fixes #40
2 parents ffed224 + 0980cc0 commit 98c1110

7 files changed

Lines changed: 76 additions & 17 deletions

File tree

src/oxygen/oxygen_handler_result.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212

1313
import functools
1414

15-
from typing import List
15+
from typing import List, Dict
1616
# TODO FIXME: Python 3.10 requires these to be imported from here
1717
# Python 3.10 EOL is in 2026
1818
from typing_extensions import TypedDict, Required
@@ -45,6 +45,7 @@ class OxygenSuiteDict(TypedDict, total=False):
4545
tags: List[str]
4646
setup: OxygenKeywordDict
4747
teardown: OxygenKeywordDict
48+
metadata: Dict[str, str]
4849
suites: List['OxygenSuiteDict']
4950
tests: List[OxygenTestCaseDict]
5051

src/oxygen/robot3_interface.py

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ def build_suite(self, starting_time, suite):
4444
teardown_keyword = suite.get('teardown') or None
4545
child_suites = suite.get('suites') or []
4646
tests = suite.get('tests') or []
47+
metadata = suite.get('metadata') or {}
4748

4849
updated_time, robot_setup = self.build_keyword(updated_time, setup_keyword, setup=True)
4950
updated_time, robot_teardown = self.build_keyword(updated_time, teardown_keyword, teardown=True)
@@ -57,7 +58,8 @@ def build_suite(self, starting_time, suite):
5758
robot_setup,
5859
robot_teardown,
5960
robot_suites,
60-
robot_tests)
61+
robot_tests,
62+
metadata)
6163

6264
return updated_time, robot_suite
6365

@@ -70,13 +72,15 @@ def spawn_robot_suite(self,
7072
setup_keyword,
7173
teardown_keyword,
7274
suites,
73-
tests):
75+
tests,
76+
metadata):
7477
start_timestamp = self.ms_to_timestamp(start_time)
7578
end_timestamp = self.ms_to_timestamp(end_time)
7679

7780
robot_suite = RobotResultSuite(name,
7881
starttime=start_timestamp,
79-
endtime=end_timestamp)
82+
endtime=end_timestamp,
83+
metadata=metadata)
8084
robot_suite.set_tags(add=tags, persist=True)
8185

8286
if setup_keyword:
@@ -342,9 +346,15 @@ def create_wrapper_keyword(self,
342346

343347
class RobotRunningInterface(object):
344348
def build_suite(self, parsed_results):
345-
robot_root_suite = RobotRunningSuite(parsed_results['name'])
349+
robot_root_suite = RobotRunningSuite(
350+
parsed_results['name'],
351+
metadata=parsed_results.get('metadata', {})
352+
)
346353
for parsed_suite in parsed_results.get('suites', []):
347-
robot_suite = robot_root_suite.suites.create(parsed_suite['name'])
354+
robot_suite = robot_root_suite.suites.create(
355+
parsed_suite['name'],
356+
metadata=parsed_results.get('metadata', {})
357+
)
348358
for subsuite in parsed_suite.get('suites', []):
349359
robot_subsuite = self.build_suite(subsuite)
350360
robot_suite.suites.append(robot_subsuite)

src/oxygen/robot4_interface.py

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ def build_suite(self, starting_time, suite):
4343
teardown_keyword = suite.get('teardown') or None
4444
child_suites = suite.get('suites') or []
4545
tests = suite.get('tests') or []
46+
metadata = suite.get('metadata') or {}
4647

4748
updated_time, robot_setup = self.build_keyword(updated_time, setup_keyword, setup=True)
4849
updated_time, robot_teardown = self.build_keyword(updated_time, teardown_keyword, teardown=True)
@@ -56,7 +57,8 @@ def build_suite(self, starting_time, suite):
5657
robot_setup,
5758
robot_teardown,
5859
robot_suites,
59-
robot_tests)
60+
robot_tests,
61+
metadata)
6062

6163
return updated_time, robot_suite
6264

@@ -69,13 +71,15 @@ def spawn_robot_suite(self,
6971
setup_keyword,
7072
teardown_keyword,
7173
suites,
72-
tests):
74+
tests,
75+
metadata):
7376
start_timestamp = self.ms_to_timestamp(start_time)
7477
end_timestamp = self.ms_to_timestamp(end_time)
7578

7679
robot_suite = RobotResultSuite(name,
7780
starttime=start_timestamp,
78-
endtime=end_timestamp)
81+
endtime=end_timestamp,
82+
metadata=metadata)
7983
robot_suite.set_tags(add=tags, persist=True)
8084

8185
if setup_keyword:
@@ -342,9 +346,15 @@ def create_wrapper_keyword(self,
342346

343347
class RobotRunningInterface(object):
344348
def build_suite(self, parsed_results):
345-
robot_root_suite = RobotRunningSuite(parsed_results['name'])
349+
robot_root_suite = RobotRunningSuite(
350+
parsed_results['name'],
351+
metadata=parsed_results.get('metadata', {})
352+
)
346353
for parsed_suite in parsed_results.get('suites', []):
347-
robot_suite = robot_root_suite.suites.create(parsed_suite['name'])
354+
robot_suite = robot_root_suite.suites.create(
355+
parsed_suite['name'],
356+
metadata=parsed_suite.get('metadata', {})
357+
)
348358
for subsuite in parsed_suite.get('suites', []):
349359
robot_subsuite = self.build_suite(subsuite)
350360
robot_suite.suites.append(robot_subsuite)

tests/utest/helpers.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,9 @@ class _TCSubclass(OxygenTestCaseDict):
7979
'''Used in test cases'''
8080
pass
8181

82+
class _StrSubclass(str):
83+
'''Used in test cases'''
84+
pass
8285

8386
GATLING_EXPECTED_OUTPUT = {'name': 'Gatling Scenario',
8487
'tags': ['GATLING'],

tests/utest/oxygen_handler_result/shared_tests.py

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,12 @@
11
from ..helpers import (MINIMAL_KEYWORD_DICT,
22
_ListSubclass,
3+
_StrSubclass,
34
_KwSubclass)
45

56
class SharedTestsForName(object):
67
def shared_test_for_name(self):
7-
class StrSubclass(str):
8-
pass
9-
valid_inherited = StrSubclass('someKeyword')
10-
this_is_not_None = StrSubclass(None)
8+
valid_inherited = _StrSubclass('someKeyword')
9+
this_is_not_None = _StrSubclass(None)
1110

1211
self.valid_inputs_for('name',
1312
'',

tests/utest/oxygen_handler_result/test_OxygenSuiteDict.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
from ..helpers import (MINIMAL_TC_DICT,
77
MINIMAL_SUITE_DICT,
88
_ListSubclass,
9+
_StrSubclass,
910
_TCSubclass)
1011
from .shared_tests import (SharedTestsForName,
1112
SharedTestsForKeywordField,
@@ -79,3 +80,22 @@ def test_validate_oxygen_suite_validates_tests(self):
7980

8081

8182
self.invalid_inputs_for('tests', None, [ {} ])
83+
84+
def test_validate_oxygen_suite_validates_metadata(self):
85+
class DictSubclass(dict):
86+
pass
87+
inherited_key = _StrSubclass('key')
88+
89+
this_is_not_None = _StrSubclass(None)
90+
91+
self.valid_inputs_for('metadata',
92+
{},
93+
{'': ''},
94+
{'key': 'value'},
95+
{_StrSubclass('key'): _StrSubclass('value')},
96+
DictSubclass(inherited_key=_StrSubclass('value')),
97+
{this_is_not_None: 'value'})
98+
99+
self.invalid_inputs_for('metadata',
100+
{'key': None},
101+
{'key': 1234},)

tests/utest/robot_interface/test_robot_interface_basic_usage.py

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
EXAMPLE_SUITES = [{
1414
'name': 'suite1',
1515
'setup': [],
16+
'metadata': {'metadata-key': 'metadata-value'},
1617
'suites': [{'name': 'suite2',
1718
'setup': {'elapsed': 0.0,
1819
'keywords': [],
@@ -152,9 +153,12 @@ class RobotInterfaceBasicTests(TestCase):
152153
def setUp(self):
153154
self.iface = RobotInterface()
154155

156+
def now(self):
157+
return int(round(time() * 1000))
158+
155159
def test_result_build_suites(self):
156-
now = int(round(time() * 1000))
157-
_, converted = self.iface.result.build_suites(now, *EXAMPLE_SUITES)
160+
_, converted = self.iface.result.build_suites(self.now(),
161+
*EXAMPLE_SUITES)
158162

159163
self.assertIsInstance(converted, list)
160164
self.assertEqual(len(converted), 2)
@@ -199,6 +203,14 @@ def test_result_create_wrapper_keyword_for_setup(self):
199203
from robot.model import BodyItem
200204
self.assertEqual(ret.type, BodyItem.SETUP)
201205

206+
def validate_metadata(self, actual):
207+
self.assertEqual(actual.name, EXAMPLE_SUITES[0]['name'])
208+
self.assertEqual(dict(actual.metadata), EXAMPLE_SUITES[0]['metadata'])
209+
210+
def test_result_build_suite_with_metadata(self):
211+
_, ret = self.iface.result.build_suite(self.now(), EXAMPLE_SUITES[0])
212+
self.validate_metadata(ret)
213+
202214
def test_result_create_wrapper_keyword_for_teardown(self):
203215
ret = self.iface.result.create_wrapper_keyword('My Wrapper',
204216
'20200507 13:42:50.001',
@@ -219,3 +231,7 @@ def test_running_build_suite(self):
219231

220232
self.assertIsInstance(ret, RobotRunningSuite)
221233
self.assertEqual(ret.name, EXAMPLE_SUITES[1]['name'])
234+
235+
def test_running_build_suite_with_metadata(self):
236+
ret = self.iface.running.build_suite(EXAMPLE_SUITES[0])
237+
self.validate_metadata(ret)

0 commit comments

Comments
 (0)