def visit_test(self, test): if test.name in self._executed_tests: self._output.warn( "Multiple test cases with name '%s' executed in " "test suite '%s'." % (test.name, self._suite.longname) ) self._executed_tests[test.name] = True result = self._suite.tests.create( name=test.name, doc=self._resolve_setting(test.doc), tags=test.tags, starttime=get_timestamp(), timeout=self._get_timeout(test), ) status = TestStatus(self._suite_status, result.critical) if not status.failures and not test.name: status.test_failed("Test case name cannot be empty.") if not status.failures and not test.keywords.normal: status.test_failed("Test case contains no keywords.") try: result.tags = self._context.variables.replace_list(result.tags) except DataError as err: status.test_failed("Replacing variables from test tags failed: %s" % err.message) self._context.start_test(result) self._output.start_test(ModelCombiner(result, test)) if status.exit: self._add_exit_combine() result.tags.add("robot-exit") self._run_setup(test.keywords.setup, status, result) try: if not status.failures: runner = KeywordRunner(self._context, bool(test.template)) runner.run_keywords(test.keywords.normal) else: status.test_failed(status.message) except PassExecution as exception: err = exception.earlier_failures if err: status.test_failed(err) else: result.message = exception.message except ExecutionFailed as err: status.test_failed(err) result.status = status.status result.message = status.message or result.message if status.teardown_allowed: with self._context.test_teardown(result): failure = self._run_teardown(test.keywords.teardown, status, result) if failure and result.critical: status.critical_failure_occurred() if not status.failures and result.timeout and result.timeout.timed_out(): status.test_failed(result.timeout.get_message()) result.message = status.message result.status = status.status result.endtime = get_timestamp() self._output.end_test(ModelCombiner(result, test)) self._context.end_test(result)
def run(self, context): self.starttime = get_timestamp() context.start_keyword(self) error = self._run_with_error_handling(self._validate_and_run, context) self.status = self._get_status(error) self.endtime = get_timestamp() self.elapsedtime = get_elapsed_time(self.starttime, self.endtime) context.end_keyword(self) if error: raise error
def run(self, kw, name=None): result = KeywordResult(name=self._get_name(kw), type=kw.FOR_LOOP_TYPE, starttime=get_timestamp()) self._context.start_keyword(result) error = self._run_with_error_handling(self._validate_and_run, kw) result.status = self._get_status(error) result.endtime = get_timestamp() self._context.end_keyword(result) if error: raise error
def _run_one_round(self, data, values): name = ', '.join(format_assign_message(var, item) for var, item in zip(data.variables, values)) result = KeywordResult(name=name, type=data.FOR_ITEM_TYPE, starttime=get_timestamp()) self._context.start_keyword(result) for var, value in zip(data.variables, values): self._context.variables[var] = value runner = KeywordRunner(self._context, self._templated) error = self._run_with_error_handling(runner.run_keywords, data.keywords) result.status = self._get_status(error) result.endtime = get_timestamp() self._context.end_keyword(result) return error
def _start_run(self, context, parent_errors): errors = TestRunErrors(parent_errors) self.status = 'RUNNING' self.starttime = utils.get_timestamp() errors.test_initialized(self._init_test(context)) context.start_test(self) return errors
def start_suite(self, suite): variables = GLOBAL_VARIABLES.copy() variables.set_from_variable_table(suite.variables) result = TestSuite(source=suite.source, name=suite.name, doc=suite.doc, metadata=suite.metadata, starttime=get_timestamp()) if not self.result: result.set_criticality(self._settings.critical_tags, self._settings.non_critical_tags) self.result = Result(root_suite=result) self.result.configure(status_rc=self._settings.status_rc, stat_config=self._settings.statistics_config) else: self._suite.suites.append(result) ns = Namespace(result, variables, self._variables, suite.user_keywords, suite.imports) EXECUTION_CONTEXTS.start_suite(ns, self._output, self._settings.dry_run) self._context.set_suite_variables(result) if not (self._suite_status and self._suite_status.failures): ns.handle_imports() variables.resolve_delayed() result.doc = self._resolve_setting(result.doc) result.metadata = [(self._resolve_setting(n), self._resolve_setting(v)) for n, v in result.metadata.items()] self._context.set_suite_variables(result) self._suite = result self._suite_status = SuiteStatus(self._suite_status, self._settings.exit_on_failure, self._settings.skip_teardown_on_exit) self._output.start_suite(ModelCombiner(suite, self._suite)) self._run_setup(suite.keywords.setup, self._suite_status) self._executed_tests = NormalizedDict(ignore='_')
def run(self, kw, name=None): handler = self._context.get_handler(name or kw.name) handler.init_keyword(self._context.variables) result = KeywordResult(kwname=handler.name or '', libname=handler.libname or '', doc=handler.shortdoc, args=kw.args, assign=self._get_assign(kw.assign), timeout=getattr(handler, 'timeout', ''), type=kw.type, status='NOT_RUN', starttime=get_timestamp()) self._context.start_keyword(result) self._warn_if_deprecated(handler.longname, handler.shortdoc) try: return_value = self._run(handler, kw) except ExecutionFailed as err: result.status = self._get_status(err) self._end(result, error=err) raise else: if not (self._context.dry_run and handler.type == 'library'): result.status = 'PASS' self._end(result, return_value) return return_value
def visit_test(self, test): if test.name in self._executed_tests: self._output.warn("Multiple test cases with name '%s' executed in " "test suite '%s'." % (test.name, self._suite.longname)) self._executed_tests[test.name] = True result = self._suite.tests.create(name=test.name, doc=self._resolve_setting(test.doc), tags=test.tags, starttime=get_timestamp(), timeout=self._get_timeout(test)) keywords = Keywords(test.keywords.normal, bool(test.template)) status = TestStatus(self._suite_status) if not status.failures and not test.name: status.test_failed('Test case name cannot be empty.', result.critical) if not status.failures and not keywords: status.test_failed('Test case contains no keywords.', result.critical) try: result.tags = self._context.variables.replace_list(result.tags) except DataError, err: status.test_failed( 'Replacing variables from test tags failed: %s' % unicode(err), result.critical)
def visit_test(self, test): if test.name in self._executed_tests: self._output.warn("Multiple test cases with name '%s' executed in " "test suite '%s'." % (test.name, self._suite.longname)) self._executed_tests[test.name] = True result = self._suite.tests.create(name=test.name, doc=self._resolve_setting(test.doc), tags=test.tags, starttime=get_timestamp(), timeout=self._get_timeout(test)) keywords = Keywords(test.keywords.normal, bool(test.template)) status = TestStatus(self._suite_status) if not status.failures and not test.name: status.test_failed('Test case name cannot be empty.', result.critical) if not status.failures and not keywords: status.test_failed('Test case contains no keywords.', result.critical) try: result.tags = self._context.variables.replace_list(result.tags) except DataError as err: status.test_failed('Replacing variables from test tags failed: %s' % unicode(err), result.critical) self._context.start_test(result) self._output.start_test(ModelCombiner(result, test)) self._run_setup(test.keywords.setup, status, result) try: if not status.failures: keywords.run(self._context) except PassExecution as exception: err = exception.earlier_failures if err: status.test_failed(err, result.critical) else: result.message = exception.message except ExecutionFailed as err: status.test_failed(err, result.critical) result.status = status.status result.message = status.message or result.message if status.teardown_allowed: with self._context.test_teardown(result): self._run_teardown(test.keywords.teardown, status, result) if not status.failures and result.timeout and result.timeout.timed_out(): status.test_failed(result.timeout.get_message(), result.critical) result.message = status.message result.status = status.status result.endtime = get_timestamp() self._output.end_test(ModelCombiner(result, test)) self._context.end_test(result)
def run(self, context): self.starttime = get_timestamp() context.output.start_keyword(self) try: self._validate() self._run(context) except ExecutionFailed, err: error = err
def _end(self, context, return_value=None, error=None): self.endtime = get_timestamp() self.elapsedtime = get_elapsed_time(self.starttime, self.endtime) try: if not error or error.can_continue(context.teardown): self._set_variables(context, return_value) finally: context.end_keyword(self)
def __enter__(self): context = self.context result = self.result self.initial_test_status = context.test.status if context.test else None result.starttime = get_timestamp() context.start_keyword(ModelCombiner(self.data, result)) self._warn_if_deprecated(result.doc, result.name) return self
def _get_writer(self, path, rpa, generator): if not path: return NullMarkupWriter() writer = XmlWriter(path, write_empty=False, usage='output') writer.start('robot', {'generator': get_full_version(generator), 'generated': get_timestamp(), 'rpa': 'true' if rpa else 'false'}) return writer
def _write(self, text, separator=False, level='INFO', timestamp=None): if separator and self._separator_written_last: return if not separator: text = '%s - %s - %s' % (timestamp or get_timestamp(), level, text) self._outfile.write(text.rstrip() + '\n') self._outfile.flush() self._separator_written_last = separator
def _end(self, result, return_value=None, error=None): result.endtime = get_timestamp() if error and result.type == 'teardown': result.message = unicode(error) try: if not error or error.can_continue(self._context.in_teardown): self._set_variables(result, return_value, error) finally: self._context.end_keyword(result)
def create_xml_doc(lib, outpath): writer = utils.XmlWriter(outpath) writer.start('keywordspec', {'name': lib.name, 'type': lib.type, 'generated': utils.get_timestamp(millissep=None)}) writer.element('version', lib.version) writer.element('doc', lib.doc) _write_keywords_to_xml(writer, 'init', lib.inits) _write_keywords_to_xml(writer, 'kw', lib.keywords) writer.end('keywordspec') writer.close()
def __exit__(self, exc_type, exc_val, exc_tb): if exc_val is None: self._result.status = self._pass_status elif isinstance(exc_val, ExecutionFailed): self._result.status = exc_val.status if self._result.type == self._result.TEARDOWN_TYPE: self._result.message = unicode(exc_val) self._result.endtime = get_timestamp() self._context.end_keyword(self._result)
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 _end(self, context, return_value=None, error=None): self.endtime = get_timestamp() self.elapsedtime = get_elapsed_time(self.starttime, self.endtime) if error and self.type == "teardown": self.message = unicode(error) try: if not error or error.can_continue(context.in_teardown): self._set_variables(context, return_value, error) finally: context.end_keyword(self)
def _end(self, context, return_value=None, error=None): self.endtime = get_timestamp() self.elapsedtime = get_elapsed_time(self.starttime, self.endtime) if error and self.type == 'teardown': self.message = unicode(error) try: if not error or error.can_continue(context.in_teardown): self._set_variables(context, return_value, error) finally: context.end_keyword(self)
def _write_start(self, libdoc, writer, formatter): lib_attrs = {'name': libdoc.name, 'type': libdoc.type, 'format': formatter.format, 'generated': get_timestamp(millissep=None)} writer.start('keywordspec', lib_attrs) writer.element('version', libdoc.version) writer.element('scope', libdoc.scope) writer.element('namedargs', 'yes' if libdoc.named_args else 'no') writer.element('doc', formatter(libdoc.doc))
def _start(self, context): handler = context.get_handler(self.handler_name) handler.init_keyword(context.variables) self.name = self._get_name(handler.longname) self.doc = handler.shortdoc self.timeout = getattr(handler, 'timeout', '') self.starttime = get_timestamp() context.start_keyword(self) self._warn_if_deprecated(handler.longname, handler.shortdoc, context) return handler
def convert(self, libdoc): return { "name": libdoc.name, "doc": self._doc_formatter.html(libdoc.doc, intro=True), "version": libdoc.version, "named_args": libdoc.named_args, "scope": libdoc.scope, "generated": get_timestamp(daysep="-", millissep=None), "inits": self._get_keywords(libdoc.inits), "keywords": self._get_keywords(libdoc.keywords), }
def _get_writer(self, path, generator): if not path: return NullMarkupWriter() try: writer = XmlWriter(path, encoding='UTF-8', write_empty=False) except EnvironmentError as err: raise DataError("Opening output file '%s' failed: %s" % (path, err.strerror)) writer.start('robot', {'generator': get_full_version(generator), 'generated': get_timestamp()}) return writer
def create_html_doc(lib, outpath, title=None, styles=None): if title: title = title.replace('_', ' ') else: title = lib.name generated = utils.get_timestamp(daysep='-', millissep=None) namespace = Namespace(LIB=lib, TITLE=title, STYLES=_get_styles(styles), GENERATED=generated) doc = Template(template=HTML_TEMPLATE).generate(namespace) + '\n' with open(outpath, 'w') as outfile: outfile.write(doc.encode('UTF-8'))
def _get_writer(self, path, generator): if not path: return NullMarkupWriter() try: writer = XmlWriter(path, encoding='UTF-8') except EnvironmentError as err: raise DataError("Opening output file '%s' failed: %s" % (path, err.strerror)) writer.start('robot', {'generator': get_full_version(generator), 'generated': get_timestamp()}) return writer
def convert(self, libdoc): return { 'name': libdoc.name, 'doc': self._doc_formatter.html(libdoc.doc, intro=True), 'version': libdoc.version, 'named_args': libdoc.named_args, 'scope': libdoc.scope, 'generated': utils.get_timestamp(daysep='-', millissep=None), 'inits': self._get_keywords(libdoc.inits), 'keywords': self._get_keywords(libdoc.keywords) }
def create_html_doc(lib, outpath, title=None): if title: title = title.replace('_', ' ') else: title = '%s - Documentation' % lib.name generated = utils.get_timestamp(daysep='-', millissep=None) namespace = Namespace(LIB=lib, TITLE=title, GENERATED=generated) doc = Template(template=DOCUMENT_TEMPLATE).generate(namespace) + '\n' outfile = open(outpath, 'w') outfile.write(doc.encode('UTF-8')) outfile.close()
def convert(self, libdoc): return { 'name': libdoc.name, 'doc': self._doc_formatter.html(libdoc.doc, intro=True), 'version': libdoc.version, 'named_args': libdoc.named_args, 'scope': libdoc.scope, 'generated': get_timestamp(daysep='-', millissep=None), 'inits': self._get_keywords(libdoc.inits), 'keywords': self._get_keywords(libdoc.keywords) }
def _start(self, context): handler = context.get_handler(self.handler_name) handler.init_keyword(context.get_current_vars()) self.name = self._get_name(handler.longname) self.doc = handler.shortdoc self.starttime = utils.get_timestamp() context.start_keyword(self) if self.doc.startswith('*DEPRECATED*'): msg = self.doc.replace('*DEPRECATED*', '', 1).strip() name = self.name.split('} = ', 1)[-1] # Remove possible variable context.warn("Keyword '%s' is deprecated. %s" % (name, msg)) return handler
def _start_run(self, output, parent_context, errors): errors.start_suite() self.status = 'RUNNING' self.starttime = utils.get_timestamp() variables = parent_context.get_current_vars() if parent_context else None ns = Namespace(self, variables) context = EXECUTION_CONTEXTS.start_suite(ns, output, self._dry_run_mode) if not errors.exit: ns.handle_imports() self._set_variable_dependent_metadata(context, errors) output.start_suite(self) return context
def write(self, libdoc, outfile): writer = XmlWriter(outfile, encoding='UTF-8') writer.start('keywordspec', {'name': libdoc.name, 'type': libdoc.type, 'generated': get_timestamp(millissep=None)}) writer.element('version', libdoc.version) writer.element('scope', libdoc.scope) writer.element('namedargs', 'yes' if libdoc.named_args else 'no') writer.element('doc', libdoc.doc) self._write_keywords('init', libdoc.inits, writer) self._write_keywords('kw', libdoc.keywords, writer) writer.end('keywordspec') writer.close()
def end_suite(self, suite): self._suite.message = self._suite_status.message self._context.report_suite_status(self._suite.status, self._suite.full_message) with self._context.suite_teardown(): failure = self._run_teardown(suite.keywords.teardown, self._suite_status) if failure: self._suite.suite_teardown_failed(unicode(failure)) self._suite.endtime = get_timestamp() self._suite.message = self._suite_status.message self._context.end_suite(self._suite) self._suite = self._suite.parent self._suite_status = self._suite_status.parent
def _write(self, text, separator=False, level='INFO', timestamp=None): if separator and self._separator_written_last: return if not separator: text = '%s - %s - %s' % (timestamp or utils.get_timestamp(), level, text) text = text.rstrip() + '\n' if PY3 and hasattr(self._outfile, 'encoding'): self._outfile.write(text) else: self._outfile.write(text.encode('UTF-8')) self._outfile.flush() self._separator_written_last = separator
def _start_run(self, output, parent, errors): if not errors: errors = SuiteRunErrors(self._run_mode_exit_on_failure, self._run_mode_skip_teardowns_on_exit) self.run_errors = errors self.run_errors.start_suite() self.status = 'RUNNING' self.starttime = utils.get_timestamp() parent_vars = parent.context.get_current_vars() if parent else None self.context = ExecutionContext(Namespace(self, parent_vars), output, self._run_mode_dry_run) self._set_variable_dependent_metadata(self.context) output.start_suite(self) return self.context
def _start(self, context): handler = context.get_handler(self.handler_name) handler.init_keyword(context.variables) self.name = self._get_name(handler.longname) self.doc = handler.shortdoc self.timeout = getattr(handler, "timeout", "") self.starttime = get_timestamp() context.start_keyword(self) if self.doc.startswith("*DEPRECATED*"): msg = self.doc.replace("*DEPRECATED*", "", 1).strip() name = self.name.split("} = ", 1)[-1] # Remove possible variable context.warn("Keyword '%s' is deprecated. %s" % (name, msg)) return handler
def __init__(self, path, log_level='TRACE', rpa=False, generator='Robot'): if not jsonstreams: raise DataError('Using the JSON output format requires the ' 'jsonstreams module to be installed. Typically ' 'you can install it by running ' '`pip install jsonstreams`.') self._log_message_is_logged = IsLogged(log_level) self._error_message_is_logged = IsLogged('WARN') self._path = path # Setup the JSON data to store before writing the file self._data = { 'rpa': rpa is not None, 'generator': get_full_version(generator), 'generated': get_timestamp() } self._errors = [] # Setup stacks self._item_stack = list() # We need to keep track of the active suite, test, and body item self._suite = None self._body = None self._body_item = None self._test = None self._errors_element = None # We need to be able to track the type of item being processed # at any moment self._item_type = None self._root = jsonstreams.Stream(jsonstreams.Type.object, filename=self._path) self._root.write('rpa', rpa is not None) self._root.write('generator', get_full_version(generator)) self._root.write('generated', get_timestamp())
def _start_run(self, output, parent_context, errors): errors.start_suite() self.status = 'RUNNING' self.starttime = utils.get_timestamp() variables = parent_context.get_current_vars( ) if parent_context else None ns = Namespace(self, variables) context = EXECUTION_CONTEXTS.start_suite(ns, output, self._dry_run_mode) if not errors.exit: ns.handle_imports() self._set_variable_dependent_metadata(context, errors) output.start_suite(self) return context
def to_dictionary(self): return { 'name': self.name, 'doc': self.doc, 'version': self.version, 'type': self.type, 'scope': self.scope, 'doc_format': self.doc_format, 'source': self.source, 'lineno': self.lineno, 'inits': [init.to_dictionary() for init in self.inits], 'keywords': [kw.to_dictionary() for kw in self.keywords], 'generated': get_timestamp(daysep='-', millissep=None), 'all_tags': tuple(self.all_tags) }
def _start_run(self, output, parent, errors): if not errors: errors = SuiteRunErrors(self._run_mode_exit_on_failure, self._run_mode_skip_teardowns_on_exit) self.run_errors = errors self.run_errors.start_suite() self.status = "RUNNING" self.starttime = utils.get_timestamp() parent_vars = parent.context.get_current_vars() if parent else None ns = Namespace(self, parent_vars) self.context = EXECUTION_CONTEXTS.start_suite(ns, output, self._run_mode_dry_run) if not errors.exit: ns.handle_imports() self._set_variable_dependent_metadata(self.context) output.start_suite(self) return self.context
def end_suite(self, suite): self._suite.message = self._suite_status.message self._context.report_suite_status(self._suite.status, self._suite.full_message) with self._context.suite_teardown(): failure = self._run_teardown(suite.keywords.teardown, self._suite_status) if failure: self._suite.suite_teardown_failed(unic(failure)) self._suite_status.failure_occurred() self._suite.endtime = get_timestamp() self._suite.message = self._suite_status.message self._context.end_suite(ModelCombiner(suite, self._suite)) self._suite = self._suite.parent self._suite_status = self._suite_status.parent self._output.library_listeners.discard_suite_scope()
def _start_run(self, output, parent, errors): if not errors: errors = SuiteRunErrors(self._run_mode_exit_on_failure, self._run_mode_skip_teardowns_on_exit) self.run_errors = errors self.run_errors.start_suite() self.status = 'RUNNING' self.starttime = utils.get_timestamp() parent_vars = parent.context.get_current_vars() if parent else None ns = Namespace(self, parent_vars) self.context = EXECUTION_CONTEXTS.start_suite(ns, output, self._run_mode_dry_run) if not errors.exit: ns.handle_imports() self._set_variable_dependent_metadata(self.context) output.start_suite(self) return self.context
def __exit__(self, exc_type, exc_val, exc_tb): context = self._context result = self._result failure = self._get_failure(exc_type, exc_val, exc_tb, context) if failure is None: result.status = self._pass_status else: result.status = failure.status if result.type == result.TEARDOWN_TYPE: result.message = failure.message if context.test: context.test.passed = self._test_passed and result.passed result.endtime = get_timestamp() context.end_keyword(result) if failure is not exc_val: raise failure
def __exit__(self, exc_type, exc_val, exc_tb): context = self.context result = self.result failure = self._get_failure(exc_type, exc_val, exc_tb, context) if failure is None: result.status = self.pass_status else: result.status = failure.status if result.type == result.TEARDOWN: result.message = failure.message if self.initial_test_status == 'PASS': context.test.status = result.status result.endtime = get_timestamp() context.end_keyword(ModelCombiner(self.data, result)) if failure is not exc_val: raise failure