Skip to content

Commit c17aa64

Browse files
made TestRobot compatible with robotframework 3.0, which implicitly fixes compatibility for RemoteRobot and robotshell
--HG-- branch : dev
1 parent 3582a5b commit c17aa64

3 files changed

Lines changed: 52 additions & 26 deletions

File tree

robottools/testrobot/__init__.py

Lines changed: 37 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -23,27 +23,27 @@
2323
2424
.. moduleauthor:: Stefan Zimmermann <zimmermann.code@gmail.com>
2525
"""
26-
from six import reraise
27-
28-
__all__ = ['TestRobot',
29-
'TestResult', # from .result
30-
]
26+
__all__ = [
27+
'TestRobot',
28+
'TestResult', # from .result
29+
]
3130

31+
from six import reraise
3232
from inspect import getargspec
3333
from functools import partial
3434

3535
from moretools import isidentifier
3636

3737
from robot.errors import DataError
38-
from robot.model import TestSuite
3938
from robot.conf import RobotSettings
39+
from robot.running.model import TestSuite
40+
from robot.running.namespace import Namespace
41+
from robot.running.runner import Runner
42+
from robot.running import TestSuiteBuilder
4043
try:
4144
from robot.variables import GLOBAL_VARIABLES, init_global_variables
4245
except ImportError: # Robot 2.9
4346
from robot.variables import VariableScopes
44-
from robot.running.namespace import Namespace
45-
from robot.running.runner import Runner
46-
from robot.running import TestSuiteBuilder
4747

4848
from robottools import TestLibraryInspector
4949

@@ -76,25 +76,36 @@ def __init__(self, name, BuiltIn=True, variable_getters=None):
7676
self.debug = False
7777
try:
7878
GLOBAL_VARIABLES
79-
except NameError: # Robot 2.9
79+
except NameError:
80+
# Robot 2.9+
8081
self._variables = VariableScopes(RobotSettings())
8182
else:
82-
if not GLOBAL_VARIABLES: #HACK
83+
# Robot 2.8
84+
if not GLOBAL_VARIABLES: # HACK
8385
init_global_variables(RobotSettings())
8486
self._variables = GLOBAL_VARIABLES.copy()
85-
#HACK even more to extend variable lookup:
87+
# HACK even more to extend variable lookup
8688
self._variables.__class__ = variablesclass(
87-
self._variables.__class__, extra_getters=variable_getters)
89+
self._variables.__class__, extra_getters=variable_getters)
90+
8891
self._output = Output()
8992
self._context = Context(testrobot=self)
9093
self._suite = TestSuite(name)
91-
namespace = partial(Namespace,
92-
suite=self._suite, variables=self._variables,
93-
user_keywords=[], imports=None)
94-
if 'parent_variables' in getargspec(Namespace.__init__).args:
95-
self._namespace = namespace(parent_variables=None)
96-
else: # Robot 2.9
97-
self._namespace = namespace()
94+
95+
argspec = getargspec(Namespace.__init__)
96+
namespace = partial(
97+
Namespace, suite=self._suite, variables=self._variables)
98+
if 'resource' in argspec.args:
99+
# Robot 3.0
100+
self._namespace = namespace(resource=self._suite.resource)
101+
else:
102+
namespace.keywords.update(user_keywords=[], imports=None)
103+
if 'parent_variables' in argspec.args:
104+
# Robot 2.8
105+
self._namespace = namespace(parent_variables=None)
106+
else:
107+
# Robot 2.9
108+
self._namespace = namespace()
98109

99110
if BuiltIn:
100111
self.Import('BuiltIn')
@@ -115,8 +126,8 @@ def __doc__(self):
115126
"""Dynamic doc string, listing imported Test Libraries.
116127
"""
117128
return '%s\n\n%s' % (repr(self), '\n\n'.join(sorted(
118-
'* [Import] ' + lib.name
119-
for alias, lib in self._libraries.items())))
129+
'* [Import] ' + lib.name
130+
for alias, lib in self._libraries.items())))
120131

121132
def Import(self, lib, args=None, alias=None):
122133
"""Import a Test Library with an optional `alias` name.
@@ -125,8 +136,8 @@ def Import(self, lib, args=None, alias=None):
125136
#HACK: `with` adds Context to robot.running.EXECUTION_CONTEXTS
126137
# and registers Output to robot.output.LOGGER
127138
with self._context:
128-
lib = self._context.importer.import_library(lib,
129-
args and list(args), alias, None)
139+
lib = self._context.importer.import_library(
140+
lib, args and list(args), alias, None)
130141
self._libraries[alias or lib.name] = lib
131142
lib = TestLibraryInspector(lib)
132143
## lib = TestLibraryInspector(lib, *(args or ()))
@@ -189,8 +200,8 @@ def __getattr__(self, name):
189200
return self._variables['${%s}' % name]
190201
except DataError:
191202
raise AttributeError(
192-
"No Test Library, Keyword or Variable named '%s'."
193-
% name)
203+
"No Test Library, Keyword or Variable named '%s'."
204+
% name)
194205

195206
def __dir__(self):
196207
"""List all Robot Variables (UPPER_CASE),

robottools/testrobot/context.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ def __init__(self, testrobot):
3838
self.in_teardown = False
3939
self.test = None
4040
self.importer = Importer()
41+
self.timeouts = set()
4142

4243
def __enter__(self):
4344
"""Prepare the TestRobot's context
@@ -84,6 +85,10 @@ def get_handler(self, name):
8485
repr(self.testrobot.name), repr(name)))
8586
return keyword._handler
8687

88+
def get_runner(self, name):
89+
handler = self.get_handler(name)
90+
return handler.create_runner(name)
91+
8792
def start_keyword(self, keyword):
8893
pass
8994

robottools/testrobot/output.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,10 @@
3030
from robot.output import LOGGER, LEVELS as LOG_LEVELS
3131
from robot.output.loggerhelper import AbstractLogger
3232
from robot.output.pyloggingconf import RobotHandler
33+
try: # Robot 3.0
34+
from robot.output.listeners import LibraryListeners
35+
except ImportError:
36+
LibraryListeners = None
3337

3438
from .highlighting import Highlighter
3539

@@ -61,11 +65,17 @@ class Output(AbstractLogger):
6165
def __init__(self, log_level='INFO'):
6266
AbstractLogger.__init__(self, level=log_level)
6367
self.logging_handler = LoggingHandler()
68+
if LibraryListeners is not None:
69+
# Robot 3.0
70+
self.library_listeners = LibraryListeners(log_level)
6471
# streams to be used internally for writing messages
6572
# - see self.__enter__() and self.message()
6673
self._out = self._err = None
6774

6875
def set_log_level(self, level):
76+
if LibraryListeners is not None:
77+
# Robot 3.0
78+
self.library_listeners.set_log_level(level)
6979
return self.set_level(level)
7080

7181
def __enter__(self):

0 commit comments

Comments
 (0)