Fix: Borken HTML in jinja template (#712)
This commit is contained in:
parent
8bc9a5d89b
commit
bd0c5302ec
|
@ -26,12 +26,27 @@
|
|||
<td></td>
|
||||
</tr>
|
||||
</template>
|
||||
<template id="template_results-table__head">
|
||||
<thead id="results-table-head">
|
||||
<tr>
|
||||
{%- for th in table_head %}
|
||||
{{ th|safe }}
|
||||
{%- endfor %}
|
||||
</tr>
|
||||
</thead>
|
||||
</template>
|
||||
<template id="template_results-table__body--empty">
|
||||
<tbody class="results-table-row">
|
||||
<tr id="not-found-message">
|
||||
<td colspan="{{ table_head|length }}">No results found. Check the filters.</th>
|
||||
</tr>
|
||||
</template>
|
||||
<template id="template_results-table__tbody">
|
||||
<tbody class="results-table-row">
|
||||
<tr class="collapsible">
|
||||
</tr>
|
||||
<tr class="extras-row">
|
||||
<td class="extra" colspan="4">
|
||||
<td class="extra" colspan="{{ table_head|length }}">
|
||||
<div class="extraHTML"></div>
|
||||
<div class="media">
|
||||
<div class="media-container">
|
||||
|
@ -52,27 +67,15 @@
|
|||
</tr>
|
||||
</tbody>
|
||||
</template>
|
||||
<template id="template_results-table__head">
|
||||
<thead id="results-table-head">
|
||||
<tr>
|
||||
{%- for th in table_head %}
|
||||
{{ th|safe }}
|
||||
{%- endfor %}
|
||||
</tr>
|
||||
</thead>
|
||||
</template>
|
||||
<template id="template_results-table__head--empty">
|
||||
<tr id="not-found-message">
|
||||
<th colspan="4">No results found. Check the filters.</th>
|
||||
</tr>
|
||||
</template>
|
||||
<!-- END TEMPLATES -->
|
||||
<div class="summary">
|
||||
<div class="summary__data">
|
||||
<h2>Summary</h2>
|
||||
{%- for p in additional_summary['prefix'] %}
|
||||
{{ p|safe }}
|
||||
{%- endfor %}
|
||||
<div class="additional-summary prefix">
|
||||
{%- for p in additional_summary['prefix'] %}
|
||||
{{ p|safe }}
|
||||
{%- endfor %}
|
||||
</div>
|
||||
<p class="run-count">{{ run_count }}</p>
|
||||
<p class="filter">(Un)check the boxes to filter the results.</p>
|
||||
<div class="summary__reload">
|
||||
|
@ -81,25 +84,29 @@
|
|||
</div>
|
||||
</div>
|
||||
<div class="summary__spacer"></div>
|
||||
<div class="controls">
|
||||
<div class="filters">
|
||||
{%- for result, values in outcomes.items() %}
|
||||
<input checked="true" class="filter" name="filter_checkbox" type="checkbox" data-test-result="{{ result }}" {{ "disabled" if values["value"] == 0 }}/>
|
||||
<span class="{{ result }}">{{ values["value"] }} {{ values["label"] }}{{ "," if result != "rerun" }}</span>
|
||||
{%- endfor %}
|
||||
</div>
|
||||
<div class="collapse">
|
||||
<button id="show_all_details">Show all details</button> / <button id="hide_all_details">Hide all details</button>
|
||||
<div>
|
||||
<div class="controls">
|
||||
<div class="filters">
|
||||
{%- for result, values in outcomes.items() %}
|
||||
<input checked="true" class="filter" name="filter_checkbox" type="checkbox" data-test-result="{{ result }}" {{ "disabled" if values["value"] == 0 }}/>
|
||||
<span class="{{ result }}">{{ values["value"] }} {{ values["label"] }}{{ "," if result != "rerun" }}</span>
|
||||
{%- endfor %}
|
||||
</div>
|
||||
<div class="collapse">
|
||||
<button id="show_all_details">Show all details</button> / <button id="hide_all_details">Hide all details</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{%- for s in additional_summary['summary'] %}
|
||||
{{ s|safe }}
|
||||
{%- endfor %}
|
||||
{%- for p in additional_summary['postfix'] %}
|
||||
{{ p|safe }}
|
||||
{%- endfor %}
|
||||
<div class="additional-summary summary">
|
||||
{%- for s in additional_summary['summary'] %}
|
||||
{{ s|safe }}
|
||||
{%- endfor %}
|
||||
</div>
|
||||
<div class="additional-summary postfix">
|
||||
{%- for p in additional_summary['postfix'] %}
|
||||
{{ p|safe }}
|
||||
{%- endfor %}
|
||||
</div>
|
||||
</div>
|
||||
<table id="results-table"></table>
|
||||
</body>
|
||||
<footer>
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
const mediaViewer = require('./mediaviewer.js')
|
||||
const templateEnvRow = document.getElementById('template_environment_row')
|
||||
const templateResult = document.getElementById('template_results-table__tbody')
|
||||
const listHeaderEmpty = document.getElementById('template_results-table__head--empty')
|
||||
|
||||
function htmlToElements(html) {
|
||||
const temp = document.createElement('template')
|
||||
|
@ -37,7 +36,6 @@ const dom = {
|
|||
|
||||
return envRow
|
||||
},
|
||||
getListHeaderEmpty: () => listHeaderEmpty.content.cloneNode(true),
|
||||
getResultTBody: ({ testId, id, log, duration, extras, resultsTableRow, tableHtml, result, collapsed }) => {
|
||||
const resultLower = result.toLowerCase()
|
||||
const resultBody = templateResult.content.cloneNode(true)
|
||||
|
|
|
@ -38,17 +38,14 @@ const renderContent = (tests) => {
|
|||
removeChildren(table)
|
||||
|
||||
tableHeader.querySelector(`.sortable[data-column-type="${sortAttr}"]`)?.classList.add(sortAsc ? 'desc' : 'asc')
|
||||
if (!rows.length) {
|
||||
tableHeader.appendChild(dom.getListHeaderEmpty())
|
||||
}
|
||||
table.appendChild(tableHeader)
|
||||
if (!rows.length) {
|
||||
const emptyTable = document.getElementById('template_results-table__body--empty').content.cloneNode(true)
|
||||
table.appendChild(emptyTable)
|
||||
}
|
||||
|
||||
rows.forEach((row) => !!row && table.appendChild(row))
|
||||
|
||||
table.querySelectorAll('.extra').forEach((item) => {
|
||||
item.colSpan = document.querySelectorAll('th').length
|
||||
})
|
||||
|
||||
findAll('.sortable').forEach((elem) => {
|
||||
elem.addEventListener('click', (evt) => {
|
||||
const { target: element } = evt
|
||||
|
|
|
@ -52,7 +52,13 @@ def run(pytester, path="report.html", cmd_flags=None, query_params=None):
|
|||
# End workaround
|
||||
|
||||
driver.get(f"file:///reports{path}?{query_params}")
|
||||
return BeautifulSoup(driver.page_source, "html.parser")
|
||||
soup = BeautifulSoup(driver.page_source, "html.parser")
|
||||
|
||||
# remove all templates as they bork the BS parsing
|
||||
for template in soup("template"):
|
||||
template.decompose()
|
||||
|
||||
return soup
|
||||
finally:
|
||||
driver.quit()
|
||||
|
||||
|
@ -88,15 +94,15 @@ def get_text(page, selector):
|
|||
|
||||
|
||||
def is_collapsed(page, test_name):
|
||||
return get_element(page, f".summary tbody[id$='{test_name}'] .collapsed")
|
||||
return get_element(page, f"tbody[id$='{test_name}'] .collapsed")
|
||||
|
||||
|
||||
def get_log(page, test_id=None):
|
||||
# TODO(jim) move to get_text (use .contents)
|
||||
if test_id:
|
||||
log = get_element(page, f".summary tbody[id$='{test_id}'] div[class='log']")
|
||||
log = get_element(page, f"tbody[id$='{test_id}'] div[class='log']")
|
||||
else:
|
||||
log = get_element(page, ".summary div[class='log']")
|
||||
log = get_element(page, "div[class='log']")
|
||||
all_text = ""
|
||||
for text in log.strings:
|
||||
all_text += text
|
||||
|
@ -195,7 +201,7 @@ class TestHTML:
|
|||
page = run(pytester)
|
||||
assert_results(page, skipped=1, total_tests=0)
|
||||
|
||||
log = get_text(page, ".summary div[class='log']")
|
||||
log = get_text(page, "div[class='log']")
|
||||
assert_that(log).contains(reason)
|
||||
|
||||
def test_skip_function_marker(self, pytester):
|
||||
|
@ -211,7 +217,7 @@ class TestHTML:
|
|||
page = run(pytester)
|
||||
assert_results(page, skipped=1, total_tests=0)
|
||||
|
||||
log = get_text(page, ".summary div[class='log']")
|
||||
log = get_text(page, "div[class='log']")
|
||||
assert_that(log).contains(reason)
|
||||
|
||||
def test_skip_class_marker(self, pytester):
|
||||
|
@ -228,7 +234,7 @@ class TestHTML:
|
|||
page = run(pytester)
|
||||
assert_results(page, skipped=1, total_tests=0)
|
||||
|
||||
log = get_text(page, ".summary div[class='log']")
|
||||
log = get_text(page, "div[class='log']")
|
||||
assert_that(log).contains(reason)
|
||||
|
||||
def test_fail(self, pytester):
|
||||
|
@ -236,7 +242,7 @@ class TestHTML:
|
|||
page = run(pytester)
|
||||
assert_results(page, failed=1)
|
||||
assert_that(get_log(page)).contains("AssertionError")
|
||||
assert_that(get_text(page, ".summary div[class='log'] span.error")).matches(
|
||||
assert_that(get_text(page, "div[class='log'] span.error")).matches(
|
||||
r"^E\s+assert False$"
|
||||
)
|
||||
|
||||
|
@ -352,7 +358,7 @@ class TestHTML:
|
|||
page = run(pytester)
|
||||
assert_results(page, error=1, total_tests=0)
|
||||
|
||||
col_name = get_text(page, ".summary td[class='col-name']")
|
||||
col_name = get_text(page, "td[class='col-name']")
|
||||
assert_that(col_name).contains("::setup")
|
||||
assert_that(get_log(page)).contains("ValueError")
|
||||
|
||||
|
@ -411,7 +417,9 @@ class TestHTML:
|
|||
pytester.makepyfile("def test_pass(): pass")
|
||||
page = run(pytester)
|
||||
|
||||
elements = page.select(".summary__data p:not(.run-count):not(.filter)")
|
||||
elements = page.select(
|
||||
".additional-summary p"
|
||||
) # ".summary__data p:not(.run-count):not(.filter)")
|
||||
assert_that(elements).is_length(3)
|
||||
for element in elements:
|
||||
key = re.search(r"(\w+).*", element.string).group(1)
|
||||
|
@ -437,7 +445,7 @@ class TestHTML:
|
|||
pytester.makepyfile("def test_pass(): pass")
|
||||
page = run(pytester)
|
||||
|
||||
assert_that(page.select_one(".summary .extraHTML").string).is_equal_to(content)
|
||||
assert_that(page.select_one(".extraHTML").string).is_equal_to(content)
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"content, encoded",
|
||||
|
@ -460,7 +468,7 @@ class TestHTML:
|
|||
pytester.makepyfile("def test_pass(): pass")
|
||||
page = run(pytester, cmd_flags=["--self-contained-html"])
|
||||
|
||||
element = page.select_one(".summary a[class='col-links__extra text']")
|
||||
element = page.select_one("a[class='col-links__extra text']")
|
||||
assert_that(element.string).is_equal_to("Text")
|
||||
assert_that(element["href"]).is_equal_to(
|
||||
f"data:text/plain;charset=utf-8;base64,{encoded}"
|
||||
|
@ -488,7 +496,7 @@ class TestHTML:
|
|||
content_str = json.dumps(content)
|
||||
data = b64encode(content_str.encode("utf-8")).decode("ascii")
|
||||
|
||||
element = page.select_one(".summary a[class='col-links__extra json']")
|
||||
element = page.select_one("a[class='col-links__extra json']")
|
||||
assert_that(element.string).is_equal_to("JSON")
|
||||
assert_that(element["href"]).is_equal_to(
|
||||
f"data:application/json;charset=utf-8;base64,{data}"
|
||||
|
@ -512,7 +520,7 @@ class TestHTML:
|
|||
pytester.makepyfile("def test_pass(): pass")
|
||||
page = run(pytester)
|
||||
|
||||
element = page.select_one(".summary a[class='col-links__extra url']")
|
||||
element = page.select_one("a[class='col-links__extra url']")
|
||||
assert_that(element.string).is_equal_to("URL")
|
||||
assert_that(element["href"]).is_equal_to(content)
|
||||
|
||||
|
@ -551,7 +559,7 @@ class TestHTML:
|
|||
# assert_that(element.string).is_equal_to("Image")
|
||||
# assert_that(element["href"]).is_equal_to(src)
|
||||
|
||||
element = page.select_one(".summary .media img")
|
||||
element = page.select_one(".media img")
|
||||
assert_that(str(element)).is_equal_to(f'<img src="{src}"/>')
|
||||
|
||||
@pytest.mark.parametrize("mime_type, extension", [("video/mp4", "mp4")])
|
||||
|
@ -579,7 +587,7 @@ class TestHTML:
|
|||
# assert_that(element.string).is_equal_to("Video")
|
||||
# assert_that(element["href"]).is_equal_to(src)
|
||||
|
||||
element = page.select_one(".summary .media video")
|
||||
element = page.select_one(".media video")
|
||||
assert_that(str(element)).is_equal_to(
|
||||
f'<video controls="">\n<source src="{src}" type="{mime_type}"/>\n</video>'
|
||||
)
|
||||
|
@ -590,10 +598,8 @@ class TestHTML:
|
|||
assert_results(page, passed=1)
|
||||
|
||||
def test_results_table_hook_append(self, pytester):
|
||||
header_selector = (
|
||||
".summary #results-table-head tr:nth-child(1) th:nth-child({})"
|
||||
)
|
||||
row_selector = ".summary #results-table tr:nth-child(1) td:nth-child({})"
|
||||
header_selector = "#results-table-head tr:nth-child(1) th:nth-child({})"
|
||||
row_selector = "#results-table tr:nth-child(1) td:nth-child({})"
|
||||
|
||||
pytester.makeconftest(
|
||||
"""
|
||||
|
@ -628,10 +634,8 @@ class TestHTML:
|
|||
)
|
||||
|
||||
def test_results_table_hook_insert(self, pytester):
|
||||
header_selector = (
|
||||
".summary #results-table-head tr:nth-child(1) th:nth-child({})"
|
||||
)
|
||||
row_selector = ".summary #results-table tr:nth-child(1) td:nth-child({})"
|
||||
header_selector = "#results-table-head tr:nth-child(1) th:nth-child({})"
|
||||
row_selector = "#results-table tr:nth-child(1) td:nth-child({})"
|
||||
|
||||
pytester.makeconftest(
|
||||
"""
|
||||
|
@ -700,12 +704,10 @@ class TestHTML:
|
|||
pytester.makepyfile("def test_pass(): pass")
|
||||
page = run(pytester)
|
||||
|
||||
header_columns = page.select(".summary #results-table-head th")
|
||||
header_columns = page.select("#results-table-head th")
|
||||
assert_that(header_columns).is_length(3)
|
||||
|
||||
row_columns = page.select_one(".summary .results-table-row").select(
|
||||
"td:not(.extra)"
|
||||
)
|
||||
row_columns = page.select_one(".results-table-row").select("td:not(.extra)")
|
||||
assert_that(row_columns).is_length(3)
|
||||
|
||||
@pytest.mark.parametrize("no_capture", ["", "-s"])
|
||||
|
|
Loading…
Reference in New Issue