def test_render_DefaultJinjaPageView_meta_info(): validation_results = { "results": [], "statistics": { "evaluated_expectations": 156, "successful_expectations": 139, "unsuccessful_expectations": 17, "success_percent": 89.1025641025641 }, "meta": { "great_expectations.__version__": "0.7.0-beta", "data_asset_name": "tetanusvaricella", "expectation_suite_name": "my_suite", "run_id": "2019-06-25T14:58:09.960521", "batch_kwargs": { "path": "/Users/user/project_data/public_healthcare_datasets/tetanusvaricella/tetvardata.csv", "timestamp": 1561474688.693565 } } } document = RenderedDocumentContent( dict_to_ordered_dict( ProfilingResultsPageRenderer().render(validation_results))) html = DefaultJinjaPageView().render(document) with open( './tests/render/output/test_render_DefaultJinjaPageView_meta_info.html', 'w') as outfile: outfile.write(html)
def test_render_section_page(): section = RenderedSectionContent( **{ "section_name": None, "content_blocks": [ RenderedHeaderContent( **{ "content_block_type": "header", "header": "Overview", } ), RenderedTableContent( **{ "content_block_type": "table", "header": "Dataset info", "table": [ ["Number of variables", "12"], ["Number of observations", "891"], ], "styling": { "classes": ["col-6", "table-responsive"], "styles": {"margin-top": "20px"}, "body": {"classes": ["table", "table-sm"]}, }, } ), ], } ) rendered_doc = ge.render.view.view.DefaultMarkdownPageView().render( RenderedDocumentContent(sections=[section]) ) rendered_doc = rendered_doc.replace(" ", "").replace("\t", "").replace("\n", "") assert ( rendered_doc == """ #ValidationResults ##Overview ###Datasetinfo ||||------------|------------|Numberofvariables|12Numberofobservations|891 ----------------------------------------------------------- Poweredby[GreatExpectations](https://greatexpectations.io/) """.replace( " ", "" ) .replace("\t", "") .replace("\n", "") )
def render(self, expectations): if isinstance(expectations, dict): expectations = ExpectationSuite(**expectations, data_context=None) ( columns, ordered_columns, ) = expectations.get_grouped_and_ordered_expectations_by_column() expectation_suite_name = expectations.expectation_suite_name overview_content_blocks = [ self._render_expectation_suite_header(), self._render_expectation_suite_info(expectations), ] table_level_expectations_content_block = self._render_table_level_expectations( columns) if table_level_expectations_content_block is not None: overview_content_blocks.append( table_level_expectations_content_block) asset_notes_content_block = self._render_expectation_suite_notes( expectations) if asset_notes_content_block is not None: overview_content_blocks.append(asset_notes_content_block) sections = [ RenderedSectionContent( **{ "section_name": "Overview", "content_blocks": overview_content_blocks, }) ] sections += [ self._column_section_renderer.render(expectations=columns[column]) for column in ordered_columns if column != "_nocolumn" ] return RenderedDocumentContent( **{ "renderer_type": "ExpectationSuitePageRenderer", "page_title": f"Expectations / {str(expectation_suite_name)}", "expectation_suite_name": expectation_suite_name, "utm_medium": "expectation-suite-page", "sections": sections, })
def render(self, validation_results): run_id = validation_results.meta["run_id"] if isinstance(run_id, str): try: run_time = parse(run_id).strftime("%Y-%m-%dT%H:%M:%S.%fZ") except (ValueError, TypeError): run_time = "__none__" run_name = run_id elif isinstance(run_id, dict): run_name = run_id.get("run_name") or "__none__" run_time = run_id.get("run_time") or "__none__" elif isinstance(run_id, RunIdentifier): run_name = run_id.run_name or "__none__" run_time = run_id.run_time.strftime("%Y-%m-%dT%H:%M:%S.%fZ") expectation_suite_name = validation_results.meta[ "expectation_suite_name"] batch_kwargs = validation_results.meta.get( "batch_kwargs", {}) or validation_results.meta.get( "batch_spec", {}) # add datasource key to batch_kwargs if missing if "datasource" not in batch_kwargs and "datasource" not in batch_kwargs: # check if expectation_suite_name follows datasource.batch_kwargs_generator.data_asset_name.suite_name pattern if len(expectation_suite_name.split(".")) == 4: if "batch_kwargs" in validation_results.meta: batch_kwargs["datasource"] = expectation_suite_name.split( ".")[0] else: batch_kwargs["datasource"] = expectation_suite_name.split( ".")[0] # Group EVRs by column # TODO: When we implement a ValidationResultSuite class, this method will move there. columns = self._group_evrs_by_column(validation_results) ordered_columns = Renderer._get_column_list_from_evrs( validation_results) column_types = self._overview_section_renderer._get_column_types( validation_results) data_asset_name = batch_kwargs.get("data_asset_name") # Determine whether we have a custom run_name try: run_name_as_time = parse(run_name) except ValueError: run_name_as_time = None try: run_time_datetime = parse(run_time) except ValueError: run_time_datetime = None include_run_name: bool = False if run_name_as_time != run_time_datetime and run_name_as_time != "__none__": include_run_name = True page_title = f"Profiling Results / {str(expectation_suite_name)}" if data_asset_name: page_title += f" / {str(data_asset_name)}" if include_run_name: page_title += f" / {str(run_name)}" page_title += f" / {str(run_time)}" return RenderedDocumentContent( **{ "renderer_type": "ProfilingResultsPageRenderer", "page_title": page_title, "expectation_suite_name": expectation_suite_name, "utm_medium": "profiling-results-page", "batch_kwargs": batch_kwargs if "batch_kwargs" in validation_results.meta else None, "batch_spec": batch_kwargs if "batch_spec" in validation_results.meta else None, "sections": [ self._overview_section_renderer.render( validation_results, section_name="Overview") ] + [ self._column_section_renderer.render( columns[column], section_name=column, column_type=column_types.get(column), ) for column in ordered_columns ], })
def render( self, validation_results: ExpectationSuiteValidationResult, evaluation_parameters=None, ): # Gather run identifiers run_name, run_time = self._parse_run_values(validation_results) expectation_suite_name = validation_results.meta[ "expectation_suite_name"] batch_kwargs = (validation_results.meta.get("batch_kwargs", {}) or validation_results.meta.get("batch_spec", {}) or {}) # Add datasource key to batch_kwargs if missing if "datasource" not in batch_kwargs and "datasource" not in batch_kwargs: # Check if expectation_suite_name follows datasource.batch_kwargs_generator.data_asset_name.suite_name pattern if len(expectation_suite_name.split(".")) == 4: batch_kwargs["datasource"] = expectation_suite_name.split( ".")[0] columns = self._group_evrs_by_column(validation_results, expectation_suite_name) overview_content_blocks = [ self._render_validation_header(validation_results), self._render_validation_statistics( validation_results=validation_results), ] collapse_content_blocks = [ self._render_validation_info(validation_results=validation_results) ] collapse_content_block = self._generate_collapse_content_block( collapse_content_blocks, validation_results) if not self.run_info_at_end: overview_content_blocks.append(collapse_content_block) sections = self._collect_rendered_document_content_sections( validation_results, overview_content_blocks, collapse_content_blocks, columns, ) # Determine whether we have a custom run_name data_asset_name = batch_kwargs.get("data_asset_name", "") page_title = self._determine_page_title(run_name, run_time, data_asset_name, expectation_suite_name) return RenderedDocumentContent( **{ "renderer_type": "ValidationResultsPageRenderer", "page_title": page_title, "batch_kwargs": batch_kwargs if "batch_kwargs" in validation_results.meta else None, "batch_spec": batch_kwargs if "batch_spec" in validation_results.meta else None, "expectation_suite_name": expectation_suite_name, "sections": sections, "utm_medium": "validation-results-page", })
def deserialize(self, key, value): return RenderedDocumentContent(**loads(value))
def render(cls, index_links_dict): sections = [] cta_object = index_links_dict.pop("cta_object", None) try: content_blocks = [] # site name header site_name_header_block = RenderedHeaderContent( **{ "content_block_type": "header", "header": RenderedStringTemplateContent( **{ "content_block_type": "string_template", "string_template": { "template": "$title_prefix | $site_name", "params": { "site_name": index_links_dict.get( "site_name"), "title_prefix": "Data Docs", }, "styling": { "params": { "title_prefix": { "tag": "strong" } } }, }, }), "styling": { "classes": ["col-12", "ge-index-page-site-name-title"], "header": { "classes": ["alert", "alert-secondary"] }, }, }) content_blocks.append(site_name_header_block) tabs = [] if index_links_dict.get("validations_links"): tabs.append({ "tab_name": "Validation Results", "tab_content": cls._generate_validation_results_link_table( index_links_dict), }) if index_links_dict.get("profiling_links"): tabs.append({ "tab_name": "Profiling Results", "tab_content": cls._generate_profiling_results_link_table( index_links_dict), }) if index_links_dict.get("expectations_links"): tabs.append({ "tab_name": "Expectation Suites", "tab_content": cls._generate_expectation_suites_link_table( index_links_dict), }) tabs_content_block = RenderedTabsContent( **{ "tabs": tabs, "styling": { "classes": ["col-12", "ge-index-page-tabs-container"], }, }) content_blocks.append(tabs_content_block) section = RenderedSectionContent( **{ "section_name": index_links_dict.get("site_name"), "content_blocks": content_blocks, }) sections.append(section) index_page_document = RenderedDocumentContent( **{ "renderer_type": "SiteIndexPageRenderer", "utm_medium": "index-page", "sections": sections, }) if cta_object: index_page_document.cta_footer = CallToActionRenderer.render( cta_object) return index_page_document except Exception as e: exception_message = f"""\ An unexpected Exception occurred during data docs rendering. Because of this error, certain parts of data docs will \ not be rendered properly and/or may not appear altogether. Please use the trace, included in this message, to \ diagnose and repair the underlying issue. Detailed information follows: """ exception_traceback = traceback.format_exc() exception_message += ( f'{type(e).__name__}: "{str(e)}". Traceback: "{exception_traceback}".' ) logger.error(exception_message)
def render(cls, index_links_dict): sections = [] for source, generators in index_links_dict.items(): content_blocks = [] # datasource header source_header_block = RenderedComponentContent( **{ "content_block_type": "header", "header": source, "styling": { "classes": ["col-12"], "header": { "classes": ["alert", "alert-secondary"] } } }) content_blocks.append(source_header_block) # generator header for generator, data_assets in generators.items(): generator_header_block = RenderedComponentContent( **{ "content_block_type": "header", "header": generator, "styling": { "classes": ["col-12", "ml-4"], } }) content_blocks.append(generator_header_block) horizontal_rule = RenderedComponentContent( **{ "content_block_type": "string_template", "string_template": { "template": "", "params": {}, "tag": "hr" }, "styling": { "classes": ["col-12"], } }) content_blocks.append(horizontal_rule) generator_table_rows = [] generator_table_header_row = ["Data Asset"] header_dict = OrderedDict( [["profiling_links", "Profiling Results"], ["expectation_suite_links", "Expectation Suite"], ["validation_links", "Validation Results"]]) for link_lists_key, header in header_dict.items(): for data_asset, link_lists in data_assets.items(): if header in generator_table_header_row: continue if link_lists[link_lists_key]: generator_table_header_row.append(header) generator_table = RenderedComponentContent( **{ "content_block_type": "table", "header_row": generator_table_header_row, "table": generator_table_rows, "styling": { "classes": ["col-12"], "styles": { "margin-top": "10px" }, "body": { "classes": ["table", "table-sm"] } } }) # data_assets for data_asset, link_lists in data_assets.items(): generator_table_rows += cls._generate_data_asset_table_section( data_asset, link_lists) content_blocks.append(generator_table) section = RenderedSectionContent(**{ "section_name": source, "content_blocks": content_blocks }) sections.append(section) return RenderedDocumentContent(**{ "utm_medium": "index-page", "sections": sections })
def render(cls, index_links_dict): sections = [] cta_object = index_links_dict.pop("cta_object", None) try: content_blocks = [] # site name header site_name_header_block = RenderedHeaderContent( **{ "content_block_type": "header", "header": RenderedStringTemplateContent( **{ "content_block_type": "string_template", "string_template": { "template": "$title_prefix | $site_name", "params": { "site_name": index_links_dict.get( "site_name"), "title_prefix": "Data Docs" }, "styling": { "params": { "title_prefix": { "tag": "strong" } } }, } }), "styling": { "classes": ["col-12", "ge-index-page-site-name-title"], "header": { "classes": ["alert", "alert-secondary"] } } }) content_blocks.append(site_name_header_block) table_rows = [] table_header_row = [] link_list_keys_to_render = [] header_dict = OrderedDict( [["expectations_links", "Expectation Suite"], ["validations_links", "Validation Results (run_id)"]]) for link_lists_key, header in header_dict.items(): if index_links_dict.get(link_lists_key): class_header_str = link_lists_key.replace("_", "-") class_str = "ge-index-page-table-{}-header".format( class_header_str) header = RenderedStringTemplateContent( **{ "content_block_type": "string_template", "string_template": { "template": header, "params": {}, "styling": { "classes": [class_str], } } }) table_header_row.append(header) link_list_keys_to_render.append(link_lists_key) generator_table = RenderedTableContent( **{ "content_block_type": "table", "header_row": table_header_row, "table": table_rows, "styling": { "classes": ["col-12", "ge-index-page-table-container"], "styles": { "margin-top": "10px" }, "body": { "classes": [ "table", "table-sm", "ge-index-page-generator-table" ] } } }) table_rows += cls._generate_links_table_rows( index_links_dict, link_list_keys_to_render=link_list_keys_to_render) content_blocks.append(generator_table) if index_links_dict.get("profiling_links"): profiling_table_rows = [] for profiling_link_dict in index_links_dict.get( "profiling_links"): profiling_table_rows.append([ RenderedStringTemplateContent( **{ "content_block_type": "string_template", "string_template": { "template": "$link_text", "params": { "link_text": profiling_link_dict[ "expectation_suite_name"] + "." + profiling_link_dict["batch_identifier"] }, "tag": "a", "styling": { "attributes": { "href": profiling_link_dict["filepath"] }, "classes": [ "ge-index-page-table-expectation-suite-link" ] } }, }) ]) content_blocks.append( RenderedTableContent( **{ "content_block_type": "table", "header_row": ["Profiling Results"], "table": profiling_table_rows, "styling": { "classes": ["col-12", "ge-index-page-table-container"], "styles": { "margin-top": "10px" }, "body": { "classes": [ "table", "table-sm", "ge-index-page-generator-table" ] } } })) section = RenderedSectionContent( **{ "section_name": index_links_dict.get("site_name"), "content_blocks": content_blocks }) sections.append(section) index_page_document = RenderedDocumentContent( **{ "renderer_type": "SiteIndexPageRenderer", "utm_medium": "index-page", "sections": sections }) if cta_object: index_page_document.cta_footer = CallToActionRenderer.render( cta_object) return index_page_document except Exception as e: exception_message = f'''\ An unexpected Exception occurred during data docs rendering. Because of this error, certain parts of data docs will \ not be rendered properly and/or may not appear altogether. Please use the trace, included in this message, to \ diagnose and repair the underlying issue. Detailed information follows: ''' exception_traceback = traceback.format_exc() exception_message += f'{type(e).__name__}: "{str(e)}". Traceback: "{exception_traceback}".' logger.error(exception_message, e, exc_info=True)
def render(cls, ge_dict=None): if ge_dict is None: ge_dict = {} return RenderedDocumentContent(**{ "renderer_type": "CustomValidationResultsPageRenderer", "data_asset_name": "my_data_asset_name", "full_data_asset_identifier": "my_datasource/my_generator/my_generator_asset", "page_title": "My Page Title", "sections": [ RenderedSectionContent(**{ "section_name": "Header Content Block", "content_blocks": [ cls._get_header_content_block(header="Header Content Block", subheader="subheader")] }), RenderedSectionContent(**{ "section_name": "Bullet List Content Block", "content_blocks": [ cls._get_header_content_block(header="Bullet List Content Block"), cls._get_bullet_list_content_block(header="My Important List", subheader="Unremarkable Subheader") ] }), RenderedSectionContent(**{ "section_name": "Table Content Block", "content_blocks": [ cls._get_header_content_block(header="Table Content Block"), cls._get_table_content_block(header="My Big Data Table"), ] }), RenderedSectionContent(**{ "section_name": "Value List Content Block", "content_blocks": [ cls._get_header_content_block(header="Value List Content Block"), cls._get_value_list_content_block(header="My Name Value List"), ] }), RenderedSectionContent(**{ "section_name": "Graph Content Block", "content_blocks": [ cls._get_header_content_block(header="Graph Content Block"), cls._get_graph_content_block(header="My Big Data Graph"), ] }), RenderedSectionContent(**{ "section_name": "String Template Content Block With Icon", "content_blocks": [ cls._get_header_content_block(header="String Template Content Block With Icon"), cls._get_string_template_content_block() ] }), RenderedSectionContent(**{ "section_name": "String Template Content Block With Tooltip", "content_blocks": [ cls._get_header_content_block(header="String Template Content Block With Tooltip"), cls._get_tooltip_string_template_content_block() ] }), RenderedSectionContent(**{ "section_name": "Multiple Content Block Section", "content_blocks": [ cls._get_header_content_block(header="Multiple Content Block Section"), cls._get_graph_content_block(header="My col-4 Graph", col=4), cls._get_graph_content_block(header="My col-4 Graph", col=4), cls._get_graph_content_block(header="My col-4 Graph", col=4), cls._get_table_content_block(header="My col-6 Table", col=6), cls._get_bullet_list_content_block(header="My col-6 List", subheader="subheader", col=6) ] }), ] })
def render(cls, index_links_dict): sections = [] cta_object = index_links_dict.pop("cta_object", None) for source, generators in index_links_dict.items(): content_blocks = [] # datasource header source_header_block = RenderedComponentContent( **{ "content_block_type": "header", "header": { "template": "$title_prefix | $source", "params": { "source": source, "title_prefix": "Datasource" }, "styling": { "params": { "title_prefix": { "tag": "strong" } } }, }, "styling": { "classes": ["col-12", "ge-index-page-datasource-title"], "header": { "classes": ["alert", "alert-secondary"] } } }) content_blocks.append(source_header_block) # generator header for generator, data_assets in generators.items(): generator_header_block = RenderedComponentContent( **{ "content_block_type": "header", "subheader": { "template": "$title_prefix | $generator", "params": { "generator": generator, "title_prefix": "Data Asset Generator" }, "styling": { "params": { "title_prefix": { "tag": "strong" } } }, }, "styling": { "classes": [ "col-12", "ml-4", "ge-index-page-generator-title" ], } }) content_blocks.append(generator_header_block) generator_table_rows = [] generator_table_header_row = [ RenderedComponentContent( **{ "content_block_type": "string_template", "string_template": { "template": "Data Asset", "params": {}, "styling": { "classes": [ "ge-index-page-generator-table-data-asset-header" ], } } }) ] link_list_keys_to_render = [] header_dict = OrderedDict( [["profiling_links", "Profiling Results"], ["expectations_links", "Expectation Suite"], ["validations_links", "Validation Results"]]) for link_lists_key, header in header_dict.items(): for data_asset, link_lists in data_assets.items(): if header in generator_table_header_row: continue if link_lists.get(link_lists_key): class_header_str = link_lists_key.replace("_", "-") class_str = "ge-index-page-generator-table-{}-header".format( class_header_str) header = RenderedComponentContent( **{ "content_block_type": "string_template", "string_template": { "template": header, "params": {}, "styling": { "classes": [class_str], } } }) generator_table_header_row.append(header) link_list_keys_to_render.append(link_lists_key) generator_table = RenderedComponentContent( **{ "content_block_type": "table", "header_row": generator_table_header_row, "table": generator_table_rows, "styling": { "classes": [ "col-12", "ge-index-page-generator-table-container", "pl-5", "pr-4" ], "styles": { "margin-top": "10px" }, "body": { "classes": [ "table", "table-sm", "ge-index-page-generator-table" ] } } }) # data_assets for data_asset, link_lists in data_assets.items(): generator_table_rows += cls._generate_data_asset_table_section( data_asset, link_lists, link_list_keys_to_render=link_list_keys_to_render) content_blocks.append(generator_table) section = RenderedSectionContent(**{ "section_name": source, "content_blocks": content_blocks }) sections.append(section) index_page_document = RenderedDocumentContent(**{ "utm_medium": "index-page", "sections": sections }) if cta_object: index_page_document["cta_footer"] = CallToActionRenderer.render( cta_object) return index_page_document
def render(cls, index_links_dict): sections = [] cta_object = index_links_dict.pop("cta_object", None) try: content_blocks = [] # site name header site_name_header_block = RenderedHeaderContent( **{ "content_block_type": "header", "header": RenderedStringTemplateContent( **{ "content_block_type": "string_template", "string_template": { "template": "$title_prefix | $site_name", "params": { "site_name": index_links_dict.get( "site_name"), "title_prefix": "Data Docs" }, "styling": { "params": { "title_prefix": { "tag": "strong" } } }, } }), "styling": { "classes": ["col-12", "ge-index-page-site-name-title"], "header": { "classes": ["alert", "alert-secondary"] } } }) content_blocks.append(site_name_header_block) table_rows = [] table_header_row = [] link_list_keys_to_render = [] header_dict = OrderedDict( [["expectations_links", "Expectation Suite"], ["validations_links", "Validation Results (run_id)"]]) for link_lists_key, header in header_dict.items(): if index_links_dict.get(link_lists_key): class_header_str = link_lists_key.replace("_", "-") class_str = "ge-index-page-table-{}-header".format( class_header_str) header = RenderedStringTemplateContent( **{ "content_block_type": "string_template", "string_template": { "template": header, "params": {}, "styling": { "classes": [class_str], } } }) table_header_row.append(header) link_list_keys_to_render.append(link_lists_key) generator_table = RenderedTableContent( **{ "content_block_type": "table", "header_row": table_header_row, "table": table_rows, "styling": { "classes": ["col-12", "ge-index-page-table-container"], "styles": { "margin-top": "10px" }, "body": { "classes": [ "table", "table-sm", "ge-index-page-generator-table" ] } } }) table_rows += cls._generate_links_table_rows( index_links_dict, link_list_keys_to_render=link_list_keys_to_render) content_blocks.append(generator_table) if index_links_dict.get("profiling_links"): profiling_table_rows = [] for profiling_link_dict in index_links_dict.get( "profiling_links"): profiling_table_rows.append([ RenderedStringTemplateContent( **{ "content_block_type": "string_template", "string_template": { "template": "$link_text", "params": { "link_text": profiling_link_dict[ "expectation_suite_name"] + "." + profiling_link_dict["batch_identifier"] }, "tag": "a", "styling": { "attributes": { "href": profiling_link_dict["filepath"] }, "classes": [ "ge-index-page-table-expectation-suite-link" ] } }, }) ]) content_blocks.append( RenderedTableContent( **{ "content_block_type": "table", "header_row": ["Profiling Results"], "table": profiling_table_rows, "styling": { "classes": ["col-12", "ge-index-page-table-container"], "styles": { "margin-top": "10px" }, "body": { "classes": [ "table", "table-sm", "ge-index-page-generator-table" ] } } })) section = RenderedSectionContent( **{ "section_name": index_links_dict.get("site_name"), "content_blocks": content_blocks }) sections.append(section) index_page_document = RenderedDocumentContent( **{ "renderer_type": "SiteIndexPageRenderer", "utm_medium": "index-page", "sections": sections }) if cta_object: index_page_document.cta_footer = CallToActionRenderer.render( cta_object) return index_page_document except Exception as e: logger.error("Exception occurred during data docs rendering: ", e, exc_info=True)
def test_render_DefaultJinjaPageView_meta_info(): validation_results = { "results": [], "statistics": { "evaluated_expectations": 156, "successful_expectations": 139, "unsuccessful_expectations": 17, "success_percent": 89.1025641025641 }, "meta": { "great_expectations.__version__": "0.7.0-beta", "data_asset_name": "tetanusvaricella", "expectation_suite_name": "my_suite", "run_id": "2019-06-25T14:58:09.960521", "batch_kwargs": { "path": "/Users/user/project_data/public_healthcare_datasets/tetanusvaricella/tetvardata.csv", "timestamp": 1561474688.693565 } } } document = RenderedDocumentContent( dict_to_ordered_dict( ProfilingResultsPageRenderer().render(validation_results))) html = DefaultJinjaPageView().render(document) print(html) expected_html = """ <!DOCTYPE html> <html> <head> <title>Data documentation compiled by Great Expectations</title> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title></title> <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css"/> <style> body { position: relative; } .container { padding-top: 50px; } .sticky { position: -webkit-sticky; position: sticky; max-height: 90vh; overflow-y: auto; top: 15px; } .ge-section { clear:both; margin-bottom: 30px; padding-bottom: 20px; } .triangle { border: solid #222; border-width: 0 1px 1px 0; display: inline; cursor: pointer; padding: 3px; position: absolute; right: 0; margin-top: 10px; transform: rotate(40deg); -webkit-transform: rotate(40deg); transition: .3s transform ease-in-out; } .collapsed .triangle{ transform: rotate(-140deg); -webkit-transform: rotate(-140deg); transition: .3s transform ease-in-out; } .popover { max-width: 100%; } .cooltip { display:inline-block; position:relative; text-align:left; cursor:pointer; } .cooltip .top { min-width:200px; top:-6px; left:50%; transform:translate(-50%, -100%); padding:10px 20px; color:#FFFFFF; background-color:#222222; font-weight:normal; font-size:13px; border-radius:8px; position:absolute; z-index:99999999 !important; box-sizing:border-box; box-shadow:0 1px 8px rgba(0,0,0,0.5); display:none; } .cooltip:hover .top { display:block; z-index:99999999 !important; } .cooltip .top i { position:absolute; top:100%; left:50%; margin-left:-12px; width:24px; height:12px; overflow:hidden; } .cooltip .top i::after { content:''; position:absolute; width:12px; height:12px; left:50%; transform:translate(-50%,-50%) rotate(45deg); background-color:#222222; box-shadow:0 1px 8px rgba(0,0,0,0.5); } ul { padding-inline-start: 20px; } .table-cell-frame { overflow-y: auto; max-height: 200px; } .table-cell-frame ul { padding-bottom: 20px } .table-cell-frame::-webkit-scrollbar { -webkit-appearance: none; } .table-cell-frame::-webkit-scrollbar:vertical { width: 11px; } .table-cell-frame::-webkit-scrollbar:horizontal { height: 11px; } .table-cell-frame::-webkit-scrollbar-thumb { border-radius: 8px; border: 2px solid white; /* should match background, can't be transparent */ background-color: rgba(0, 0, 0, .5); }</style> <style></style> <script src="https://cdn.jsdelivr.net/npm/[email protected]/build/vega.js"></script> <script src="https://cdn.jsdelivr.net/npm/[email protected]/build/vega-lite.js"></script> <script src="https://cdn.jsdelivr.net/npm/[email protected]/build/vega-embed.js"></script> <script src="https://kit.fontawesome.com/8217dffd95.js"></script> </head> <body data-spy="scroll" data-target="#navigation" data-offset="50" > <nav aria-label="breadcrumb"> <ol class="ge-breadcrumbs breadcrumb"> <li class="ge-breadcrumbs-item breadcrumb-item"><a href="../../../../../index.html">Home</a></li> <li class="ge-breadcrumbs-item breadcrumb-item">tetanusvaricella</li> <li class="ge-breadcrumbs-item breadcrumb-item active" aria-current="page">2019-06-25T14:58:09.960521-my_suite-ProfilingResults</li> </ol> </nav> <div class="container-fluid px-3"> <div class="row"> <div class="col-2 navbar-collapse"> <nav id="navigation" class="navbar navbar-light bg-light sticky d-none d-sm-block ge-navigation-sidebar-container"> <nav class="nav nav-pills flex-column ge-navigation-sidebar-content"> <a class="navbar-brand ge-navigation-sidebar-title" href="#" style="white-space: normal; word-break: break-all;overflow-wrap: normal; font-size: 1rem; font-weight: 500;">tetanusvaricella</a> <a class="nav-link ge-navigation-sidebar-link" href="#section-1">Overview</a> </nav> </nav> </div> <div class="col-md-8 col-lg-8 col-xs-12"> <div id="section-1" class="ge-section container-fluid"> <div class="row"> <div id="section-1-content-block-1" class="col-12" > <div id="section-1-content-block-1-header" class="alert alert-secondary" > <h3> Overview </h3></div> </div> <div id="section-1-content-block-2" class="col-6" style="margin-top:20px;" > <div id="section-1-content-block-2-header" > <h4> Dataset info </h4> </div> <table id="section-1-content-block-2-body" class="table table-sm" > <tr> <td id="section-1-content-block-2-cell-1-1" ><div class="table-cell-frame"><span>Number of variables</span></div></td><td id="section-1-content-block-2-cell-1-2" ><div class="table-cell-frame">0</div></td></tr><tr> <td id="section-1-content-block-2-cell-2-1" ><div class="table-cell-frame"> <span class="cooltip" > Number of observations <span class=top> expect_table_row_count_to_be_between </span> </span> </div></td><td id="section-1-content-block-2-cell-2-2" ><div class="table-cell-frame"><span>--</span></div></td></tr><tr> <td id="section-1-content-block-2-cell-3-1" ><div class="table-cell-frame"><span>Missing cells</span></div></td><td id="section-1-content-block-2-cell-3-2" ><div class="table-cell-frame"><span>?</span></div></td></tr></table> </div> <div id="section-1-content-block-3" class="col-6 table-responsive" style="margin-top:20px;" > <div id="section-1-content-block-3-header" > <h4> Variable types </h4> </div> <table id="section-1-content-block-3-body" class="table table-sm" > <tr> <td id="section-1-content-block-3-cell-1-1" ><div class="table-cell-frame"><span>int</span></div></td><td id="section-1-content-block-3-cell-1-2" ><div class="table-cell-frame"><span>0</span></div></td></tr><tr> <td id="section-1-content-block-3-cell-2-1" ><div class="table-cell-frame"><span>float</span></div></td><td id="section-1-content-block-3-cell-2-2" ><div class="table-cell-frame"><span>0</span></div></td></tr><tr> <td id="section-1-content-block-3-cell-3-1" ><div class="table-cell-frame"><span>string</span></div></td><td id="section-1-content-block-3-cell-3-2" ><div class="table-cell-frame"><span>0</span></div></td></tr><tr> <td id="section-1-content-block-3-cell-4-1" ><div class="table-cell-frame"><span>unknown</span></div></td><td id="section-1-content-block-3-cell-4-2" ><div class="table-cell-frame"><span>0</span></div></td></tr></table> </div>""" expected_html_2 = """ </div> </div> </div> <div class="col-lg-2 col-md-2 col-xs-12 d-none d-md-block"> <div> <div class="col-12"> <div class="row"> <img src="https://great-expectations.readthedocs.io/en/latest/_images/generic_dickens_protagonist.png" style=" width: 200px; margin-left: auto; margin-right: auto; "> </div> </div> <div class="col-12"> <p> Documentation autogenerated using <a href="https://greatexpectations.io">Great Expectations</a>. </p> </div> <div class="alert alert-danger col-12" role="alert"> This is a beta feature! Expect changes in API, behavior, and design. </div> </div> </div> <div class="d-block d-sm-none col-12"> <div> <div class="row"> <img src="https://great-expectations.readthedocs.io/en/latest/_images/generic_dickens_protagonist.png" style=" width: 200px; margin-left: auto; margin-right: auto; "> </div> </div> <div class="col-12"> <p> Documentation autogenerated using <a href="https://greatexpectations.io">Great Expectations</a>. </p> </div> <div class="alert alert-danger col-12" role="alert"> This is a beta feature! Expect changes in API, behavior, and design. </div> </div> </div> </div> <script src="https://code.jquery.com/jquery-3.2.1.slim.min.js"></script> <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js"></script> <script> $(window).on('activate.bs.scrollspy', function () { document.querySelector(".nav-link.active").scrollIntoViewIfNeeded(); }); </script> </body> </html> """ assert expected_html.replace(" ", "").replace("\t", "").replace( "\n", "") in html.replace(" ", "").replace("\t", "").replace("\n", "") assert expected_html_2.replace(" ", "").replace("\t", "").replace( "\n", "") in html.replace(" ", "").replace("\t", "").replace("\n", "")