pytest-html-plus 1.2.0__tar.gz → 1.3.0__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.3.0/PKG-INFO +133 -0
- pytest_html_plus-1.3.0/README.md +98 -0
- {pytest_html_plus-1.2.0 → pytest_html_plus-1.3.0}/pyproject.toml +6 -8
- {pytest_html_plus-1.2.0 → pytest_html_plus-1.3.0}/pytest_html_plus/generate_html_report.py +112 -18
- {pytest_html_plus-1.2.0 → pytest_html_plus-1.3.0}/pytest_html_plus/plugin.py +2 -4
- pytest_html_plus-1.2.0/PKG-INFO +0 -219
- pytest_html_plus-1.2.0/README.md +0 -185
- {pytest_html_plus-1.2.0 → pytest_html_plus-1.3.0}/LICENSE +0 -0
- {pytest_html_plus-1.2.0 → pytest_html_plus-1.3.0}/pytest_html_plus/__init__.py +0 -0
- {pytest_html_plus-1.2.0 → pytest_html_plus-1.3.0}/pytest_html_plus/compute_filter_counts.py +0 -0
- {pytest_html_plus-1.2.0 → pytest_html_plus-1.3.0}/pytest_html_plus/compute_report_metadata.py +0 -0
- {pytest_html_plus-1.2.0 → pytest_html_plus-1.3.0}/pytest_html_plus/extract_link.py +0 -0
- {pytest_html_plus-1.2.0 → pytest_html_plus-1.3.0}/pytest_html_plus/json_merge.py +0 -0
- {pytest_html_plus-1.2.0 → pytest_html_plus-1.3.0}/pytest_html_plus/json_to_xml_converter.py +0 -0
- {pytest_html_plus-1.2.0 → pytest_html_plus-1.3.0}/pytest_html_plus/resolver_driver.py +0 -0
- {pytest_html_plus-1.2.0 → pytest_html_plus-1.3.0}/pytest_html_plus/send_email_report.py +0 -0
- {pytest_html_plus-1.2.0 → pytest_html_plus-1.3.0}/pytest_html_plus/utils.py +0 -0
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: pytest-html-plus
|
|
3
|
+
Version: 1.3.0
|
|
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
|
+
License: MIT
|
|
6
|
+
License-File: LICENSE
|
|
7
|
+
Keywords: pytest,pytest-plugin,html-report,test-report,screenshot,mobile-report,xdist,allure-alternative,playwright,selenium
|
|
8
|
+
Author: reporterplus
|
|
9
|
+
Maintainer: reporterplus
|
|
10
|
+
Requires-Python: >=3.10,<4.0
|
|
11
|
+
Classifier: Development Status :: 5 - Production/Stable
|
|
12
|
+
Classifier: Framework :: Pytest
|
|
13
|
+
Classifier: Intended Audience :: Developers
|
|
14
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
15
|
+
Classifier: Operating System :: OS Independent
|
|
16
|
+
Classifier: Programming Language :: Python :: 3
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
22
|
+
Classifier: Programming Language :: Python :: 3.15
|
|
23
|
+
Classifier: Topic :: Software Development :: Quality Assurance
|
|
24
|
+
Classifier: Topic :: Software Development :: Testing
|
|
25
|
+
Requires-Dist: keyring (>=25.6.0,<26.0.0)
|
|
26
|
+
Requires-Dist: tomli (>=2.0.1,<3.0.0) ; python_version < "3.11"
|
|
27
|
+
Requires-Dist: yagmail (>=0.15.293,<0.16.0)
|
|
28
|
+
Project-URL: Changelog, https://github.com/reporterplus/pytest-html-plus/blob/main/CHANGELOG.md
|
|
29
|
+
Project-URL: Documentation, https://pytest-html-plus.readthedocs.io
|
|
30
|
+
Project-URL: Homepage, https://github.com/reporterplus/pytest-html-plus
|
|
31
|
+
Project-URL: Source, https://github.com/reporterplus/pytest-html-plus
|
|
32
|
+
Project-URL: Tracker, https://github.com/reporterplus/pytest-html-plus/issues
|
|
33
|
+
Description-Content-Type: text/markdown
|
|
34
|
+
|
|
35
|
+
⚡ **Test your code, not your reporting setup.**
|
|
36
|
+
|
|
37
|
+
> A pytest report built for fast debugging, with parallel execution support, automatic screenshots, and shareable failure context.
|
|
38
|
+
|
|
39
|
+
`pytest-html-plus` turns pytest results into portable debugging artifacts for CI, collaboration, and integrations, without a reporting platform.
|
|
40
|
+
|
|
41
|
+
➡️ [View Demo Report](https://reporterplus.github.io/pytest-html-plus/)
|
|
42
|
+
|
|
43
|
+
[](https://pytest-html-plus.readthedocs.io/en/main/) [](https://pypistats.org/packages/pytest-html-plus)    [](https://github.com/reporterplus/pytest-html-plus/actions/workflows/unit-test.yml) [](https://codecov.io/gh/reporterplus/pytest-html-plus) [](https://github.com/marketplace/actions/pytest-html-plus-action) [](https://marketplace.visualstudio.com/items?itemName=reporterplus.pytest-html-plus-vscode)
|
|
44
|
+
|
|
45
|
+
---
|
|
46
|
+
|
|
47
|
+
## 🚀 Quick Start
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
pip install pytest-html-plus
|
|
51
|
+
# or
|
|
52
|
+
poetry add pytest-html-plus
|
|
53
|
+
|
|
54
|
+
pytest
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
By default, that generates a portable HTML report and structured JSON output. No hooks, decorators, or reporting server are required.
|
|
58
|
+
|
|
59
|
+
## Why pytest-html-plus?
|
|
60
|
+
|
|
61
|
+
- ⚡ Produce one unified report with or without `pytest-xdist`.
|
|
62
|
+
- 📸 Capture failure screenshots automatically for Selenium and Playwright tests.
|
|
63
|
+
- 📋 Keep errors, traces, logs, stdout, and stderr together in one report.
|
|
64
|
+
- 🔄 Understand flaky tests with complete retry history.
|
|
65
|
+
- 🔗 Share a direct link to an individual test result.
|
|
66
|
+
- 🔍 Find tests, failures, traces, issue references, and documentation links from the same report.
|
|
67
|
+
|
|
68
|
+
## ✨ Features
|
|
69
|
+
|
|
70
|
+
#### ⚡ One Unified Report with xdist
|
|
71
|
+
|
|
72
|
+
Run tests in parallel and receive one merged HTML and JSON report without an additional merge plugin or post-processing step.
|
|
73
|
+
|
|
74
|
+
#### 📸 See What Failed Automatically
|
|
75
|
+
|
|
76
|
+
Capture Selenium and Playwright screenshots automatically and view them alongside the relevant failure context, with no custom hooks or decorators required.
|
|
77
|
+
|
|
78
|
+
#### 📋 Everything You Need to Investigate a Failure
|
|
79
|
+
|
|
80
|
+
Review errors, traces, logs, stdout, stderr, and screenshots together. Copy the context you need in one click and use `--plus-output=failed-only` to keep passing-test output compact.
|
|
81
|
+
|
|
82
|
+

|
|
83
|
+
|
|
84
|
+

|
|
85
|
+
|
|
86
|
+
#### 🔄 Understand Flaky Tests Across Every Retry
|
|
87
|
+
|
|
88
|
+
See how a test behaves across retries, from initial failure to recovery. Spot patterns such as cache issues, race conditions, and intermittent crashes without guesswork.
|
|
89
|
+
|
|
90
|
+

|
|
91
|
+
|
|
92
|
+
#### 🔗 Share Any Test with a Direct Link
|
|
93
|
+
|
|
94
|
+
Copy a direct link to any test result and share it with your team. The report opens at the linked test, reveals it, expands its details, and highlights it, so teammates can jump straight to the relevant context without searching through the report.
|
|
95
|
+
|
|
96
|
+
<img width="3024" height="1778" alt="ScreenRecording2026-10-03at8 55 26AM-ezgif com-cut" src="https://github.com/user-attachments/assets/0c44a38f-7898-4a4d-8241-4f1d1c57ccfb" />
|
|
97
|
+
|
|
98
|
+
#### 🔍 Find the Context You Need
|
|
99
|
+
|
|
100
|
+
Search tests, errors, traces, issue references, documentation links, and custom references from the same report.
|
|
101
|
+
|
|
102
|
+
<img width="800" height="421" alt="Universal test search" src="https://github.com/user-attachments/assets/54858747-ab16-4d4f-baa9-0d651a1d8bac" />
|
|
103
|
+
|
|
104
|
+
---
|
|
105
|
+
|
|
106
|
+
## Try It Without Changing Your Test Suite
|
|
107
|
+
|
|
108
|
+
`pytest-html-plus` works alongside existing pytest tooling, so you can evaluate it with your current test suite without adopting a reporting server, rewriting tests, or maintaining reporting infrastructure.
|
|
109
|
+
|
|
110
|
+
## More Built In
|
|
111
|
+
|
|
112
|
+
Also includes merged JUnit XML export, run metadata, slow-test visibility, reusable profiles, traceability helpers, email delivery, dynamic markers, and configurable output capture.
|
|
113
|
+
|
|
114
|
+
**[See all features and configuration options →](https://pytest-html-plus.readthedocs.io/en/main/)**
|
|
115
|
+
|
|
116
|
+
## Project Status
|
|
117
|
+
|
|
118
|
+
pytest-html-plus is stable and actively maintained, with its core reporting experience now well established. Future development will focus on compatibility, reliability, and carefully selected improvements that strengthen the core reporting experience.
|
|
119
|
+
|
|
120
|
+
We're also looking for co-maintainers to help review pull requests, triage issues, and keep the project healthy across future Python and pytest releases.
|
|
121
|
+
|
|
122
|
+
If you're interested in becoming a long-term contributor, we'd love to hear from you. Please open an issue or start a discussion.
|
|
123
|
+
|
|
124
|
+
## Contributing
|
|
125
|
+
|
|
126
|
+
We welcome pull requests, issues, and feature suggestions from the community.
|
|
127
|
+
|
|
128
|
+
See the [contribution guide](CONTRIBUTING.md) for setup instructions.
|
|
129
|
+
|
|
130
|
+
## 📜 License
|
|
131
|
+
|
|
132
|
+
MIT
|
|
133
|
+
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
⚡ **Test your code, not your reporting setup.**
|
|
2
|
+
|
|
3
|
+
> A pytest report built for fast debugging, with parallel execution support, automatic screenshots, and shareable failure context.
|
|
4
|
+
|
|
5
|
+
`pytest-html-plus` turns pytest results into portable debugging artifacts for CI, collaboration, and integrations, without a reporting platform.
|
|
6
|
+
|
|
7
|
+
➡️ [View Demo Report](https://reporterplus.github.io/pytest-html-plus/)
|
|
8
|
+
|
|
9
|
+
[](https://pytest-html-plus.readthedocs.io/en/main/) [](https://pypistats.org/packages/pytest-html-plus)    [](https://github.com/reporterplus/pytest-html-plus/actions/workflows/unit-test.yml) [](https://codecov.io/gh/reporterplus/pytest-html-plus) [](https://github.com/marketplace/actions/pytest-html-plus-action) [](https://marketplace.visualstudio.com/items?itemName=reporterplus.pytest-html-plus-vscode)
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
## 🚀 Quick Start
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
pip install pytest-html-plus
|
|
17
|
+
# or
|
|
18
|
+
poetry add pytest-html-plus
|
|
19
|
+
|
|
20
|
+
pytest
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
By default, that generates a portable HTML report and structured JSON output. No hooks, decorators, or reporting server are required.
|
|
24
|
+
|
|
25
|
+
## Why pytest-html-plus?
|
|
26
|
+
|
|
27
|
+
- ⚡ Produce one unified report with or without `pytest-xdist`.
|
|
28
|
+
- 📸 Capture failure screenshots automatically for Selenium and Playwright tests.
|
|
29
|
+
- 📋 Keep errors, traces, logs, stdout, and stderr together in one report.
|
|
30
|
+
- 🔄 Understand flaky tests with complete retry history.
|
|
31
|
+
- 🔗 Share a direct link to an individual test result.
|
|
32
|
+
- 🔍 Find tests, failures, traces, issue references, and documentation links from the same report.
|
|
33
|
+
|
|
34
|
+
## ✨ Features
|
|
35
|
+
|
|
36
|
+
#### ⚡ One Unified Report with xdist
|
|
37
|
+
|
|
38
|
+
Run tests in parallel and receive one merged HTML and JSON report without an additional merge plugin or post-processing step.
|
|
39
|
+
|
|
40
|
+
#### 📸 See What Failed Automatically
|
|
41
|
+
|
|
42
|
+
Capture Selenium and Playwright screenshots automatically and view them alongside the relevant failure context, with no custom hooks or decorators required.
|
|
43
|
+
|
|
44
|
+
#### 📋 Everything You Need to Investigate a Failure
|
|
45
|
+
|
|
46
|
+
Review errors, traces, logs, stdout, stderr, and screenshots together. Copy the context you need in one click and use `--plus-output=failed-only` to keep passing-test output compact.
|
|
47
|
+
|
|
48
|
+

|
|
49
|
+
|
|
50
|
+

|
|
51
|
+
|
|
52
|
+
#### 🔄 Understand Flaky Tests Across Every Retry
|
|
53
|
+
|
|
54
|
+
See how a test behaves across retries, from initial failure to recovery. Spot patterns such as cache issues, race conditions, and intermittent crashes without guesswork.
|
|
55
|
+
|
|
56
|
+

|
|
57
|
+
|
|
58
|
+
#### 🔗 Share Any Test with a Direct Link
|
|
59
|
+
|
|
60
|
+
Copy a direct link to any test result and share it with your team. The report opens at the linked test, reveals it, expands its details, and highlights it, so teammates can jump straight to the relevant context without searching through the report.
|
|
61
|
+
|
|
62
|
+
<img width="3024" height="1778" alt="ScreenRecording2026-10-03at8 55 26AM-ezgif com-cut" src="https://github.com/user-attachments/assets/0c44a38f-7898-4a4d-8241-4f1d1c57ccfb" />
|
|
63
|
+
|
|
64
|
+
#### 🔍 Find the Context You Need
|
|
65
|
+
|
|
66
|
+
Search tests, errors, traces, issue references, documentation links, and custom references from the same report.
|
|
67
|
+
|
|
68
|
+
<img width="800" height="421" alt="Universal test search" src="https://github.com/user-attachments/assets/54858747-ab16-4d4f-baa9-0d651a1d8bac" />
|
|
69
|
+
|
|
70
|
+
---
|
|
71
|
+
|
|
72
|
+
## Try It Without Changing Your Test Suite
|
|
73
|
+
|
|
74
|
+
`pytest-html-plus` works alongside existing pytest tooling, so you can evaluate it with your current test suite without adopting a reporting server, rewriting tests, or maintaining reporting infrastructure.
|
|
75
|
+
|
|
76
|
+
## More Built In
|
|
77
|
+
|
|
78
|
+
Also includes merged JUnit XML export, run metadata, slow-test visibility, reusable profiles, traceability helpers, email delivery, dynamic markers, and configurable output capture.
|
|
79
|
+
|
|
80
|
+
**[See all features and configuration options →](https://pytest-html-plus.readthedocs.io/en/main/)**
|
|
81
|
+
|
|
82
|
+
## Project Status
|
|
83
|
+
|
|
84
|
+
pytest-html-plus is stable and actively maintained, with its core reporting experience now well established. Future development will focus on compatibility, reliability, and carefully selected improvements that strengthen the core reporting experience.
|
|
85
|
+
|
|
86
|
+
We're also looking for co-maintainers to help review pull requests, triage issues, and keep the project healthy across future Python and pytest releases.
|
|
87
|
+
|
|
88
|
+
If you're interested in becoming a long-term contributor, we'd love to hear from you. Please open an issue or start a discussion.
|
|
89
|
+
|
|
90
|
+
## Contributing
|
|
91
|
+
|
|
92
|
+
We welcome pull requests, issues, and feature suggestions from the community.
|
|
93
|
+
|
|
94
|
+
See the [contribution guide](CONTRIBUTING.md) for setup instructions.
|
|
95
|
+
|
|
96
|
+
## 📜 License
|
|
97
|
+
|
|
98
|
+
MIT
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[tool.poetry]
|
|
2
2
|
name = "pytest-html-plus"
|
|
3
|
-
version = "1.
|
|
3
|
+
version = "1.3.0"
|
|
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
|
+
]
|
|
@@ -1,14 +1,23 @@
|
|
|
1
1
|
import argparse
|
|
2
2
|
import base64
|
|
3
|
+
import hashlib
|
|
3
4
|
import json
|
|
4
5
|
import os
|
|
5
6
|
import shutil
|
|
6
7
|
from datetime import datetime, timezone
|
|
7
8
|
from html import escape
|
|
9
|
+
|
|
8
10
|
from pytest_html_plus.compute_filter_counts import compute_filter_count
|
|
11
|
+
from pytest_html_plus.resolver_driver import sanitize_filename
|
|
9
12
|
from pytest_html_plus.utils import extract_error_block, extract_trace_block
|
|
10
13
|
|
|
11
14
|
|
|
15
|
+
def stable_test_anchor(nodeid):
|
|
16
|
+
"""Return a deterministic, URL-safe HTML anchor for a pytest nodeid."""
|
|
17
|
+
digest = hashlib.sha256(str(nodeid).encode("utf-8")).hexdigest()[:32]
|
|
18
|
+
return f"test-{digest}"
|
|
19
|
+
|
|
20
|
+
|
|
12
21
|
def main():
|
|
13
22
|
parser = argparse.ArgumentParser(
|
|
14
23
|
description="Generate HTML report from Playwright JSON report"
|
|
@@ -342,6 +351,13 @@ class JSONReporter:
|
|
|
342
351
|
|
|
343
352
|
.inline-copy-btn {{ cursor: pointer; background: none; border: 1px solid #ddd; border-radius: 3px; padding: 2px 4px; font-size: 0.8em; margin-left: 8px; color: #666; transition: all 0.2s ease; line-height: 1; }}
|
|
344
353
|
.inline-copy-btn:hover {{ border-color: #999; background: #f5f5f5; color: #333; }}
|
|
354
|
+
.test:target, .test.deep-link-target {{
|
|
355
|
+
outline: 2px solid rgba(160, 130, 90, 0.4);
|
|
356
|
+
outline-offset: 1px;
|
|
357
|
+
box-shadow: 0 2px 8px rgba(80, 65, 45, 0.1);
|
|
358
|
+
}}
|
|
359
|
+
.test:focus-visible {{ outline: 2px solid #2563eb; outline-offset: 2px; }}
|
|
360
|
+
.test {{ scroll-margin-top: 1rem; }}
|
|
345
361
|
.error-content pre {{ background: #fef2f2; border-left: 4px solid #dc2626; padding: 12px; border-radius: 4px; color: #7f1d1d; margin: 8px 0; }}
|
|
346
362
|
.trace-content pre {{ background: #fef7ed; border-left: 4px solid #ea580c; padding: 12px; border-radius: 4px; color: #9a3412; margin: 8px 0; }}
|
|
347
363
|
.details-text div pre {{ background: #f8fafc; border: 1px solid #e2e8f0; padding: 12px; border-radius: 4px; margin: 8px 0; font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', monospace; font-size: 0.85em; line-height: 1.4; }}
|
|
@@ -416,6 +432,68 @@ class JSONReporter:
|
|
|
416
432
|
}}
|
|
417
433
|
}}
|
|
418
434
|
|
|
435
|
+
function copyTestLink(anchorId, button) {{
|
|
436
|
+
try {{
|
|
437
|
+
const url = new URL(window.location.href);
|
|
438
|
+
url.hash = anchorId;
|
|
439
|
+
const originalContent = button.innerHTML;
|
|
440
|
+
navigator.clipboard.writeText(url.href).then(() => {{
|
|
441
|
+
button.innerHTML = '<span style="color: #2f7a33;">✓</span>';
|
|
442
|
+
setTimeout(() => {{ button.innerHTML = originalContent; }}, 1000);
|
|
443
|
+
}}).catch(err => {{
|
|
444
|
+
console.error("Copy link failed:", err);
|
|
445
|
+
button.innerHTML = '<span style="color: #d32f2f;">✗</span>';
|
|
446
|
+
setTimeout(() => {{ button.innerHTML = originalContent; }}, 1000);
|
|
447
|
+
}});
|
|
448
|
+
}} catch (error) {{
|
|
449
|
+
console.error("Copy link error:", error);
|
|
450
|
+
}}
|
|
451
|
+
}}
|
|
452
|
+
|
|
453
|
+
function clearFiltersForDeepLink() {{
|
|
454
|
+
const filterIds = [
|
|
455
|
+
'failedOnlyCheckbox', 'errorOnlyCheckbox', 'skippedOnlyCheckbox',
|
|
456
|
+
'longestOnlyCheckbox', 'untrackedOnlyCheckbox', 'flakyOnlyCheckbox'
|
|
457
|
+
];
|
|
458
|
+
filterIds.forEach(id => {{
|
|
459
|
+
const checkbox = document.getElementById(id);
|
|
460
|
+
if (checkbox) checkbox.checked = false;
|
|
461
|
+
}});
|
|
462
|
+
document.querySelectorAll('.marker-filter input[type="checkbox"]')
|
|
463
|
+
.forEach(checkbox => checkbox.checked = false);
|
|
464
|
+
const searchInput = document.getElementById('universal-search');
|
|
465
|
+
if (searchInput) searchInput.value = '';
|
|
466
|
+
document.querySelectorAll('.test').forEach(test => test.style.display = 'block');
|
|
467
|
+
}}
|
|
468
|
+
|
|
469
|
+
function revealTestFromFragment() {{
|
|
470
|
+
if (!window.location.hash) return;
|
|
471
|
+
let anchorId;
|
|
472
|
+
try {{
|
|
473
|
+
anchorId = decodeURIComponent(window.location.hash.slice(1));
|
|
474
|
+
}} catch (error) {{
|
|
475
|
+
return;
|
|
476
|
+
}}
|
|
477
|
+
if (!anchorId.startsWith('test-')) return;
|
|
478
|
+
const testCard = document.getElementById(anchorId);
|
|
479
|
+
if (!testCard || !testCard.classList.contains('test')) return;
|
|
480
|
+
|
|
481
|
+
clearFiltersForDeepLink();
|
|
482
|
+
document.querySelectorAll('.test.deep-link-target')
|
|
483
|
+
.forEach(test => test.classList.remove('deep-link-target'));
|
|
484
|
+
testCard.classList.add('deep-link-target');
|
|
485
|
+
|
|
486
|
+
const header = testCard.querySelector('.header');
|
|
487
|
+
const details = testCard.querySelector('.details');
|
|
488
|
+
if (header && details) {{
|
|
489
|
+
header.classList.add('expanded');
|
|
490
|
+
details.style.display = 'block';
|
|
491
|
+
}}
|
|
492
|
+
|
|
493
|
+
testCard.scrollIntoView({{ behavior: 'smooth', block: 'center' }});
|
|
494
|
+
testCard.focus({{ preventScroll: true }});
|
|
495
|
+
}}
|
|
496
|
+
|
|
419
497
|
function toggleFullscreen(img) {{
|
|
420
498
|
const overlay = document.getElementById('fullscreen-overlay');
|
|
421
499
|
if (img.classList.contains('fullscreen')) {{
|
|
@@ -664,6 +742,8 @@ class JSONReporter:
|
|
|
664
742
|
flakyCheckbox.addEventListener('change', () => toggleFlakyOnly(flakyCheckbox));
|
|
665
743
|
const markerCheckboxes = document.querySelectorAll('.marker-filter input[type="checkbox"]');
|
|
666
744
|
markerCheckboxes.forEach(cb => cb.addEventListener('change', filterByMarkers));
|
|
745
|
+
revealTestFromFragment();
|
|
746
|
+
window.addEventListener('hashchange', revealTestFromFragment);
|
|
667
747
|
}};
|
|
668
748
|
</script>
|
|
669
749
|
</head>
|
|
@@ -792,7 +872,14 @@ class JSONReporter:
|
|
|
792
872
|
else "error" if test["status"] == "error" else "skipped"
|
|
793
873
|
)
|
|
794
874
|
)
|
|
795
|
-
|
|
875
|
+
# NOTE: Parammetrized test name may contains unsupport filesystem-safe chars
|
|
876
|
+
# Use test_name will not match the screenshot.
|
|
877
|
+
# 1. use test["screenshot"] which is the the screenshot path will lost the wild pattern
|
|
878
|
+
# *2. use sanitize_filename which replace non-alphanumeric will match the screenshot filename pattern
|
|
879
|
+
# 3. try to split parametrized will be hard
|
|
880
|
+
screenshot_path = self.find_screenshot_and_copy(
|
|
881
|
+
sanitize_filename(test["test"])
|
|
882
|
+
)
|
|
796
883
|
screenshot_html = (
|
|
797
884
|
f'<div class="details-screenshot"><img src="{screenshot_path}" alt="Screenshot" onclick="toggleFullscreen(this)"></div>'
|
|
798
885
|
if screenshot_path
|
|
@@ -847,7 +934,7 @@ class JSONReporter:
|
|
|
847
934
|
|
|
848
935
|
error_block = (
|
|
849
936
|
f'<div class="error-content"><strong>Error:</strong> '
|
|
850
|
-
f
|
|
937
|
+
f"{self.generate_copy_button(error, 'error')}"
|
|
851
938
|
f"<pre>{error}</pre></div>"
|
|
852
939
|
if error
|
|
853
940
|
else ""
|
|
@@ -855,7 +942,7 @@ class JSONReporter:
|
|
|
855
942
|
|
|
856
943
|
trace_block = (
|
|
857
944
|
f'<div class="trace-content"><strong>Trace:</strong> '
|
|
858
|
-
f
|
|
945
|
+
f"{self.generate_copy_button(trace, 'trace')}"
|
|
859
946
|
f"<pre>{trace}</pre></div>"
|
|
860
947
|
if trace
|
|
861
948
|
else ""
|
|
@@ -874,7 +961,7 @@ class JSONReporter:
|
|
|
874
961
|
"""
|
|
875
962
|
|
|
876
963
|
attempts_html += "</div>"
|
|
877
|
-
|
|
964
|
+
|
|
878
965
|
search_error = ""
|
|
879
966
|
|
|
880
967
|
if test.get("error"):
|
|
@@ -895,10 +982,8 @@ class JSONReporter:
|
|
|
895
982
|
<pre>{error_content}</pre></div>
|
|
896
983
|
"""
|
|
897
984
|
search_error = (
|
|
898
|
-
error_content.replace("\n", " ")
|
|
899
|
-
.replace("\r", " ")
|
|
985
|
+
error_content.replace("\n", " ").replace("\r", " ")
|
|
900
986
|
)[:1000]
|
|
901
|
-
|
|
902
987
|
|
|
903
988
|
flaky_badge = ""
|
|
904
989
|
if test.get("flaky"):
|
|
@@ -935,18 +1020,26 @@ class JSONReporter:
|
|
|
935
1020
|
'<span style="display:inline-block; min-width:45px;"></span>'
|
|
936
1021
|
)
|
|
937
1022
|
|
|
1023
|
+
escaped_test_name = escape(test["test"])
|
|
1024
|
+
test_anchor = stable_test_anchor(test["nodeid"])
|
|
938
1025
|
html += f"""
|
|
939
|
-
<div class="test test-card" data-
|
|
1026
|
+
<div id="{test_anchor}" class="test test-card" data-nodeid="{escape(test["nodeid"], quote=True)}" tabindex="-1" data-name="{escaped_test_name}" data-link="{",".join(test.get("links") or [])}" data-markers="{marker_str}" data-error="{escape(search_error)}">
|
|
940
1027
|
<div class="header {status_class}" onclick="toggleDetails(this)">
|
|
941
1028
|
<div class="header-section test-info">
|
|
942
1029
|
<span class="toggle"></span>
|
|
943
|
-
<strong>{
|
|
1030
|
+
<strong>{escaped_test_name}</strong>
|
|
944
1031
|
<span>— {test["status"].upper()}</span>
|
|
945
1032
|
</div>
|
|
946
1033
|
<div class="header-section meta">
|
|
947
1034
|
<span class="nodeid-badge" style="display: flex; align-items: center; gap: 6px;">
|
|
948
|
-
<code style="font-size: 0.6em; color: #555;">{test["nodeid"]}</code>
|
|
1035
|
+
<code style="font-size: 0.6em; color: #555;">{escape(test["nodeid"], quote=True)}</code>
|
|
949
1036
|
{self.generate_copy_button(test["nodeid"], "nodeid")}
|
|
1037
|
+
<button class="inline-copy-btn test-link-btn" onclick="event.stopPropagation(); copyTestLink('{test_anchor}', this)" title="Copy link to test">
|
|
1038
|
+
<svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
|
1039
|
+
<path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"></path>
|
|
1040
|
+
<path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"></path>
|
|
1041
|
+
</svg>
|
|
1042
|
+
</button>
|
|
950
1043
|
</span>
|
|
951
1044
|
<span class="worker-id" style="background: #ddd; border-radius: 3px; padding: 2px 5px; font-size: 0.85em; font-weight: bold;">{test["worker"]}</span>
|
|
952
1045
|
</div>
|
|
@@ -990,20 +1083,21 @@ class JSONReporter:
|
|
|
990
1083
|
"#e6f4ea" if failed_tests == 0 and error_tests == 0 else "#fdecea"
|
|
991
1084
|
};
|
|
992
1085
|
border: 1px solid {
|
|
993
|
-
"#2f7a33" if failed_tests == 0 and
|
|
994
|
-
error_tests == 0
|
|
995
|
-
else "#a83232"
|
|
1086
|
+
"#2f7a33" if failed_tests == 0 and error_tests == 0 else "#a83232"
|
|
996
1087
|
};
|
|
997
1088
|
border-radius: 5px; margin-bottom: 1rem;">
|
|
998
1089
|
{
|
|
999
1090
|
"<strong>Bingo!</strong> All your tests passed!"
|
|
1000
1091
|
if failed_tests == 0 and error_tests == 0
|
|
1001
|
-
else (
|
|
1002
|
-
|
|
1003
|
-
|
|
1092
|
+
else (
|
|
1093
|
+
f"Total tests: {total_tests}, "
|
|
1094
|
+
f"Failures: {failed_tests}, "
|
|
1095
|
+
f"Errors: {error_tests}."
|
|
1096
|
+
)
|
|
1004
1097
|
}
|
|
1005
|
-
The slowest test was <strong>{
|
|
1006
|
-
|
|
1098
|
+
The slowest test was <strong>{
|
|
1099
|
+
escape(slowest_test_name, quote=True)
|
|
1100
|
+
}</strong> at {slowest_test_duration:.2f}s.
|
|
1007
1101
|
</div>
|
|
1008
1102
|
"""
|
|
1009
1103
|
|
|
@@ -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,
|
pytest_html_plus-1.2.0/PKG-INFO
DELETED
|
@@ -1,219 +0,0 @@
|
|
|
1
|
-
Metadata-Version: 2.4
|
|
2
|
-
Name: pytest-html-plus
|
|
3
|
-
Version: 1.2.0
|
|
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
|
-
License: MIT
|
|
6
|
-
License-File: LICENSE
|
|
7
|
-
Keywords: pytest,pytest-plugin,html-report,test-report,screenshot,mobile-report,xdist,allure-alternative,playwright,selenium
|
|
8
|
-
Author: reporterplus
|
|
9
|
-
Maintainer: reporterplus
|
|
10
|
-
Requires-Python: >=3.10,<4.0
|
|
11
|
-
Classifier: Development Status :: 5 - Production/Stable
|
|
12
|
-
Classifier: Framework :: Pytest
|
|
13
|
-
Classifier: Intended Audience :: Developers
|
|
14
|
-
Classifier: License :: OSI Approved :: MIT License
|
|
15
|
-
Classifier: Operating System :: OS Independent
|
|
16
|
-
Classifier: Programming Language :: Python :: 3
|
|
17
|
-
Classifier: Programming Language :: Python :: 3.10
|
|
18
|
-
Classifier: Programming Language :: Python :: 3.11
|
|
19
|
-
Classifier: Programming Language :: Python :: 3.12
|
|
20
|
-
Classifier: Programming Language :: Python :: 3.13
|
|
21
|
-
Classifier: Programming Language :: Python :: 3.14
|
|
22
|
-
Classifier: Topic :: Software Development :: Quality Assurance
|
|
23
|
-
Classifier: Topic :: Software Development :: Testing
|
|
24
|
-
Requires-Dist: keyring (>=25.6.0,<26.0.0)
|
|
25
|
-
Requires-Dist: tomli (>=2.0.1,<3.0.0) ; python_version < "3.11"
|
|
26
|
-
Requires-Dist: yagmail (>=0.15.293,<0.16.0)
|
|
27
|
-
Project-URL: Changelog, https://github.com/reporterplus/pytest-html-plus/blob/main/CHANGELOG.md
|
|
28
|
-
Project-URL: Documentation, https://pytest-html-plus.readthedocs.io
|
|
29
|
-
Project-URL: Homepage, https://github.com/reporterplus/pytest-html-plus
|
|
30
|
-
Project-URL: Source, https://github.com/reporterplus/pytest-html-plus
|
|
31
|
-
Project-URL: Tracker, https://github.com/reporterplus/pytest-html-plus/issues
|
|
32
|
-
Description-Content-Type: text/markdown
|
|
33
|
-
|
|
34
|
-
⚡ **Test your code, not your reporting setup.**
|
|
35
|
-
> _Get started with rich pytest reports in under 3 seconds. Just install — no setup required. The simplest, fastest reporter for pytest._
|
|
36
|
-
|
|
37
|
-
## Get a self-contained, actionable, easy-to-read single page HTML unified reports summarizing all your test results — no hassle, just clarity. Detect **flaky tests**, **attach screenshots** automatically without hooks and optionally send reports via email**. Works beautifully with or without `xdist`.
|
|
38
|
-
|
|
39
|
-
➡️ [View Demo Report](https://reporterplus.github.io/pytest-html-plus/)
|
|
40
|
-
|
|
41
|
-
[](https://pytest-html-plus.readthedocs.io/en/main/) [](https://pepy.tech/projects/pytest-html-plus)    [](https://github.com/reporterplus/pytest-html-plus/actions/workflows/unit-test.yml) [](https://codecov.io/gh/reporterplus/pytest-html-plus)
|
|
42
|
-
|
|
43
|
-
---
|
|
44
|
-
|
|
45
|
-
## Already using pytest-html or Allure?
|
|
46
|
-
|
|
47
|
-
No uninstall needed — `pytest-html-plus` works alongside `pytest-html`. Install it, run your suite, and see what you've been missing. Most teams uninstall `pytest-html` within the same day.
|
|
48
|
-
|
|
49
|
-
```bash
|
|
50
|
-
pip install pytest-html-plus
|
|
51
|
-
```
|
|
52
|
-
|
|
53
|
-
Your existing `pytest --html=report.html` commands keep working unchanged.
|
|
54
|
-
|
|
55
|
-
| Feature | pytest-html | Allure | pytest-html-plus |
|
|
56
|
-
|---|:---:|:---:|:---:|
|
|
57
|
-
| Self-contained single HTML file | ✅ | ❌ | ✅ |
|
|
58
|
-
| No server or CLI tool needed | ✅ | ❌ | ✅ |
|
|
59
|
-
| Zero config — works out of the box | ✅ | ❌ | ✅ |
|
|
60
|
-
| xdist parallel run support | ⚠️ extra plugin | ✅ | ✅ built-in |
|
|
61
|
-
| Screenshots (no hooks or decorators) | ❌ | ❌ requires decorators | ✅ |
|
|
62
|
-
| Automatic log & print() capture | ❌ | ✅ | ✅ |
|
|
63
|
-
| Flaky test detection + retry history | ❌ | ✅ | ✅ |
|
|
64
|
-
| Slow test highlighting | ❌ | ❌ | ✅ |
|
|
65
|
-
| Traceability links (Jira, Testmo, etc.) | ❌ | ✅ | ✅ |
|
|
66
|
-
| JUnit XML export (merged, one flag) | ❌ extra steps | ✅ | ✅ |
|
|
67
|
-
| Run metadata (branch, commit, env) | ❌ | ✅ | ✅ |
|
|
68
|
-
| Reusable config profiles | ❌ | ❌ | ✅ |
|
|
69
|
-
| Unlinked test detection | ❌ | ❌ | ✅ |
|
|
70
|
-
| Copy logs & traces to clipboard | ❌ | ❌ | ✅ |
|
|
71
|
-
| Email reports | ❌ | ❌ | ✅ |
|
|
72
|
-
| Mobile-friendly layout | ❌ | ✅ | ✅ |
|
|
73
|
-
| Report size | 🟢 single file | 🔴 many files | 🟢 single file |
|
|
74
|
-
|
|
75
|
-
---
|
|
76
|
-
|
|
77
|
-
## 🚀 Installation
|
|
78
|
-
|
|
79
|
-
```bash
|
|
80
|
-
pip install pytest-html-plus
|
|
81
|
-
# or with Poetry
|
|
82
|
-
poetry add pytest-html-plus
|
|
83
|
-
```
|
|
84
|
-
|
|
85
|
-
## Pytest HTML Plus Action
|
|
86
|
-
|
|
87
|
-
If you don't want the burden of installing pytest-html-plus manually and your project already manages dependencies with `requirements.txt` or Poetry, use this GitHub Action to generate rich pytest reports automatically.
|
|
88
|
-
|
|
89
|
-
[](https://github.com/marketplace/actions/pytest-html-plus-action)
|
|
90
|
-
[](https://pytest-html-plus.readthedocs.io/en/main/marketplace/usage.html)
|
|
91
|
-
|
|
92
|
-
## Pytest HTML Plus VSCode
|
|
93
|
-
|
|
94
|
-
[](https://marketplace.visualstudio.com/items?itemName=reporterplus.pytest-html-plus-vscode)
|
|
95
|
-
[]
|
|
96
|
-
[](https://pytest-html-plus.readthedocs.io/en/main/extensions/vscode/usage.html)
|
|
97
|
-
|
|
98
|
-
## ✨ Features
|
|
99
|
-
|
|
100
|
-
#### 🧩 Seamless Combined XML Export to your favourite test management tools — No Plugins Needed
|
|
101
|
-
Export a fully merged JUnit XML report effortlessly — no external tools or plugins required. (No More merge html additional plugins or steps in your YAML to feed xml reports)
|
|
102
|
-
|
|
103
|
-
✔ Links, logs, stdout/stderr, and even flaky history — all included
|
|
104
|
-
✔ Works out-of-the-box with your test management tools (like TestRail, XRay, Zephyr)
|
|
105
|
-
✔ Just one flag. No extra lines of code. Total traceability.
|
|
106
|
-
|
|
107
|
-

|
|
108
|
-
|
|
109
|
-
#### 🔄 Stop Guessing — See What's Breaking Your Flaky Tests
|
|
110
|
-
Instantly see how your tests behave across retries — from failure to recovery. Spot patterns like cache issues, race conditions, and random crashes without the guesswork.
|
|
111
|
-
|
|
112
|
-

|
|
113
|
-
|
|
114
|
-
#### 🏷️ Tag your tests on the fly!
|
|
115
|
-
With dynamic markers, you can assign tags like `api`, `critical`, or `slow` — or any custom label — at runtime using standard `pytest.mark.*`.
|
|
116
|
-
No need for custom marker definitions. Perfect for smarter filtering, reporting, and analysis.
|
|
117
|
-
|
|
118
|
-

|
|
119
|
-
|
|
120
|
-
#### 📦 Ship reports with provenance 📜 — full run metadata included 📋 and copy-ready.
|
|
121
|
-
|
|
122
|
-

|
|
123
|
-
|
|
124
|
-
#### 📋⚡ Turn failure context into a single click — copy logs, traces, and errors instantly for your team.
|
|
125
|
-
|
|
126
|
-

|
|
127
|
-
|
|
128
|
-
#### Easily track Untracked test scenarios
|
|
129
|
-
|
|
130
|
-

|
|
131
|
-
|
|
132
|
-
#### 🔍 Universal Test Search + Smart Traceability
|
|
133
|
-
|
|
134
|
-
Whether you're tracing coverage, investigating failures, or tracking unlinked test cases — this search has your back!
|
|
135
|
-
|
|
136
|
-
Just start typing, and the dashboard will instantly filter tests by:
|
|
137
|
-
|
|
138
|
-
✅ Test names
|
|
139
|
-
|
|
140
|
-
✅ Linked issue or documentation IDs (JIRA, Testmo, Notion, etc.)
|
|
141
|
-
|
|
142
|
-
✅ Custom URLs or keywords present in linked references
|
|
143
|
-
|
|
144
|
-
✅ Error messages and trace snippets to quickly group related failures
|
|
145
|
-
|
|
146
|
-
<img width="800" height="421" alt="new_search" src="https://github.com/user-attachments/assets/54858747-ab16-4d4f-baa9-0d651a1d8bac" />
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
#### 📸 Screenshot Support: View screenshots directly in the report to understand failures faster.
|
|
150
|
-
|
|
151
|
-
#### 📧 Email Test Reports: Send your reports via email effortlessly using SendGrid integration.
|
|
152
|
-
|
|
153
|
-

|
|
154
|
-
|
|
155
|
-
#### 🐢 Spot Slow Tests: Highlights the slowest tests so you know where to optimize your suite.
|
|
156
|
-
|
|
157
|
-

|
|
158
|
-
|
|
159
|
-
#### 📝 Configurable output capture: Test logs, print() statements, stdout/stderr, and screenshots are automatically captured and embedded in the report. Use `--plus-output=failed-only` to omit captured stdout/stderr from passing tests and reduce report size; logger and screenshot behavior is unchanged.
|
|
160
|
-
|
|
161
|
-

|
|
162
|
-
|
|
163
|
-
### Complete Feature List
|
|
164
|
-
|
|
165
|
-
| Feature | Details |
|
|
166
|
-
|---|---|
|
|
167
|
-
| 📊 **Single-file HTML report** | Fully self-contained — no external CSS, JS, or image folders to archive |
|
|
168
|
-
| 🔄 **Flaky test detection** | Detects tests that fail then pass on retry; shows full retry history |
|
|
169
|
-
| 📸 **Automatic screenshots** | Selenium & Playwright screenshots captured and embedded with no conftest hooks |
|
|
170
|
-
| 🧩 **JUnit XML export** | Merged XML output compatible with TestRail, Xray, and Zephyr (`--generate-xml`) |
|
|
171
|
-
| 🔗 **Traceability links** | Attach Jira, Testmo, Notion, or any URL to a test; rendered and searchable in the report |
|
|
172
|
-
| 🏷️ **Dynamic markers** | Tag tests at runtime with `pytest.mark.*` — no marker pre-registration needed |
|
|
173
|
-
| 🔍 **Universal search** | Filter tests by name, issue ID, or any URL keyword in real time |
|
|
174
|
-
| 🐢 **Slow test highlighting** | Slowest tests in the run automatically flagged |
|
|
175
|
-
| 📋 **Copy-to-clipboard** | Copy test path, logs, trace, and errors in one click |
|
|
176
|
-
| 📦 **Run metadata** | Branch, commit SHA, environment, and custom metadata embedded in the report header |
|
|
177
|
-
| 📝 **Configurable stream capture** | Control captured stdout/stderr with `--plus-output`; logger and screenshot behavior remains unchanged |
|
|
178
|
-
| ⚡ **xdist support** | Parallel runs with `pytest-xdist` produce a single merged report, no extra steps |
|
|
179
|
-
| 🌐 **Auto-open report** | `--should-open-report` opens the report in your browser after a run (always / failed / never) |
|
|
180
|
-
| 📄 **JSON report** | Raw JSON output (`--json-report`) for custom dashboards or post-processing |
|
|
181
|
-
| 🔎 **Unlinked test detection** | Instantly filter tests that have no associated issue or documentation link |
|
|
182
|
-
| ⚙️ **Reusable config profiles** | Define named profiles in `pyproject.toml` (`--profile=ci`) — no more repeated CLI flags |
|
|
183
|
-
| 📱 **Mobile-friendly layout** | Report renders cleanly on any screen size |
|
|
184
|
-
| 📧 **Email reports** | Send reports via SendGrid integration (`--send-email`) |
|
|
185
|
-
|
|
186
|
-
## Target Audience
|
|
187
|
-
|
|
188
|
-
This plugin is aimed at those who are:
|
|
189
|
-
|
|
190
|
-
- Tired of writing extra code just to generate reports or capture screenshots
|
|
191
|
-
|
|
192
|
-
- Manually attaching logs or outputs to test results
|
|
193
|
-
|
|
194
|
-
- Are frustrated with archiving folders full of assets, CSS, JS, and dashboards just to share test results.
|
|
195
|
-
|
|
196
|
-
- Don't want to refactor existing test suites or tag everything with new decorators just to integrate with a reporting tool.
|
|
197
|
-
|
|
198
|
-
- Prefer simplicity — a zero-config, zero code, lightweight report that still looks clean, useful, and polished.
|
|
199
|
-
|
|
200
|
-
- Want "just enough" — not bare-bones plain text, not a full dashboard with database setup — just a portable HTML report that STILL supports features like links, screenshots, and markers.
|
|
201
|
-
|
|
202
|
-
## Project Status
|
|
203
|
-
|
|
204
|
-
pytest-html-plus is stable and actively maintained, with its core reporting experience now well established. Future development will prioritize compatibility, reliability, bug fixes, and thoughtfully selected enhancements.
|
|
205
|
-
|
|
206
|
-
We're also looking for co-maintainers to help review pull requests, triage issues, and keep the project healthy across future Python and pytest releases.
|
|
207
|
-
|
|
208
|
-
If you're interested in becoming a long-term contributor, we'd love to hear from you. Please open an issue or start a discussion.
|
|
209
|
-
|
|
210
|
-
## Contributing
|
|
211
|
-
|
|
212
|
-
We welcome pull requests, issues, and feature suggestions from the community.
|
|
213
|
-
|
|
214
|
-
See the [contribution guide](CONTRIBUTING.md) for setup instructions.
|
|
215
|
-
|
|
216
|
-
## 📜 License
|
|
217
|
-
|
|
218
|
-
MIT
|
|
219
|
-
|
pytest_html_plus-1.2.0/README.md
DELETED
|
@@ -1,185 +0,0 @@
|
|
|
1
|
-
⚡ **Test your code, not your reporting setup.**
|
|
2
|
-
> _Get started with rich pytest reports in under 3 seconds. Just install — no setup required. The simplest, fastest reporter for pytest._
|
|
3
|
-
|
|
4
|
-
## Get a self-contained, actionable, easy-to-read single page HTML unified reports summarizing all your test results — no hassle, just clarity. Detect **flaky tests**, **attach screenshots** automatically without hooks and optionally send reports via email**. Works beautifully with or without `xdist`.
|
|
5
|
-
|
|
6
|
-
➡️ [View Demo Report](https://reporterplus.github.io/pytest-html-plus/)
|
|
7
|
-
|
|
8
|
-
[](https://pytest-html-plus.readthedocs.io/en/main/) [](https://pepy.tech/projects/pytest-html-plus)    [](https://github.com/reporterplus/pytest-html-plus/actions/workflows/unit-test.yml) [](https://codecov.io/gh/reporterplus/pytest-html-plus)
|
|
9
|
-
|
|
10
|
-
---
|
|
11
|
-
|
|
12
|
-
## Already using pytest-html or Allure?
|
|
13
|
-
|
|
14
|
-
No uninstall needed — `pytest-html-plus` works alongside `pytest-html`. Install it, run your suite, and see what you've been missing. Most teams uninstall `pytest-html` within the same day.
|
|
15
|
-
|
|
16
|
-
```bash
|
|
17
|
-
pip install pytest-html-plus
|
|
18
|
-
```
|
|
19
|
-
|
|
20
|
-
Your existing `pytest --html=report.html` commands keep working unchanged.
|
|
21
|
-
|
|
22
|
-
| Feature | pytest-html | Allure | pytest-html-plus |
|
|
23
|
-
|---|:---:|:---:|:---:|
|
|
24
|
-
| Self-contained single HTML file | ✅ | ❌ | ✅ |
|
|
25
|
-
| No server or CLI tool needed | ✅ | ❌ | ✅ |
|
|
26
|
-
| Zero config — works out of the box | ✅ | ❌ | ✅ |
|
|
27
|
-
| xdist parallel run support | ⚠️ extra plugin | ✅ | ✅ built-in |
|
|
28
|
-
| Screenshots (no hooks or decorators) | ❌ | ❌ requires decorators | ✅ |
|
|
29
|
-
| Automatic log & print() capture | ❌ | ✅ | ✅ |
|
|
30
|
-
| Flaky test detection + retry history | ❌ | ✅ | ✅ |
|
|
31
|
-
| Slow test highlighting | ❌ | ❌ | ✅ |
|
|
32
|
-
| Traceability links (Jira, Testmo, etc.) | ❌ | ✅ | ✅ |
|
|
33
|
-
| JUnit XML export (merged, one flag) | ❌ extra steps | ✅ | ✅ |
|
|
34
|
-
| Run metadata (branch, commit, env) | ❌ | ✅ | ✅ |
|
|
35
|
-
| Reusable config profiles | ❌ | ❌ | ✅ |
|
|
36
|
-
| Unlinked test detection | ❌ | ❌ | ✅ |
|
|
37
|
-
| Copy logs & traces to clipboard | ❌ | ❌ | ✅ |
|
|
38
|
-
| Email reports | ❌ | ❌ | ✅ |
|
|
39
|
-
| Mobile-friendly layout | ❌ | ✅ | ✅ |
|
|
40
|
-
| Report size | 🟢 single file | 🔴 many files | 🟢 single file |
|
|
41
|
-
|
|
42
|
-
---
|
|
43
|
-
|
|
44
|
-
## 🚀 Installation
|
|
45
|
-
|
|
46
|
-
```bash
|
|
47
|
-
pip install pytest-html-plus
|
|
48
|
-
# or with Poetry
|
|
49
|
-
poetry add pytest-html-plus
|
|
50
|
-
```
|
|
51
|
-
|
|
52
|
-
## Pytest HTML Plus Action
|
|
53
|
-
|
|
54
|
-
If you don't want the burden of installing pytest-html-plus manually and your project already manages dependencies with `requirements.txt` or Poetry, use this GitHub Action to generate rich pytest reports automatically.
|
|
55
|
-
|
|
56
|
-
[](https://github.com/marketplace/actions/pytest-html-plus-action)
|
|
57
|
-
[](https://pytest-html-plus.readthedocs.io/en/main/marketplace/usage.html)
|
|
58
|
-
|
|
59
|
-
## Pytest HTML Plus VSCode
|
|
60
|
-
|
|
61
|
-
[](https://marketplace.visualstudio.com/items?itemName=reporterplus.pytest-html-plus-vscode)
|
|
62
|
-
[]
|
|
63
|
-
[](https://pytest-html-plus.readthedocs.io/en/main/extensions/vscode/usage.html)
|
|
64
|
-
|
|
65
|
-
## ✨ Features
|
|
66
|
-
|
|
67
|
-
#### 🧩 Seamless Combined XML Export to your favourite test management tools — No Plugins Needed
|
|
68
|
-
Export a fully merged JUnit XML report effortlessly — no external tools or plugins required. (No More merge html additional plugins or steps in your YAML to feed xml reports)
|
|
69
|
-
|
|
70
|
-
✔ Links, logs, stdout/stderr, and even flaky history — all included
|
|
71
|
-
✔ Works out-of-the-box with your test management tools (like TestRail, XRay, Zephyr)
|
|
72
|
-
✔ Just one flag. No extra lines of code. Total traceability.
|
|
73
|
-
|
|
74
|
-

|
|
75
|
-
|
|
76
|
-
#### 🔄 Stop Guessing — See What's Breaking Your Flaky Tests
|
|
77
|
-
Instantly see how your tests behave across retries — from failure to recovery. Spot patterns like cache issues, race conditions, and random crashes without the guesswork.
|
|
78
|
-
|
|
79
|
-

|
|
80
|
-
|
|
81
|
-
#### 🏷️ Tag your tests on the fly!
|
|
82
|
-
With dynamic markers, you can assign tags like `api`, `critical`, or `slow` — or any custom label — at runtime using standard `pytest.mark.*`.
|
|
83
|
-
No need for custom marker definitions. Perfect for smarter filtering, reporting, and analysis.
|
|
84
|
-
|
|
85
|
-

|
|
86
|
-
|
|
87
|
-
#### 📦 Ship reports with provenance 📜 — full run metadata included 📋 and copy-ready.
|
|
88
|
-
|
|
89
|
-

|
|
90
|
-
|
|
91
|
-
#### 📋⚡ Turn failure context into a single click — copy logs, traces, and errors instantly for your team.
|
|
92
|
-
|
|
93
|
-

|
|
94
|
-
|
|
95
|
-
#### Easily track Untracked test scenarios
|
|
96
|
-
|
|
97
|
-

|
|
98
|
-
|
|
99
|
-
#### 🔍 Universal Test Search + Smart Traceability
|
|
100
|
-
|
|
101
|
-
Whether you're tracing coverage, investigating failures, or tracking unlinked test cases — this search has your back!
|
|
102
|
-
|
|
103
|
-
Just start typing, and the dashboard will instantly filter tests by:
|
|
104
|
-
|
|
105
|
-
✅ Test names
|
|
106
|
-
|
|
107
|
-
✅ Linked issue or documentation IDs (JIRA, Testmo, Notion, etc.)
|
|
108
|
-
|
|
109
|
-
✅ Custom URLs or keywords present in linked references
|
|
110
|
-
|
|
111
|
-
✅ Error messages and trace snippets to quickly group related failures
|
|
112
|
-
|
|
113
|
-
<img width="800" height="421" alt="new_search" src="https://github.com/user-attachments/assets/54858747-ab16-4d4f-baa9-0d651a1d8bac" />
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
#### 📸 Screenshot Support: View screenshots directly in the report to understand failures faster.
|
|
117
|
-
|
|
118
|
-
#### 📧 Email Test Reports: Send your reports via email effortlessly using SendGrid integration.
|
|
119
|
-
|
|
120
|
-

|
|
121
|
-
|
|
122
|
-
#### 🐢 Spot Slow Tests: Highlights the slowest tests so you know where to optimize your suite.
|
|
123
|
-
|
|
124
|
-

|
|
125
|
-
|
|
126
|
-
#### 📝 Configurable output capture: Test logs, print() statements, stdout/stderr, and screenshots are automatically captured and embedded in the report. Use `--plus-output=failed-only` to omit captured stdout/stderr from passing tests and reduce report size; logger and screenshot behavior is unchanged.
|
|
127
|
-
|
|
128
|
-

|
|
129
|
-
|
|
130
|
-
### Complete Feature List
|
|
131
|
-
|
|
132
|
-
| Feature | Details |
|
|
133
|
-
|---|---|
|
|
134
|
-
| 📊 **Single-file HTML report** | Fully self-contained — no external CSS, JS, or image folders to archive |
|
|
135
|
-
| 🔄 **Flaky test detection** | Detects tests that fail then pass on retry; shows full retry history |
|
|
136
|
-
| 📸 **Automatic screenshots** | Selenium & Playwright screenshots captured and embedded with no conftest hooks |
|
|
137
|
-
| 🧩 **JUnit XML export** | Merged XML output compatible with TestRail, Xray, and Zephyr (`--generate-xml`) |
|
|
138
|
-
| 🔗 **Traceability links** | Attach Jira, Testmo, Notion, or any URL to a test; rendered and searchable in the report |
|
|
139
|
-
| 🏷️ **Dynamic markers** | Tag tests at runtime with `pytest.mark.*` — no marker pre-registration needed |
|
|
140
|
-
| 🔍 **Universal search** | Filter tests by name, issue ID, or any URL keyword in real time |
|
|
141
|
-
| 🐢 **Slow test highlighting** | Slowest tests in the run automatically flagged |
|
|
142
|
-
| 📋 **Copy-to-clipboard** | Copy test path, logs, trace, and errors in one click |
|
|
143
|
-
| 📦 **Run metadata** | Branch, commit SHA, environment, and custom metadata embedded in the report header |
|
|
144
|
-
| 📝 **Configurable stream capture** | Control captured stdout/stderr with `--plus-output`; logger and screenshot behavior remains unchanged |
|
|
145
|
-
| ⚡ **xdist support** | Parallel runs with `pytest-xdist` produce a single merged report, no extra steps |
|
|
146
|
-
| 🌐 **Auto-open report** | `--should-open-report` opens the report in your browser after a run (always / failed / never) |
|
|
147
|
-
| 📄 **JSON report** | Raw JSON output (`--json-report`) for custom dashboards or post-processing |
|
|
148
|
-
| 🔎 **Unlinked test detection** | Instantly filter tests that have no associated issue or documentation link |
|
|
149
|
-
| ⚙️ **Reusable config profiles** | Define named profiles in `pyproject.toml` (`--profile=ci`) — no more repeated CLI flags |
|
|
150
|
-
| 📱 **Mobile-friendly layout** | Report renders cleanly on any screen size |
|
|
151
|
-
| 📧 **Email reports** | Send reports via SendGrid integration (`--send-email`) |
|
|
152
|
-
|
|
153
|
-
## Target Audience
|
|
154
|
-
|
|
155
|
-
This plugin is aimed at those who are:
|
|
156
|
-
|
|
157
|
-
- Tired of writing extra code just to generate reports or capture screenshots
|
|
158
|
-
|
|
159
|
-
- Manually attaching logs or outputs to test results
|
|
160
|
-
|
|
161
|
-
- Are frustrated with archiving folders full of assets, CSS, JS, and dashboards just to share test results.
|
|
162
|
-
|
|
163
|
-
- Don't want to refactor existing test suites or tag everything with new decorators just to integrate with a reporting tool.
|
|
164
|
-
|
|
165
|
-
- Prefer simplicity — a zero-config, zero code, lightweight report that still looks clean, useful, and polished.
|
|
166
|
-
|
|
167
|
-
- Want "just enough" — not bare-bones plain text, not a full dashboard with database setup — just a portable HTML report that STILL supports features like links, screenshots, and markers.
|
|
168
|
-
|
|
169
|
-
## Project Status
|
|
170
|
-
|
|
171
|
-
pytest-html-plus is stable and actively maintained, with its core reporting experience now well established. Future development will prioritize compatibility, reliability, bug fixes, and thoughtfully selected enhancements.
|
|
172
|
-
|
|
173
|
-
We're also looking for co-maintainers to help review pull requests, triage issues, and keep the project healthy across future Python and pytest releases.
|
|
174
|
-
|
|
175
|
-
If you're interested in becoming a long-term contributor, we'd love to hear from you. Please open an issue or start a discussion.
|
|
176
|
-
|
|
177
|
-
## Contributing
|
|
178
|
-
|
|
179
|
-
We welcome pull requests, issues, and feature suggestions from the community.
|
|
180
|
-
|
|
181
|
-
See the [contribution guide](CONTRIBUTING.md) for setup instructions.
|
|
182
|
-
|
|
183
|
-
## 📜 License
|
|
184
|
-
|
|
185
|
-
MIT
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{pytest_html_plus-1.2.0 → pytest_html_plus-1.3.0}/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
|