def get_filtered_source(self, source, tag_dict, filter_type): """ Create a clone of the original report and filter it with the given filter type & tag context. Also populate cloned report's meta attribute with the tag label. """ if filter_type == self.ANY: filter_func = tagging.check_any_matching_tags elif filter_type == self.ALL: filter_func = tagging.check_all_matching_tags else: raise ValueError('Invalid filter_type: `{}`'.format(filter_type)) def _tag_filter(obj): # Check against denormalized tag data if not hasattr(obj, 'tags_index'): return True # include everything that doesn't have tags return filter_func(tag_arg_dict=tag_dict, target_tag_dict=obj.tags_index) result = source.filter(_tag_filter) tag_label = tagging.tag_label(tag_dict) result.meta['report_tags_{}'.format(filter_type)] = tag_label return result
def format_suite(self, instance, suite): if not isinstance(instance, MultiTest): return '{}:{}'.format(instance.name, suite) pattern = '{}:{}'.format(instance.name, suite.__class__.__name__) tag_label = tagging.tag_label(tagging.get_native_suite_tags(suite)) if tag_label: return '{} --tags {}'.format(pattern, tag_label) return pattern
def get_skip_message(self, source, tag_dict, filter_type): """ :param source: Cloned test report. :param tag_dict: Tag context for the current filtered test report. :param filter_type: all / any :return: String message to be displayed on skipped export operations. """ return ('Empty report for tags: `{tag_label}`, filter_type:' ' `{filter_type}`, skipping export operation.').format( tag_label=tagging.tag_label(tag_dict), filter_type=filter_type)
def get_skip_message(self, source, tag_dict, filter_type): """ :param source: Cloned test report. :type source: :py:class:`~testplan.report.testing.base.TestReport` :param tag_dict: Tag context for the current filtered test report. :type tag_dict: ``dict`` of ``set`` :param filter_type: all / any :type filter_type: ``str`` :return: String message to be displayed on skipped export operations. :rtype: ``str`` """ return ('Empty report for tags: `{tag_label}`, filter_type:' ' `{filter_type}`, skipping export operation.').format( tag_label=tagging.tag_label(tag_dict), filter_type=filter_type)
def get_skip_message( self, source: Optional[TestReport], tag_dict: Dict, filter_type: str, ) -> str: """ Produces message logged if filtered clone is empty. :param source: cloned test report :param tag_dict: tag context for the current filtered test report :param filter_type: all / any :return: string message to be displayed on skipped export operations """ return ("Empty report for tags: `{tag_label}`, filter_type:" " `{filter_type}`, skipping export operation.").format( tag_label=tagging.tag_label(tag_dict), filter_type=filter_type)
def generate_path_for_tags(config, tag_dict, filter_type): """ Generate the PDF filename using the given filter and tag context. Will trim the filename and append a uuid suffix if it ends up being longer than `MAX_FILENAME_LENGTH`. TOOD: support custom filename generation & move logic to the exporter. >>> generate_pdf_path( ... filter_type='all', ... tag_arg_dict={ ... 'simple': {'foo', 'bar'}, ... 'hello': {'world', 'mars'} ... } ... ) <directory>/report-tags-all-foo__bar__hello-world-mars.pdf """ def add_count_suffix(directory, path, count=0): """Add a number suffix to file name if files with same names exist.""" target_path = '{}_{}'.format(path, count) if count else path full_path = os.path.join(config.report_dir, target_path + '.pdf') if os.path.exists(full_path): return add_count_suffix(directory, path, count + 1) return full_path tag_label = tagging.tag_label(tag_dict).replace(' ', '__').replace( '=', '-').replace(',', '-') path_template = 'report-tags-{filter_type}-{label}' path_kwargs = dict( filter_type=filter_type, label=slugify(tag_label), ) if config.timestamp: path_template += '-{timestamp}' path_kwargs['timestamp'] = config.timestamp path = path_template.format(**path_kwargs) if len(path) >= MAX_FILENAME_LENGTH: path = '{}-{}'.format(path[:MAX_FILENAME_LENGTH], uuid.uuid4()) return add_count_suffix(config.report_dir, path)
def get_filtered_source( self, source: TestReport, tag_dict: Dict, filter_type: str, ) -> TestReport: """ Creates a filtered clone of the report by filter type and tag context. :param source: Testplan report :param tag_dict: tag context for filtering :param filter_type: all / any :return: filtered clone """ tag_label = tagging.tag_label(tag_dict) result = source.filter_by_tags(tag_dict, all_tags=filter_type == self.ALL) result.meta["report_tags_{}".format(filter_type)] = tag_label return result
def get_filtered_source(self, source, tag_dict, filter_type): """ Create a clone of the original report and filter it with the given filter type & tag context. Also populate cloned report's meta attribute with the tag label. :param source: Original test report. :type source: :py:class:`~testplan.report.testing.base.TestReport` :param tag_dict: Tag context for the current filtered test report. :type tag_dict: ``dict`` of ``set`` :param filter_type: all / any :type filter_type: ``str`` """ tag_label = tagging.tag_label(tag_dict) result = source.filter_by_tags(tag_dict, all_tags=filter_type == self.ALL) result.meta['report_tags_{}'.format(filter_type)] = tag_label return result
def get_header(self, source, depth, row_idx): """ Assuming we have 4 columns per row, render the header in the format: [<TEST_NAME> - <NATIVE TAGS>][][][<TEST_STATUS>] """ passed = source.passed font_size = const.FONT_SIZE if depth == 0 else const.FONT_SIZE_SMALL font = const.FONT_BOLD if (depth == 0) or not passed else const.FONT styles = [ RowStyle(font=(font, font_size), line_above=self.get_header_linestyle()), RowStyle(left_padding=const.INDENT * depth, end_column=0), RowStyle( text_color=colors.green if passed else colors.red, start_column=const.LAST_COLUMN_IDX, ), ] if not source.passed: styles.append(RowStyle(background=colors.whitesmoke)) header_text = source.name if source.tags: header_text += " (Tags: {})".format(tagging.tag_label(source.tags)) header_text = split_text( header_text, font, font_size, const.PAGE_WIDTH - (depth * const.INDENT), ) return RowData( start=row_idx, content=[header_text, "", "", format_status(source.status)], style=styles, )
def apply_tag_label(self, pattern, obj): if obj.__tags__: return '{} --tags {}'.format(pattern, tagging.tag_label(obj.__tags__)) return pattern