Lib.robot.running.outputcapture.py Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of sikulixapi Show documentation
Show all versions of sikulixapi Show documentation
... for visual testing and automation
# Copyright 2008-2015 Nokia Solutions and Networks
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import sys
from robot.utils import StringIO
from robot.output import LOGGER
from robot.utils import console_decode, console_encode, JYTHON
class OutputCapturer(object):
def __init__(self, library_import=False):
self._library_import = library_import
self._python_out = PythonCapturer(stdout=True)
self._python_err = PythonCapturer(stdout=False)
self._java_out = JavaCapturer(stdout=True)
self._java_err = JavaCapturer(stdout=False)
def __enter__(self):
if self._library_import:
LOGGER.enable_library_import_logging()
return self
def __exit__(self, exc_type, exc_value, exc_trace):
self._release_and_log()
if self._library_import:
LOGGER.disable_library_import_logging()
return False
def _release_and_log(self):
stdout, stderr = self._release()
if stdout:
LOGGER.log_output(stdout)
if stderr:
LOGGER.log_output(stderr)
sys.__stderr__.write(console_encode(stderr, stream=sys.__stderr__))
def _release(self):
stdout = self._python_out.release() + self._java_out.release()
stderr = self._python_err.release() + self._java_err.release()
return stdout, stderr
class PythonCapturer(object):
def __init__(self, stdout=True):
if stdout:
self._original = sys.stdout
self._set_stream = self._set_stdout
else:
self._original = sys.stderr
self._set_stream = self._set_stderr
self._stream = StringIO()
self._set_stream(self._stream)
def _set_stdout(self, stream):
sys.stdout = stream
def _set_stderr(self, stream):
sys.stderr = stream
def release(self):
# Original stream must be restored before closing the current
self._set_stream(self._original)
try:
return self._get_value(self._stream)
finally:
self._stream.close()
self._avoid_at_exit_errors(self._stream)
def _get_value(self, stream):
try:
return console_decode(stream.getvalue())
except UnicodeError:
# Error occurs if non-ASCII chars logged both as str and unicode.
stream.buf = console_decode(stream.buf)
stream.buflist = [console_decode(item) for item in stream.buflist]
return stream.getvalue()
def _avoid_at_exit_errors(self, stream):
# Avoid ValueError at program exit when logging module tries to call
# methods of streams it has intercepted that are already closed.
# Which methods are called, and does logging silence possible errors,
# depends on Python/Jython version. For related discussion see
# http://bugs.python.org/issue6333
stream.write = lambda s: None
stream.flush = lambda: None
if not JYTHON:
class JavaCapturer(object):
def __init__(self, stdout=True):
pass
def release(self):
return u''
else:
from java.io import ByteArrayOutputStream, PrintStream
from java.lang import System
class JavaCapturer(object):
def __init__(self, stdout=True):
if stdout:
self._original = System.out
self._set_stream = System.setOut
else:
self._original = System.err
self._set_stream = System.setErr
self._bytes = ByteArrayOutputStream()
self._stream = PrintStream(self._bytes, False, 'UTF-8')
self._set_stream(self._stream)
def release(self):
# Original stream must be restored before closing the current
self._set_stream(self._original)
self._stream.close()
output = self._bytes.toString('UTF-8')
self._bytes.reset()
return output
© 2015 - 2025 Weber Informatics LLC | Privacy Policy