Skip to content

Commit a88bf0d

Browse files
committed
Fix: Broken sorting for custom columns
1 parent 112c48f commit a88bf0d

File tree

5 files changed

+79
-13
lines changed

5 files changed

+79
-13
lines changed

src/pytest_html/basereport.py

Lines changed: 18 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -193,35 +193,33 @@ def pytest_runtest_logreport(self, report):
193193
)
194194

195195
outcome = _process_outcome(report)
196-
data = {
197-
"result": outcome,
198-
"duration": _format_duration(report.duration),
199-
}
196+
duration = _format_duration(report.duration)
200197
self._report.total_duration += report.duration
201198

202199
test_id = report.nodeid
203200
if report.when != "call":
204201
test_id += f"::{report.when}"
205-
data["testId"] = test_id
206202

207-
data["extras"] = self._process_extras(report, test_id)
203+
data = {
204+
"extras": self._process_extras(report, test_id),
205+
}
208206
links = [
209207
extra
210208
for extra in data["extras"]
211209
if extra["format_type"] in ["json", "text", "url"]
212210
]
213211
cells = [
214-
f'<td class="col-result">{data["result"]}</td>',
215-
f'<td class="col-name">{data["testId"]}</td>',
216-
f'<td class="col-duration">{data["duration"]}</td>',
212+
f'<td class="col-result">{outcome}</td>',
213+
f'<td class="col-testId">{test_id}</td>',
214+
f'<td class="col-duration">{duration}</td>',
217215
f'<td class="col-links">{_process_links(links)}</td>',
218216
]
219-
220217
self._config.hook.pytest_html_results_table_row(report=report, cells=cells)
221218
if not cells:
222219
return
223220

224221
cells = _fix_py(cells)
222+
_hydrate_data(data, cells)
225223
data["resultsTableRow"] = cells
226224

227225
# don't count passed setups and teardowns
@@ -237,6 +235,16 @@ def pytest_runtest_logreport(self, report):
237235
self._generate_report()
238236

239237

238+
def _hydrate_data(data, cells):
239+
for cell in cells:
240+
# extract column name and data
241+
if "col-links" not in cell:
242+
name_match = re.search(r"col-(\w+)", cell)
243+
data_match = re.search(r"<td.*?>(.*?)</td>", cell)
244+
if name_match and data_match:
245+
data[name_match.group(1)] = data_match.group(1)
246+
247+
240248
def _format_duration(duration):
241249
if duration < 1:
242250
return "{} ms".format(round(duration * 1000))

src/pytest_html/report_data.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,6 @@ def __init__(self, config):
4141
self._data = {
4242
"environment": {},
4343
"tests": defaultdict(list),
44-
"resultsTableRow": None,
4544
}
4645

4746
collapsed = config.getini("render_collapsed")

src/pytest_html/scripts/dom.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ const dom = {
3636

3737
return envRow
3838
},
39-
getResultTBody: ({ testId, id, log, duration, extras, resultsTableRow, tableHtml, result, collapsed }) => {
39+
getResultTBody: ({ testId, id, log, extras, resultsTableRow, tableHtml, result, collapsed }) => {
4040
const resultBody = templateResult.content.cloneNode(true)
4141
resultBody.querySelector('tbody').classList.add(result.toLowerCase())
4242
resultBody.querySelector('tbody').id = testId

testing/test_e2e.py

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,23 @@ def _encode_query_params(params):
5454
return urllib.parse.urlencode(params)
5555

5656

57+
def _parse_result_table(driver):
58+
table = driver.find_element(By.ID, "results-table")
59+
headers = table.find_elements(By.CSS_SELECTOR, "thead th")
60+
rows = table.find_elements(By.CSS_SELECTOR, "tbody tr.collapsible")
61+
table_data = []
62+
for row in rows:
63+
data_dict = {}
64+
65+
cells = row.find_elements(By.TAG_NAME, "td")
66+
for header, cell in zip(headers, cells):
67+
data_dict[header.text.lower()] = cell.text
68+
69+
table_data.append(data_dict)
70+
71+
return table_data
72+
73+
5774
def test_visible(pytester, path, driver):
5875
pytester.makepyfile(
5976
"""
@@ -76,3 +93,45 @@ def test_pass_two(): pass
7693
)
7794
result = driver.find_elements(By.CSS_SELECTOR, "tr.collapsible")
7895
assert_that(result).is_length(0)
96+
97+
98+
def test_custom_sorting(pytester, path, driver):
99+
pytester.makeconftest(
100+
"""
101+
def pytest_html_results_table_header(cells):
102+
cells.append(
103+
'<th class="sortable alpha" data-column-type="alpha">Alpha</th>'
104+
)
105+
106+
def pytest_html_results_table_row(report, cells):
107+
data = report.nodeid.split("_")[-1]
108+
cells.append(f'<td class="col-alpha">{data}</td>')
109+
"""
110+
)
111+
pytester.makepyfile(
112+
"""
113+
def test_AAA(): pass
114+
def test_BBB(): pass
115+
"""
116+
)
117+
query_params = _encode_query_params({"sort": "alpha"})
118+
driver.get(f"file:///reports{path()}?{query_params}")
119+
WebDriverWait(driver, 5).until(
120+
ec.visibility_of_all_elements_located((By.CSS_SELECTOR, "#results-table"))
121+
)
122+
123+
rows = _parse_result_table(driver)
124+
assert_that(rows).is_length(2)
125+
assert_that(rows[0]["test"]).contains("AAA")
126+
assert_that(rows[0]["alpha"]).is_equal_to("AAA")
127+
assert_that(rows[1]["test"]).contains("BBB")
128+
assert_that(rows[1]["alpha"]).is_equal_to("BBB")
129+
130+
driver.find_element(By.CSS_SELECTOR, "th[data-column-type='alpha']").click()
131+
# we might need some wait here to ensure sorting happened
132+
rows = _parse_result_table(driver)
133+
assert_that(rows).is_length(2)
134+
assert_that(rows[0]["test"]).contains("BBB")
135+
assert_that(rows[0]["alpha"]).is_equal_to("BBB")
136+
assert_that(rows[1]["test"]).contains("AAA")
137+
assert_that(rows[1]["alpha"]).is_equal_to("AAA")

testing/test_integration.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -358,7 +358,7 @@ def test_function(arg):
358358
page = run(pytester)
359359
assert_results(page, error=1, total_tests=0)
360360

361-
col_name = get_text(page, "td[class='col-name']")
361+
col_name = get_text(page, "td[class='col-testId']")
362362
assert_that(col_name).contains("::setup")
363363
assert_that(get_log(page)).contains("ValueError")
364364

0 commit comments

Comments
 (0)