Skip to content

Commit c8416de

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

File tree

5 files changed

+78
-13
lines changed

5 files changed

+78
-13
lines changed

src/pytest_html/basereport.py

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,15 @@ def _run_count(self):
149149

150150
return f"{counts}/{self._report.collected_items} {'tests' if plural else 'test'} done."
151151

152+
def _hydrate_data(self, data, cells):
153+
for index, cell in enumerate(cells):
154+
# extract column name and data if column is sortable
155+
if "sortable" in self._report.table_header[index]:
156+
name_match = re.search(r"col-(\w+)", cell)
157+
data_match = re.search(r"<td.*?>(.*?)</td>", cell)
158+
if name_match and data_match:
159+
data[name_match.group(1)] = data_match.group(1)
160+
152161
@pytest.hookimpl(trylast=True)
153162
def pytest_sessionstart(self, session):
154163
self._report.set_data("environment", self._generate_environment())
@@ -193,35 +202,33 @@ def pytest_runtest_logreport(self, report):
193202
)
194203

195204
outcome = _process_outcome(report)
196-
data = {
197-
"result": outcome,
198-
"duration": _format_duration(report.duration),
199-
}
205+
duration = _format_duration(report.duration)
200206
self._report.total_duration += report.duration
201207

202208
test_id = report.nodeid
203209
if report.when != "call":
204210
test_id += f"::{report.when}"
205-
data["testId"] = test_id
206211

207-
data["extras"] = self._process_extras(report, test_id)
212+
data = {
213+
"extras": self._process_extras(report, test_id),
214+
}
208215
links = [
209216
extra
210217
for extra in data["extras"]
211218
if extra["format_type"] in ["json", "text", "url"]
212219
]
213220
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>',
221+
f'<td class="col-result">{outcome}</td>',
222+
f'<td class="col-testId">{test_id}</td>',
223+
f'<td class="col-duration">{duration}</td>',
217224
f'<td class="col-links">{_process_links(links)}</td>',
218225
]
219-
220226
self._config.hook.pytest_html_results_table_row(report=report, cells=cells)
221227
if not cells:
222228
return
223229

224230
cells = _fix_py(cells)
231+
self._hydrate_data(data, cells)
225232
data["resultsTableRow"] = cells
226233

227234
# don't count passed setups and teardowns

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)