pytest-html-plus 1.2.0__tar.gz → 1.2.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {pytest_html_plus-1.2.0 → pytest_html_plus-1.2.1}/PKG-INFO +1 -1
- {pytest_html_plus-1.2.0 → pytest_html_plus-1.2.1}/pyproject.toml +6 -8
- {pytest_html_plus-1.2.0 → pytest_html_plus-1.2.1}/pytest_html_plus/generate_html_report.py +27 -18
- {pytest_html_plus-1.2.0 → pytest_html_plus-1.2.1}/pytest_html_plus/plugin.py +2 -4
- {pytest_html_plus-1.2.0 → pytest_html_plus-1.2.1}/LICENSE +0 -0
- {pytest_html_plus-1.2.0 → pytest_html_plus-1.2.1}/README.md +0 -0
- {pytest_html_plus-1.2.0 → pytest_html_plus-1.2.1}/pytest_html_plus/__init__.py +0 -0
- {pytest_html_plus-1.2.0 → pytest_html_plus-1.2.1}/pytest_html_plus/compute_filter_counts.py +0 -0
- {pytest_html_plus-1.2.0 → pytest_html_plus-1.2.1}/pytest_html_plus/compute_report_metadata.py +0 -0
- {pytest_html_plus-1.2.0 → pytest_html_plus-1.2.1}/pytest_html_plus/extract_link.py +0 -0
- {pytest_html_plus-1.2.0 → pytest_html_plus-1.2.1}/pytest_html_plus/json_merge.py +0 -0
- {pytest_html_plus-1.2.0 → pytest_html_plus-1.2.1}/pytest_html_plus/json_to_xml_converter.py +0 -0
- {pytest_html_plus-1.2.0 → pytest_html_plus-1.2.1}/pytest_html_plus/resolver_driver.py +0 -0
- {pytest_html_plus-1.2.0 → pytest_html_plus-1.2.1}/pytest_html_plus/send_email_report.py +0 -0
- {pytest_html_plus-1.2.0 → pytest_html_plus-1.2.1}/pytest_html_plus/utils.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: pytest-html-plus
|
|
3
|
-
Version: 1.2.
|
|
3
|
+
Version: 1.2.1
|
|
4
4
|
Summary: Generate Actionable, automatic screenshots, unified Mobile friendly Pytest HTML report in less than 3 seconds — no hooks, merge plugins, no config, xdist-ready.
|
|
5
5
|
License: MIT
|
|
6
6
|
License-File: LICENSE
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[tool.poetry]
|
|
2
2
|
name = "pytest-html-plus"
|
|
3
|
-
version = "1.2.
|
|
3
|
+
version = "1.2.1"
|
|
4
4
|
description = "Generate Actionable, automatic screenshots, unified Mobile friendly Pytest HTML report in less than 3 seconds — no hooks, merge plugins, no config, xdist-ready."
|
|
5
5
|
readme = "README.md"
|
|
6
6
|
authors = ["reporterplus"]
|
|
@@ -78,13 +78,7 @@ html-output = "report_output_warnings"
|
|
|
78
78
|
[tool.ruff]
|
|
79
79
|
line-length = 88
|
|
80
80
|
target-version = "py39"
|
|
81
|
-
ignore = [
|
|
82
|
-
"E501", # line too long — let black handle
|
|
83
|
-
"W291", # trailing whitespace — let black handle
|
|
84
|
-
"W293", # blank line whitespace — let black handle
|
|
85
|
-
]
|
|
86
81
|
exclude = [
|
|
87
|
-
"pytest_html_plus/generate_html_report.py",
|
|
88
82
|
".git"
|
|
89
83
|
]
|
|
90
84
|
|
|
@@ -96,4 +90,8 @@ select = [
|
|
|
96
90
|
"I", # isort
|
|
97
91
|
"UP", # pyupgrade
|
|
98
92
|
]
|
|
99
|
-
ignore = [
|
|
93
|
+
ignore = [
|
|
94
|
+
"E501", # line too long — let black handle
|
|
95
|
+
"W291", # trailing whitespace — let black handle
|
|
96
|
+
"W293", # blank line whitespace — let black handle
|
|
97
|
+
]
|
|
@@ -5,7 +5,9 @@ import os
|
|
|
5
5
|
import shutil
|
|
6
6
|
from datetime import datetime, timezone
|
|
7
7
|
from html import escape
|
|
8
|
+
|
|
8
9
|
from pytest_html_plus.compute_filter_counts import compute_filter_count
|
|
10
|
+
from pytest_html_plus.resolver_driver import sanitize_filename
|
|
9
11
|
from pytest_html_plus.utils import extract_error_block, extract_trace_block
|
|
10
12
|
|
|
11
13
|
|
|
@@ -792,7 +794,14 @@ class JSONReporter:
|
|
|
792
794
|
else "error" if test["status"] == "error" else "skipped"
|
|
793
795
|
)
|
|
794
796
|
)
|
|
795
|
-
|
|
797
|
+
# NOTE: Parammetrized test name may contains unsupport filesystem-safe chars
|
|
798
|
+
# Use test_name will not match the screenshot.
|
|
799
|
+
# 1. use test["screenshot"] which is the the screenshot path will lost the wild pattern
|
|
800
|
+
# *2. use sanitize_filename which replace non-alphanumeric will match the screenshot filename pattern
|
|
801
|
+
# 3. try to split parametrized will be hard
|
|
802
|
+
screenshot_path = self.find_screenshot_and_copy(
|
|
803
|
+
sanitize_filename(test["test"])
|
|
804
|
+
)
|
|
796
805
|
screenshot_html = (
|
|
797
806
|
f'<div class="details-screenshot"><img src="{screenshot_path}" alt="Screenshot" onclick="toggleFullscreen(this)"></div>'
|
|
798
807
|
if screenshot_path
|
|
@@ -847,7 +856,7 @@ class JSONReporter:
|
|
|
847
856
|
|
|
848
857
|
error_block = (
|
|
849
858
|
f'<div class="error-content"><strong>Error:</strong> '
|
|
850
|
-
f
|
|
859
|
+
f"{self.generate_copy_button(error, 'error')}"
|
|
851
860
|
f"<pre>{error}</pre></div>"
|
|
852
861
|
if error
|
|
853
862
|
else ""
|
|
@@ -855,7 +864,7 @@ class JSONReporter:
|
|
|
855
864
|
|
|
856
865
|
trace_block = (
|
|
857
866
|
f'<div class="trace-content"><strong>Trace:</strong> '
|
|
858
|
-
f
|
|
867
|
+
f"{self.generate_copy_button(trace, 'trace')}"
|
|
859
868
|
f"<pre>{trace}</pre></div>"
|
|
860
869
|
if trace
|
|
861
870
|
else ""
|
|
@@ -874,7 +883,7 @@ class JSONReporter:
|
|
|
874
883
|
"""
|
|
875
884
|
|
|
876
885
|
attempts_html += "</div>"
|
|
877
|
-
|
|
886
|
+
|
|
878
887
|
search_error = ""
|
|
879
888
|
|
|
880
889
|
if test.get("error"):
|
|
@@ -895,10 +904,8 @@ class JSONReporter:
|
|
|
895
904
|
<pre>{error_content}</pre></div>
|
|
896
905
|
"""
|
|
897
906
|
search_error = (
|
|
898
|
-
error_content.replace("\n", " ")
|
|
899
|
-
.replace("\r", " ")
|
|
907
|
+
error_content.replace("\n", " ").replace("\r", " ")
|
|
900
908
|
)[:1000]
|
|
901
|
-
|
|
902
909
|
|
|
903
910
|
flaky_badge = ""
|
|
904
911
|
if test.get("flaky"):
|
|
@@ -935,17 +942,18 @@ class JSONReporter:
|
|
|
935
942
|
'<span style="display:inline-block; min-width:45px;"></span>'
|
|
936
943
|
)
|
|
937
944
|
|
|
945
|
+
escaped_test_name = escape(test["test"])
|
|
938
946
|
html += f"""
|
|
939
|
-
<div class="test test-card" data-name="{
|
|
947
|
+
<div class="test test-card" data-name="{escaped_test_name}" data-link="{",".join(test.get("links") or [])}" data-markers="{marker_str}" data-error="{escape(search_error)}">
|
|
940
948
|
<div class="header {status_class}" onclick="toggleDetails(this)">
|
|
941
949
|
<div class="header-section test-info">
|
|
942
950
|
<span class="toggle"></span>
|
|
943
|
-
<strong>{
|
|
951
|
+
<strong>{escaped_test_name}</strong>
|
|
944
952
|
<span>— {test["status"].upper()}</span>
|
|
945
953
|
</div>
|
|
946
954
|
<div class="header-section meta">
|
|
947
955
|
<span class="nodeid-badge" style="display: flex; align-items: center; gap: 6px;">
|
|
948
|
-
<code style="font-size: 0.6em; color: #555;">{test["nodeid"]}</code>
|
|
956
|
+
<code style="font-size: 0.6em; color: #555;">{escape(test["nodeid"], quote=True)}</code>
|
|
949
957
|
{self.generate_copy_button(test["nodeid"], "nodeid")}
|
|
950
958
|
</span>
|
|
951
959
|
<span class="worker-id" style="background: #ddd; border-radius: 3px; padding: 2px 5px; font-size: 0.85em; font-weight: bold;">{test["worker"]}</span>
|
|
@@ -990,20 +998,21 @@ class JSONReporter:
|
|
|
990
998
|
"#e6f4ea" if failed_tests == 0 and error_tests == 0 else "#fdecea"
|
|
991
999
|
};
|
|
992
1000
|
border: 1px solid {
|
|
993
|
-
"#2f7a33" if failed_tests == 0 and
|
|
994
|
-
error_tests == 0
|
|
995
|
-
else "#a83232"
|
|
1001
|
+
"#2f7a33" if failed_tests == 0 and error_tests == 0 else "#a83232"
|
|
996
1002
|
};
|
|
997
1003
|
border-radius: 5px; margin-bottom: 1rem;">
|
|
998
1004
|
{
|
|
999
1005
|
"<strong>Bingo!</strong> All your tests passed!"
|
|
1000
1006
|
if failed_tests == 0 and error_tests == 0
|
|
1001
|
-
else (
|
|
1002
|
-
|
|
1003
|
-
|
|
1007
|
+
else (
|
|
1008
|
+
f"Total tests: {total_tests}, "
|
|
1009
|
+
f"Failures: {failed_tests}, "
|
|
1010
|
+
f"Errors: {error_tests}."
|
|
1011
|
+
)
|
|
1004
1012
|
}
|
|
1005
|
-
The slowest test was <strong>{
|
|
1006
|
-
|
|
1013
|
+
The slowest test was <strong>{
|
|
1014
|
+
escape(slowest_test_name, quote=True)
|
|
1015
|
+
}</strong> at {slowest_test_duration:.2f}s.
|
|
1007
1016
|
</div>
|
|
1008
1017
|
"""
|
|
1009
1018
|
|
|
@@ -247,7 +247,6 @@ def pytest_runtest_makereport(item, call):
|
|
|
247
247
|
screenshot_path = take_screenshot_generic(screenshot_path, item, driver)
|
|
248
248
|
|
|
249
249
|
worker_id = os.getenv("PYTEST_XDIST_WORKER") or "main"
|
|
250
|
-
test_name = "".join(c if c.isalnum() else "_" for c in item.name)
|
|
251
250
|
|
|
252
251
|
status = report.outcome
|
|
253
252
|
if report.when in ("setup", "teardown") and report.failed:
|
|
@@ -256,14 +255,13 @@ def pytest_runtest_makereport(item, call):
|
|
|
256
255
|
output_policy = config.getoption(OUTPUT_OPTION)
|
|
257
256
|
is_expected_failure = report.skipped and hasattr(report, "wasxfail")
|
|
258
257
|
include_output = output_policy == "all" or (
|
|
259
|
-
output_policy == "failed-only"
|
|
260
|
-
and (report.failed or is_expected_failure)
|
|
258
|
+
output_policy == "failed-only" and (report.failed or is_expected_failure)
|
|
261
259
|
)
|
|
262
260
|
stdout = getattr(report, "capstdout", "") if include_output else ""
|
|
263
261
|
stderr = getattr(report, "capstderr", "") if include_output else ""
|
|
264
262
|
|
|
265
263
|
reporter.log_result(
|
|
266
|
-
test_name=
|
|
264
|
+
test_name=item.name,
|
|
267
265
|
nodeid=item.nodeid,
|
|
268
266
|
status=status,
|
|
269
267
|
duration=report.duration,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{pytest_html_plus-1.2.0 → pytest_html_plus-1.2.1}/pytest_html_plus/compute_report_metadata.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|