def test_render_profiling_results(titanic_profiled_evrs_1): rendered_json = ProfilingResultsPageRenderer().render(titanic_profiled_evrs_1) rendered_page = DefaultJinjaPageView().render(rendered_json) with open('./tests/render/output/test_render_profiling_results.html', 'wb') as f: f.write(rendered_page.encode("utf-8")) assert rendered_page[:15] == "<!DOCTYPE html>" assert rendered_page[-7:] == "</html>"
def test_render_profiled_fixture_expectation_suite(titanic_dataset_profiler_expectations): rendered_json = ExpectationSuitePageRenderer().render(titanic_dataset_profiler_expectations) rendered_page = DefaultJinjaPageView().render(rendered_json) with open('./tests/render/output/test_render_profiled_fixture_expectation_suite.html', 'wb') as f: f.write(rendered_page.encode("utf-8")) assert rendered_page[:15] == "<!DOCTYPE html>" assert rendered_page[-7:] == "</html>"
def test_render_profiled_fixture_expectation_suite(titanic_dataset_profiler_expectations): rendered_content = ExpectationSuitePageRenderer().render(titanic_dataset_profiler_expectations) rendered_page = DefaultJinjaPageView().render(rendered_content) with open(file_relative_path(__file__, './output/test_render_profiled_fixture_expectation_suite.html'), 'wb') as f: f.write(rendered_page.encode("utf-8")) assert rendered_page[:15] == "<!DOCTYPE html>" assert rendered_page[-7:] == "</html>"
def test_render_profiling_results(titanic_profiled_evrs_1): rendered_content = ProfilingResultsPageRenderer().render(titanic_profiled_evrs_1) rendered_page = DefaultJinjaPageView().render(rendered_content) with open(file_relative_path(__file__, './output/test_render_profiling_results.html'), 'wb') as f: f.write(rendered_page.encode("utf-8")) assert rendered_page[:15] == "<!DOCTYPE html>" assert rendered_page[-7:] == "</html>"
def test_smoke_render_profiling_results_page_renderer_with_exception(titanic_profiler_evrs_with_exception): rendered_json = ProfilingResultsPageRenderer().render(titanic_profiler_evrs_with_exception) rendered_page = DefaultJinjaPageView().render(rendered_json) with open('./tests/render/output/test_render_profiling_results_column_section_renderer_with_exception.html', 'wb') as f: f.write(rendered_page.encode("utf-8")) assert rendered_page[:15] == "<!DOCTYPE html>" assert rendered_page[-7:] == "</html>" assert "exception" in rendered_page
def test_render_string_template_bug_1(): #Looks like string templates can't contain dollar signs. We need some kind of escaping with pytest.raises(ValueError): template = { 'template': 'Car Insurance Premiums ($)', 'tooltip': { 'content': 'expect_column_to_exist', 'placement': 'top' } } DefaultJinjaPageView.render_string_template(template)
def test_render_validation_results(titanic_profiled_evrs_1): rendered_content = ValidationResultsPageRenderer().render(titanic_profiled_evrs_1) rendered_page = DefaultJinjaPageView().render(rendered_content) with open(file_relative_path(__file__, './output/test_render_validation_results.html'), 'wb') as f: f.write(rendered_page.encode("utf-8")) assert rendered_page[:15] == "<!DOCTYPE html>" assert rendered_page[-7:] == "</html>" assert "Table-Level Expectations" in rendered_page assert 'Must have more than <span class="badge badge-secondary" >0</span> rows.' in rendered_page
def test_render_validation_results(titanic_profiled_evrs_1): rendered_json = ValidationResultsPageRenderer().render(titanic_profiled_evrs_1) rendered_page = DefaultJinjaPageView().render(rendered_json) with open('./tests/render/output/test_render_validation_results.html', 'wb') as f: f.write(rendered_page.encode("utf-8")) assert rendered_page[:15] == "<!DOCTYPE html>" assert rendered_page[-7:] == "</html>" assert "Table-Level Expectations" in rendered_page assert 'Must have more than <span class="badge badge-secondary" >0</span> rows.' in rendered_page assert 'Must have between <span class="badge badge-secondary" >0</span> and <span class="badge badge-secondary" >23</span> columns.' in rendered_page
def test_smoke_render_profiling_results_page_renderer_with_exception( titanic_profiler_evrs_with_exception): rendered_content = ProfilingResultsPageRenderer().render(titanic_profiler_evrs_with_exception) rendered_page = DefaultJinjaPageView().render(rendered_content) with open( file_relative_path(__file__, './output/test_render_profiling_results_column_section_renderer_with_exception.html'), 'wb' ) as outfile: outfile.write(rendered_page.encode("utf-8")) assert rendered_page[:15] == "<!DOCTYPE html>" assert rendered_page[-7:] == "</html>" assert "exception" in rendered_page
def test_full_oobe_flow(): df = ge.read_csv("examples/data/Titanic.csv") df.profile(BasicDatasetProfiler) evrs = df.validate() # ["results"] rendered_json = ProfilingResultsPageRenderer().render(evrs) rendered_page = DefaultJinjaPageView().render(rendered_json) with open('./tests/render/output/test_full_oobe_flow.html', 'wb') as f: f.write(rendered_page.encode("utf-8")) assert rendered_page[:15] == "<!DOCTYPE html>" assert rendered_page[-7:] == "</html>"
def test_full_oobe_flow(): df = ge.read_csv(file_relative_path(__file__, "../../examples/data/Titanic.csv")) df.data_asset_name = "my_datasource/my_generator/my_asset" df.profile(BasicDatasetProfiler) evrs = df.validate() # results rendered_content = ProfilingResultsPageRenderer().render(evrs) rendered_page = DefaultJinjaPageView().render(rendered_content) with open(file_relative_path(__file__, './output/test_full_oobe_flow.html'), 'wb') as f: f.write(rendered_page.encode("utf-8")) assert rendered_page[:15] == "<!DOCTYPE html>" assert rendered_page[-7:] == "</html>"
def test_render_template_with_extra_dollar_signs_in_param_values(): result = DefaultJinjaPageView().render_string_template({ "template": "It was the $first_adj of times; it was the $second_adj of times. Blahhh$hhhh. $Bloooop. " "Bleep$.", "params": { "first_adj": "$best$", "second_adj": "$$worst$", }, }) assert result.replace(" ", "").replace("\t", "").replace( "\n", "" ) == "<span>It was the $best$ of times; it was the $$worst$ of times. Blahhh$hhhh. $Bloooop. Bleep$.</span>".replace( " ", "").replace("\t", "").replace("\n", "")
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_DefaultJinjaPageView_meta_info(): validation_results = ExpectationSuiteValidationResult( **{ "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": "datasource/generator/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 = ProfilingResultsPageRenderer().render(validation_results) html = DefaultJinjaPageView().render(document) with open( file_relative_path( __file__, "./output/test_render_DefaultJinjaPageView_meta_info.html"), "w", ) as outfile: outfile.write(html)
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 = DescriptivePageRenderer.render(validation_results) html = DefaultJinjaPageView.render(document) print(html) # TODO: Use above print to set up snapshot test once we like the result assert '<a class="navbar-brand" href="#">tetanusvaricella</a>' in html
def test_render_descriptive_page_view(titanic_validation_results): document = DescriptivePageRenderer.render(titanic_validation_results) rendered = DefaultJinjaPageView.render(document) with open('./tests/render/output/test_render_descriptive_page_view.html', 'w') as outfile: outfile.write(rendered) assert len(rendered) > 1000
def test_render_profiled_fixture_expectation_suite_with_distribution( titanic_dataset_profiler_expectations_with_distribution, ): # Tests sparkline rendered_content = ExpectationSuitePageRenderer().render( titanic_dataset_profiler_expectations_with_distribution) rendered_page = DefaultJinjaPageView().render(rendered_content) with open( file_relative_path( __file__, "./output/titanic_dataset_profiler_expectation_suite_with_distribution.html", ), "wb", ) as f: f.write(rendered_page.encode("utf-8")) assert rendered_page[:15] == "<!DOCTYPE html>" assert rendered_page[-7:] == "</html>"
def test_render_profiled_fixture_evrs(titanic_profiler_evrs): rendered_json = DescriptivePageRenderer.render(titanic_profiler_evrs) rendered_page = DefaultJinjaPageView.render(rendered_json) with open('./tests/render/output/test_render_profiled_fixture_evrs.html', 'w') as f: f.write(rendered_page) assert rendered_page[:15] == "<!DOCTYPE html>" assert rendered_page[-7:] == "</html>"
def render(render_object): """Render a great expectations object to documentation. RENDER_OBJECT: path to a GE object to render """ with open(render_object, "r") as infile: raw = json.load(infile) model = DescriptivePageRenderer.render(raw) # model = PrescriptivePageRenderer.render(raw) print(DefaultJinjaPageView.render(model))
def test_render_validation_results(titanic_profiled_evrs_1): rendered_json = ValidationResultsPageRenderer.render( titanic_profiled_evrs_1) rendered_page = DefaultJinjaPageView.render(rendered_json) with open('./tests/render/output/test_render_validation_results.html', 'w') as f: f.write(rendered_page) assert rendered_page[:15] == "<!DOCTYPE html>" assert rendered_page[-7:] == "</html>"
def render(render_object): """Render a great expectations object to documentation. RENDER_OBJECT: path to a GE object to render """ with open(render_object, "r") as infile: raw = json.load(infile) if "results" in raw: model = ProfilingResultsPageRenderer.render(raw) else: model = ExpectationSuitePageRenderer.render(raw) print(DefaultJinjaPageView.render(model))
def test_render_profiled_fixture_expectations( tetanus_varicella_basic_dataset_profiler_expectations): rendered_json = PrescriptivePageRenderer.render( tetanus_varicella_basic_dataset_profiler_expectations) rendered_page = DefaultJinjaPageView.render(rendered_json) with open( './tests/render/output/test_render_profiled_fixture_expectations.html', 'w') as f: f.write(rendered_page) assert rendered_page[:15] == "<!DOCTYPE html>" assert rendered_page[-7:] == "</html>"
def test_smoke_render_descriptive_page_renderer_with_exception( tetanus_varicella_basic_dataset_profiler_evrs_with_exception): rendered_json = DescriptivePageRenderer.render( tetanus_varicella_basic_dataset_profiler_evrs_with_exception) rendered_page = DefaultJinjaPageView.render(rendered_json) with open( './tests/render/output/test_render_descriptive_column_section_renderer_with_exception.html', 'w') as f: f.write(rendered_page) assert rendered_page[:15] == "<!DOCTYPE html>" assert rendered_page[-7:] == "</html>" assert "exception" in rendered_page
def test_render_profiled_fixture_expectations_with_distribution( titanic_dataset_profiler_expectations_with_distribution): # Tests sparkline rendered_json = PrescriptivePageRenderer.render( titanic_dataset_profiler_expectations_with_distribution) rendered_page = DefaultJinjaPageView.render(rendered_json) with open( './tests/render/output/titanic_dataset_profiler_expectations_with_distribution.html', 'wb') as f: f.write(rendered_page.encode("utf-8")) assert rendered_page[:15] == "<!DOCTYPE html>" assert rendered_page[-7:] == "</html>"
def test_render_string_template(): template = { "template": "$column Kullback-Leibler (KL) divergence with respect to the following distribution must be lower than $threshold: $sparklines_histogram", "params": { "column": "categorical_fixed", "partition_object": { "weights": [ 0.54, 0.32, 0.14 ], "values": [ "A", "B", "C" ] }, "threshold": 0.1, "sparklines_histogram": u"\u2588\u2584\u2581" }, "styling": { "default": { "classes": [ "badge", "badge-secondary" ] }, "params": { "sparklines_histogram": { "styles": { "font-family": "serif" } } } } } res = DefaultJinjaPageView().render_string_template(template).replace(" ", "").replace("\t", "").replace("\n", "") expected = u"""<span> <span class="badge badge-secondary" >categorical_fixed</span> Kullback-Leibler (KL) divergence with respect to the following distribution must be lower than <span class="badge badge-secondary" >0.1</span>: <span style="font-family:serif;" >█▄▁</span> </span>""".replace(" ", "").replace("\t", "").replace("\n", "") assert res == expected template = { "template": "$column Kullback-Leibler (KL) divergence with respect to the following distribution must be lower than $threshold: $sparklines_histogram", "params": { "column": "categorical_fixed", "partition_object": { "weights": [ 0.54, 0.32, 0.14 ], "values": [ "A", "B", "C" ] }, "threshold": 0.1, "sparklines_histogram": u"▃▆▁█" }, "styling": { "default": { "classes": [ "badge", "badge-secondary" ] }, "params": { "sparklines_histogram": { "styles": { "font-family": "serif" } } } } } res = DefaultJinjaPageView().render_string_template(template).replace(" ", "").replace("\t", "").replace("\n", "") expected = u"""<span> <span class="badge badge-secondary" >categorical_fixed</span> Kullback-Leibler (KL) divergence with respect to the following distribution must be lower than <span class="badge badge-secondary" >0.1</span>: <span style="font-family:serif;" >▃▆▁█</span> </span>""".replace(" ", "").replace("\t", "").replace("\n", "") assert res == expected
def test_render_template(): assert DefaultJinjaPageView().render_string_template({ "template": "It was the $first_adj of times; it was the $second_adj of times.", "params": { "first_adj": "best", "second_adj": "worst", }, }).replace(" ", "").replace("\t", "").replace( "\n", "" ) == "<span>It was the best of times; it was the worst of times.</span>".replace( " ", "").replace("\t", "").replace("\n", "") assert DefaultJinjaPageView().render_string_template({ "template": "It was the $first_adj of times; it was the $second_adj of times.", "params": { "first_adj": "best", "second_adj": "worst", }, "styling": { "default": { "classes": ["badge", "badge-warning"], } }, }).replace(" ", "").replace("\t", "").replace( "\n", "" ) == '<span>It was the <span class="badge badge-warning" >best</span> of times; it was the <span class="badge badge-warning" >worst</span> of times.</span>'.replace( " ", "").replace("\t", "").replace("\n", "") assert DefaultJinjaPageView().render_string_template({ "template": "It was the $first_adj of times; it was the $second_adj of times.", "params": { "first_adj": "best", "second_adj": "worst", }, "styling": { "default": { "classes": ["badge", "badge-warning"], }, "params": { "first_adj": { "classes": ["badge-error"], } }, }, }).replace(" ", "").replace("\t", "").replace( "\n", "" ) == '<span>It was the <span class="badge-error" >best</span> of times; it was the <span class="badge badge-warning" >worst</span> of times.</span>'.replace( " ", "").replace("\t", "").replace("\n", "") assert DefaultJinjaPageView().render_string_template({ "template": "It was the $first_adj of times; it was the $second_adj of times.", "params": { "first_adj": "best", "second_adj": "worst", }, "styling": { "params": { "first_adj": { "classes": ["badge", "badge-warning"], } } }, }).replace(" ", "").replace("\t", "").replace( "\n", "" ) == '<span>It was the <span class="badge badge-warning" >best</span> of times; it was the worst of times.</span>'.replace( " ", "").replace("\t", "").replace("\n", "") assert DefaultJinjaPageView().render_string_template({ "template": "It was the $first_adj of times; it was the $second_adj of times.", "params": { "first_adj": "best", "second_adj": "worst", }, "styling": { "params": { "first_adj": { "classes": ["badge", "badge-warning"], "attributes": { "role": "alert" }, "styles": { "padding": "5px" }, } } }, }).replace(" ", "").replace("\t", "").replace( "\n", "" ) == '<span>It was the <span class="badge badge-warning" role="alert" style="padding:5px;" >best</span> of times; it was the worst of times.</span>'.replace( " ", "").replace("\t", "").replace("\n", "")
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", "")