def _single_result(source, options): result = Result(source, rpa=options.pop('rpa', None)) if source.upper().endswith("JSON"): try: with open(source, 'r') as source_file: json_data = json.load(source_file) return JsonExecutionResultBuilder(json_data, **options).build(result) except IOError as err: error = err.strerror except Exception: traceback.print_exc() error = get_error_message() raise DataError("Reading JSON source '%s' failed: %s" % (unic(json_data), error)) else: ets = ETSource(source) try: return XmlExecutionResultBuilder(ets, **options).build(result) except IOError as err: error = err.strerror except: error = get_error_message() raise DataError("Reading XML source '%s' failed: %s" % (unic(ets), error))
def _create_output_dir(self, path, type_): try: if not os.path.exists(path): os.makedirs(path) except: raise DataError("Can't create %s file's parent directory '%s': %s" % (type_.lower(), path, utils.get_error_message()))
def end_keyword(self, name: str, attributes: Dict[str, Union[str, List[str]]]) -> None: """Do additional actions after keyword ends. Update current Keyword model. For keywords with type "BEFORE_SUITE" and "AFTER_SUITE" send logs to Report Portal. Args: name: keyword name. attributes: keyword attributes. """ self.keyword.update(attributes=attributes) if self.keyword.is_setup_or_teardown: error_message = get_error_message() message = { "message": error_message, "level": "FAIL", "timestamp": self.keyword.end_time } if self.keyword.status == "FAIL": message = self._prepare_message(message=message) self.keyword.messages.append(message) elif "Skip tests:" in error_message: self.keyword.status = "SKIP" message["level"] = "WARN" message = self._prepare_message(message=message) self.keyword.messages.append(message) if self.keyword.rp_item_type in ["BEFORE_SUITE", "AFTER_SUITE"]: self._rp_log_fixture_keyword(keyword=self.keyword) self._current_scope = self.keyword.parent if isinstance(self.current_scope, Keyword): self._keyword = self.current_scope
class ExtendedFinder(object): _extended_var_re = re.compile( r''' ^\${ # start of the string and "${" (.+?) # base name (group 1) ([^\s\w].+) # extended part (group 2) }$ # "}" and end of the string ''', re.UNICODE | re.VERBOSE) def __init__(self, variables): self._variables = variables def find(self, name): res = self._extended_var_re.search(name) if res is None: raise ValueError base_name = res.group(1) expression = res.group(2) try: variable = self._variables['${%s}' % base_name] except DataError, err: raise DataError("Resolving variable '%s' failed: %s" % (name, unicode(err))) try: return eval('_BASE_VAR_' + expression, {'_BASE_VAR_': variable}) except: raise DataError("Resolving variable '%s' failed: %s" % (name, get_error_message()))
def _convert(self, value, explicit_type=True): try: return self.converter_info.converter(value) except ValueError: raise except Exception: raise ValueError(get_error_message())
def _open(self, path): if not os.path.isfile(path): raise DataError("Data source does not exist.") try: return open(path, 'rb') except: raise DataError(get_error_message())
def _convert(self, value, explicit_type=True): if not explicit_type: return value try: return unicode(value) except Exception: raise ValueError(get_error_message())
def _get_outfile(self, outpath, outtype): if outpath != 'NONE': try: return open(outpath, 'wb') except: LOGGER.error("Opening %s file '%s' for writing failed: %s" % (outtype, outpath, utils.get_error_message())) return None
def _create_output_dir(self, path, type_): try: if not os.path.exists(path): os.makedirs(path) except: raise DataError( "Can't create %s file's parent directory '%s': %s" % (type_.lower(), path, utils.get_error_message()))
def _handle_imports(self, import_settings): for item in import_settings: try: if not item.name: raise DataError('%s setting requires a name' % item.type) self._import(item) except: item.report_invalid_syntax(utils.get_error_message())
def __call__(self, *args): if not self._method: return self._default try: return self._method(*args) except: raise DataError("Calling dynamic method '%s' failed: %s" % (self._method.__name__, utils.get_error_message()))
def _get_range_items(self, items): try: items = [self._to_number_with_arithmetics(item) for item in items] except: raise DataError("Converting argument of FOR IN RANGE failed: %s" % get_error_message()) if not 1 <= len(items) <= 3: raise DataError("FOR IN RANGE expected 1-3 arguments, " "got %d instead." % len(items)) return frange(*items)
def populate(self, source): """ Populate from the string """ LOGGER.info("Parsing string '%s'." % source) try: RobotReader().read(BytesIO(source.encode("utf-8")), self) except Exception: raise DataError(get_error_message())
def _get_writer(self, path, attrs={}): try: writer = utils.XmlWriter(path) except: raise DataError("Opening output file '%s' for writing failed: %s" % (path, utils.get_error_message())) writer.start('robot', attrs) return writer
def evaluate(self,expression,modules=None): modules = modules.replace(' ','').split(',') if modules else [] namespace = dict((m, __import__(m)) for m in modules if m !='') try: return eval(expression,namespace) except: raise RuntimeError("evaluating expression '%s' failed: %s" %(expression,utils.get_error_message()))
def _open(self, path): if not os.path.isfile(path): raise DataError("Data source does not exist.") try: # IronPython handles BOM incorrectly if not using binary mode: # http://code.google.com/p/robotframework/issues/detail?id=1580 return open(path, 'rb') except: raise DataError(get_error_message())
def _should_run_handler(self, data, failures, handler, handler_matched, handler_error): if not self._run or handler_matched or handler_error or data.error: return False, None try: return failures and self._error_is_expected(failures, handler), None except: return False, ExecutionFailed(get_error_message())
def _open(self, path): if not os.path.isfile(path): raise DataError("Data source does not exist.") try: # IronPython handles BOM incorrectly if not using binary mode: # https://ironpython.codeplex.com/workitem/34655 return open(path, 'rb') except: raise DataError(get_error_message())
def _get_writer(self, path, generator): try: writer = utils.XmlWriter(path) except: raise DataError("Opening output file '%s' for writing failed: %s" % (path, utils.get_error_message())) writer.start('robot', {'generator': get_full_version(generator), 'generated': utils.get_timestamp()}) return writer
def _convert_to_integer(self,orig,base=None): try: item = self._handle_java_numbers(orig) if base: return int(item,self._convert_to_integer(base)) return int(item) except: raise RuntimeError(" '%s' cannot be converted to an integer:%s" %(orig,utils.get_error_message()))
def _single_result(source, options): ets = ETSource(source) try: return ExecutionResultBuilder(ets, **options).build(Result(source)) except IOError as err: error = err.strerror except: error = get_error_message() raise DataError("Reading XML source '%s' failed: %s" % (unic(ets), error))
def _single_result(source, options): ets = ETSource(source) try: return ExecutionResultBuilder(ets, **options).build(Result(source)) except IOError as err: error = err.strerror except: error = get_error_message() raise DataError("Reading XML source '%s' failed: %s" % (unicode(ets), error))
def populate(self, path): LOGGER.info("Parsing file '%s'." % path) source = self._open(path) try: self._get_reader(path).read(source, self) except: raise DataError(get_error_message()) finally: source.close()
def _get_range_items(self, items): try: items = [self._to_int_with_arithmetics(item) for item in items] except: raise DataError('Converting argument of FOR IN RANGE failed: %s' % get_error_message()) if not 1 <= len(items) <= 3: raise DataError('FOR IN RANGE expected 1-3 arguments, ' 'got %d instead.' % len(items)) return range(*items)
def _single_result(source, options): ets = ETSource(source) result = Result(source, rpa=options.pop('rpa', None)) try: return ExecutionResultBuilder(ets, **options).build(result) except IOError as err: error = err.strerror except: error = get_error_message() raise DataError(f"Reading XML source '{ets}' failed: {error}")
def import_variables(self, path, args=None): LOGGER.info("Importing variable file '%s' with args %s" % (path, args)) importer = Importer('variable file').import_class_or_module_by_path var_file = importer(path, instantiate_with_args=()) try: return self._get_variables(var_file, args) except: amsg = 'with arguments %s ' % seq2str2(args) if args else '' raise DataError("Processing variable file '%s' %sfailed: %s" % (path, amsg, get_error_message()))
def _get_range_items(self, items): try: items = [self._to_int_with_arithmetics(item) for item in items] except: raise DataError('Converting argument of FOR IN RANGE failed: %s' % get_error_message()) if not 1 <= len(items) <= 3: raise DataError('FOR IN RANGE expected 1-3 arguments, ' 'got %d instead.' % len(items)) return list(range(*items))
def _transform_items(self, items): try: items = [self._to_number_with_arithmetics(item) for item in items] except: raise DataError('Converting argument of FOR IN RANGE failed: %s.' % get_error_message()) if not 1 <= len(items) <= 3: raise DataError('FOR IN RANGE expected 1-3 arguments, got %d.' % len(items)) return frange(*items)
def _read(self, path): try: # IronPython handles BOM incorrectly if not using binary mode: # https://ironpython.codeplex.com/workitem/34655 with open(path, 'rb') as data: if os.path.splitext(path)[1].lower() in ('.rest', '.rst'): return read_rest(data) return Utf8Reader(data).read() except: raise DataError(get_error_message())
def import_variables(self, path, args=None): LOGGER.info("Importing variable file '%s' with args %s" % (path, args)) importer = Importer('variable file').import_class_or_module_by_path var_file = importer(path, instantiate_with_args=()) try: return self._get_variables(var_file, args) except: args = 'with arguments %s ' % seq2str2(args) if args else '' raise DataError("Processing variable file '%s' %sfailed: %s" % (path, args, get_error_message()))
def _read(self, source): try: with FileReader(source, accept_text=True) as reader: if os.path.splitext(reader.name)[1].lower() in ('.rest', '.rst'): from ..restreader import read_robot_data return read_robot_data(reader) return reader.read() except: raise DataError(get_error_message())
def _get_range_items(self, items): try: items = [ int(item) for item in items ] except: raise DataError('Converting argument of FOR IN RANGE failed: %s' % utils.get_error_message()) if not 1 <= len(items) <= 3: raise DataError('FOR IN RANGE expected 1-3 arguments, ' 'got %d instead.' % len(items)) return range(*items)
def get_handler(self, name): try: handler = self._get_handler(name) if handler is None: raise DataError("No keyword with name '%s' found." % name) except: error = utils.get_error_message() handler = UserErrorHandler(name, error) self._replace_variables_from_user_handlers(handler) return handler
def __call__(self, *args): if not self._method: return self._default try: value = self._method(*args) except: raise DataError("Calling dynamic method '%s' failed: %s" % (self._method.__name__, utils.get_error_message())) else: return self._to_unicode(value) if value is not None else self._default
def _screenshot_to_file(self, path): path = self._validate_screenshot_path(path) logger.debug('Using %s module/tool for taking screenshot.' % self._screenshot_taker.module) try: self._screenshot_taker(path) except: logger.warn('Taking screenshot failed: %s\n' 'Make sure tests are run with a physical or virtual ' 'display.' % get_error_message()) return path
def __call__(self, *args): if not self._method: return self._default try: value = self._method(*args) except: raise DataError("Calling dynamic method '%s' failed: %s" % (self._method.__name__, utils.get_error_message())) else: return self._to_unicode( value) if value is not None else self._default
def _map_values_to_rounds(self, values, per_round): if not 1 <= len(values) <= 3: raise DataError('FOR IN RANGE expected 1-3 values, got %d.' % len(values)) try: values = [self._to_number_with_arithmetic(v) for v in values] except: raise DataError('Converting FOR IN RANGE values failed: %s.' % get_error_message()) values = frange(*values) return ForInRunner._map_values_to_rounds(self, values, per_round)
def DebugFile(path): if path == 'NONE': LOGGER.info('No debug file') return None try: LOGGER.info('Debug file: %s' % path) return _DebugFileWriter(path) except: LOGGER.error("Opening debug file '%s' failed and writing to debug file " "is disabled. Error: %s" % (path, utils.get_error_message())) return None
def set_from_file(self, path, args=None, overwrite=False): LOGGER.info("Importing variable file '%s' with args %s" % (path, args)) var_file = self._import_variable_file(path) try: variables = self._get_variables_from_var_file(var_file, args) self._set_from_file(variables, overwrite, path) except: amsg = 'with arguments %s ' % utils.seq2str2(args) if args else '' raise DataError("Processing variable file '%s' %sfailed: %s" % (path, amsg, utils.get_error_message())) return variables
def _screenshot_to_file(self, path): path = self._validate_screenshot_path(path) logger.debug('Using %s modules for taking screenshot.' % self._screenshot_taker.module) try: self._screenshot_taker(path) except: logger.warn('Taking screenshot failed: %s\n' 'Make sure tests are run with a physical or virtual display.' % utils.get_error_message()) return path
def gather_failed_tests(output): if output.upper() == 'NONE': return [] gatherer = GatherFailedTests() try: ExecutionResult(output, include_keywords=False).suite.visit(gatherer) if not gatherer.tests: raise DataError('All tests passed.') except: raise DataError("Collecting failed tests from '%s' failed: %s" % (output, get_error_message())) return gatherer.tests
def process_output(self, path): path = path.replace("/", os.sep) try: print "Processing output '%s'" % path result = Result(root_suite=NoSlotsTestSuite()) ExecutionResultBuilder(path).build(result) except: raise RuntimeError("Processing output failed: %s" % utils.get_error_message()) setter = BuiltIn().set_suite_variable setter("$SUITE", process_suite(result.suite)) setter("$STATISTICS", result.statistics) setter("$ERRORS", process_errors(result.errors))
def process_output(self, path): path = path.replace('/', os.sep) try: print "Processing output '%s'" % path suite, errors = readers.process_output(path) except: raise RuntimeError('Processing output failed: %s' % utils.get_error_message()) setter = BuiltIn().set_suite_variable setter('$SUITE', process_suite(suite)) setter('$STATISTICS', Statistics(suite)) setter('$ERRORS', process_errors(errors))
def gather_failed_tests(output): if output.upper() == 'NONE': return [] gatherer = GatherFailedTests() try: ExecutionResult(output).suite.visit(gatherer) if not gatherer.tests: raise DataError('All tests passed.') except: raise DataError("Collecting failed tests from '%s' failed: %s" % (output, get_error_message())) return gatherer.tests
def get_count(self,item1,item2): if not hasattr(item1,'count'): try: item1 = list(item1) except: raise RuntimeError("Converting '%s' to list failed: %s" %(item1,utils.get_error_message())) count = item1.count(item2) self.log('Item found from the first item %d time%s' %(count,utils.plural_or_not(count)) ) return count
def gather_failed_suites(output, empty_suite_ok=False): if output is None: return None gatherer = GatherFailedSuites() try: ExecutionResult(output, include_keywords=False).suite.visit(gatherer) if not gatherer.suites and not empty_suite_ok: raise DataError('All suites passed.') except Exception: raise DataError("Collecting failed suites from '%s' failed: %s" % (output, get_error_message())) return gatherer.suites
def set_from_file(self, path, args, overwrite=False): LOGGER.info("Importing variable file '%s' with args %s" % (path, args)) args = args or [] try: module = utils.simple_import(path) variables = self._get_variables_from_module(module, args) self._set_from_file(variables, overwrite, path) except: amsg = args and 'with arguments %s ' % utils.seq2str2(args) or '' raise DataError("Processing variable file '%s' %sfailed: %s" % (path, amsg, utils.get_error_message())) return variables
def gather_failed_suites(output): if output.upper() == 'NONE': return [] gatherer = RenameThenGatherFailedSuites() try: ExecutionResult(output, include_keywords=False).suite.visit(gatherer) if not gatherer.suites: raise DataError('All suites passed.') except: raise DataError("Collecting failed suites from '%s' failed: %s" % (output, get_error_message())) return gatherer.suites
def register_file_logger(self, path=None, level='INFO'): if not path: path = os.environ.get('ROBOT_SYSLOG_FILE', 'NONE') level = os.environ.get('ROBOT_SYSLOG_LEVEL', level) if path.upper() == 'NONE': return try: logger = FileLogger(path, level) except: self.error("Opening syslog file '%s' failed: %s" % (path, utils.get_error_message())) else: self.register_logger(logger)
def get_handler(self, name): try: handler = self._get_handler(name) if handler is None: raise DataError("No keyword with name '%s' found." % name) except: error = utils.get_error_message() handler = UserErrorHandler(name, error) try: handler.replace_variables(self.variables) except AttributeError: # only applicable for UserHandlers pass return handler
def _convert_to_number_without_precision(self,item): try: if utils.is_jython: item = self._handle_java_numbers(item) return float(item) except: error = utils.get_error_message() try: return float(self._convert_to_integer(item)) except RuntimeError: raise RuntimeError("'%s cannot be converted to a floating" "point number: %s" %(item,error))
def process_output(path, log_level=None, settings=None): """Process one output file and return TestSuite and ExecutionErrors""" if not os.path.isfile(path): raise DataError("Output file '%s' does not exist." % path) LOGGER.info("Processing output file '%s'." % path) try: root = utils.etreewrapper.get_root(path) except: raise DataError("Opening XML file '%s' failed: %s" % (path, utils.get_error_message())) suite = TestSuite(_get_suite_node(root, path), log_level=log_level, settings=settings) errors = ExecutionErrors(_get_errors_node(root)) return suite, errors