pytest-html-plus 0.5.2__tar.gz → 1.0.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.
@@ -1,13 +1,14 @@
1
- Metadata-Version: 2.3
1
+ Metadata-Version: 2.4
2
2
  Name: pytest-html-plus
3
- Version: 0.5.2
3
+ Version: 1.0.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
+ License-File: LICENSE
6
7
  Keywords: pytest,pytest-plugin,html-report,test-report,screenshot,mobile-report,xdist,allure-alternative,playwright,selenium
7
8
  Author: reporterplus
8
9
  Maintainer: reporterplus
9
10
  Requires-Python: >=3.10,<4.0
10
- Classifier: Development Status :: 4 - Beta
11
+ Classifier: Development Status :: 5 - Production/Stable
11
12
  Classifier: Framework :: Pytest
12
13
  Classifier: Intended Audience :: Developers
13
14
  Classifier: License :: OSI Approved :: MIT License
@@ -17,10 +18,13 @@ Classifier: Programming Language :: Python :: 3.10
17
18
  Classifier: Programming Language :: Python :: 3.11
18
19
  Classifier: Programming Language :: Python :: 3.12
19
20
  Classifier: Programming Language :: Python :: 3.13
21
+ Classifier: Programming Language :: Python :: 3.14
20
22
  Classifier: Topic :: Software Development :: Quality Assurance
21
23
  Classifier: Topic :: Software Development :: Testing
22
24
  Requires-Dist: keyring (>=25.6.0,<26.0.0)
25
+ Requires-Dist: tomli (>=2.0.1,<3.0.0) ; python_version < "3.11"
23
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
24
28
  Project-URL: Documentation, https://pytest-html-plus.readthedocs.io
25
29
  Project-URL: Homepage, https://github.com/reporterplus/pytest-html-plus
26
30
  Project-URL: Source, https://github.com/reporterplus/pytest-html-plus
@@ -34,9 +38,41 @@ Description-Content-Type: text/markdown
34
38
 
35
39
  ➡️ [View Demo Report](https://reporterplus.github.io/pytest-html-plus/)
36
40
 
37
- [![Docs](https://img.shields.io/badge/docs-online-blue)](https://pytest-html-plus.readthedocs.io/en/main/) [![PyPI Downloads](https://static.pepy.tech/badge/pytest-html-plus)](https://pepy.tech/projects/pytest-html-plus) ![PyPI](https://img.shields.io/pypi/v/pytest-html-plus) ![Python Versions](https://img.shields.io/pypi/pyversions/pytest-html-plus) ![License](https://img.shields.io/pypi/l/pytest-html-plus) [![Unit Tests](https://github.com/reach2jeyan/pytest-report-plus/actions/workflows/unit-test.yml/badge.svg)](https://github.com/reach2jeyan/pytest-report-plus/actions/workflows/unit-test.yml)
41
+ [![Docs](https://img.shields.io/badge/docs-online-blue)](https://pytest-html-plus.readthedocs.io/en/main/) [![PyPI Downloads](https://static.pepy.tech/badge/pytest-html-plus)](https://pepy.tech/projects/pytest-html-plus) ![PyPI](https://img.shields.io/pypi/v/pytest-html-plus) ![Python Versions](https://img.shields.io/pypi/pyversions/pytest-html-plus) ![License](https://img.shields.io/pypi/l/pytest-html-plus) [![Unit Tests](https://github.com/reporterplus/pytest-html-plus/actions/workflows/unit-test.yml/badge.svg)](https://github.com/reporterplus/pytest-html-plus/actions/workflows/unit-test.yml) [![codecov](https://codecov.io/gh/reporterplus/pytest-html-plus/branch/main/graph/badge.svg)](https://codecov.io/gh/reporterplus/pytest-html-plus)
38
42
 
39
- [![Discord](https://img.shields.io/discord/1377581416337903646?labelColor=black&logo=discord&logoColor=c20a71&style=for-the-badge&color=c20a71)](https://discord.gg/nUNZ9crf)
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
+ ---
40
76
 
41
77
  ## 🚀 Installation
42
78
 
@@ -48,7 +84,7 @@ poetry add pytest-html-plus
48
84
 
49
85
  ## Pytest HTML Plus Action
50
86
 
51
- 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.
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.
52
88
 
53
89
  [![🚀 Checkout on GitHub Marketplace](https://img.shields.io/badge/Marketplace-Pytest%20HTML%20Plus-blue?logo=github)](https://github.com/marketplace/actions/pytest-html-plus-action)
54
90
  [![Documentation](https://img.shields.io/badge/docs-readthedocs.io-brightgreen)](https://pytest-html-plus.readthedocs.io/en/main/marketplace/usage.html)
@@ -70,7 +106,7 @@ Export a fully merged JUnit XML report effortlessly — no external tools or plu
70
106
 
71
107
  ![ScreenRecording2025-07-06at11 38 21PM-ezgif com-video-to-gif-converter](https://github.com/user-attachments/assets/02da5cc9-7ef5-4a3a-a475-88907964a9c6)
72
108
 
73
- #### 🔄 Stop Guessing — See What’s Breaking Your Flaky Tests
109
+ #### 🔄 Stop Guessing — See What's Breaking Your Flaky Tests
74
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.
75
111
 
76
112
  ![ezgif com-video-to-gif-converter](https://github.com/user-attachments/assets/1f7e0cd8-d2f9-47fd-8909-6f12adf8a800)
@@ -111,7 +147,7 @@ Just start typing, and the dashboard will instantly filter tests by:
111
147
 
112
148
  #### 📧 Email Test Reports: Send your reports via email effortlessly using SendGrid integration.
113
149
 
114
- ![Screenshot 2025-05-28 at 4 38 49 PM](https://github.com/user-attachments/assets/3f40e206-5dfd-45e9-a511-4dd206cf3318)
150
+ ![Screenshot 2025-05-28 at 4 38 49 PM](https://github.com/user-attachments/assets/3f40e206-5dfd-45e9-a511-4dd206cf3318)
115
151
 
116
152
  #### 🐢 Spot Slow Tests: Highlights the slowest tests so you know where to optimize your suite.
117
153
 
@@ -121,7 +157,28 @@ Just start typing, and the dashboard will instantly filter tests by:
121
157
 
122
158
  ![ezgif-744a5d34a4c46d](https://github.com/user-attachments/assets/209cd2c0-d33b-48ec-b58b-8c8991ce35be)
123
159
 
124
- ### AND MANY MANY MORE
160
+ ### Complete Feature List
161
+
162
+ | Feature | Details |
163
+ |---|---|
164
+ | 📊 **Single-file HTML report** | Fully self-contained — no external CSS, JS, or image folders to archive |
165
+ | 🔄 **Flaky test detection** | Detects tests that fail then pass on retry; shows full retry history |
166
+ | 📸 **Automatic screenshots** | Selenium & Playwright screenshots captured and embedded with no conftest hooks |
167
+ | 🧩 **JUnit XML export** | Merged XML output compatible with TestRail, Xray, and Zephyr (`--generate-xml`) |
168
+ | 🔗 **Traceability links** | Attach Jira, Testmo, Notion, or any URL to a test; rendered and searchable in the report |
169
+ | 🏷️ **Dynamic markers** | Tag tests at runtime with `pytest.mark.*` — no marker pre-registration needed |
170
+ | 🔍 **Universal search** | Filter tests by name, issue ID, or any URL keyword in real time |
171
+ | 🐢 **Slow test highlighting** | Slowest tests in the run automatically flagged |
172
+ | 📋 **Copy-to-clipboard** | Copy test path, logs, trace, and errors in one click |
173
+ | 📦 **Run metadata** | Branch, commit SHA, environment, and custom metadata embedded in the report header |
174
+ | 📝 **Comprehensive log capture** | `print()`, logger output, and stdout/stderr automatically captured per test |
175
+ | ⚡ **xdist support** | Parallel runs with `pytest-xdist` produce a single merged report, no extra steps |
176
+ | 🌐 **Auto-open report** | `--should-open-report` opens the report in your browser after a run (always / failed / never) |
177
+ | 📄 **JSON report** | Raw JSON output (`--json-report`) for custom dashboards or post-processing |
178
+ | 🔎 **Unlinked test detection** | Instantly filter tests that have no associated issue or documentation link |
179
+ | ⚙️ **Reusable config profiles** | Define named profiles in `pyproject.toml` (`--profile=ci`) — no more repeated CLI flags |
180
+ | 📱 **Mobile-friendly layout** | Report renders cleanly on any screen size |
181
+ | 📧 **Email reports** | Send reports via SendGrid integration (`--send-email`) |
125
182
 
126
183
  ## Target Audience
127
184
 
@@ -133,36 +190,17 @@ This plugin is aimed at those who are:
133
190
 
134
191
  - Are frustrated with archiving folders full of assets, CSS, JS, and dashboards just to share test results.
135
192
 
136
- - Don’t want to refactor existing test suites or tag everything with new decorators just to integrate with a reporting tool.
193
+ - Don't want to refactor existing test suites or tag everything with new decorators just to integrate with a reporting tool.
137
194
 
138
195
  - Prefer simplicity — a zero-config, zero code, lightweight report that still looks clean, useful, and polished.
139
196
 
140
- - 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.
141
-
142
-
143
- ## Comparison with Alternatives
144
- Most existing pytest reporter tools:
145
-
146
- Only generate HTML reports from a single run (by making you write code for creating xmls like pytest-html) OR they generate all the JS and png files that are not the scope of test results and force you to archive it.
147
-
148
- Heavy duty with bloated charts and other test management features(when they arent your only test management system either) increasing your archive size.
149
-
150
- This plugin aims to fill those gaps by acting as a companion layer on top of the JSON report, focusing on:
151
-
152
- 🔄 Merge + flakiness intelligence
153
-
154
- 🔗 Traceability via metadata
155
-
156
- 🧼 HTML that’s both readable and minimal
157
-
158
- 🧼 Quickly copy test paths and run in your local
197
+ - 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.
159
198
 
160
199
  ## Contributing
161
200
 
162
201
  We welcome pull requests, issues, and feature suggestions from the community.
163
202
 
164
- See the [contribution guide](https://pytest-html-plus.readthedocs.io/en/latest/contributing.html) for setup instructions.
165
-
203
+ See the [contribution guide](CONTRIBUTING.md) for setup instructions.
166
204
 
167
205
  ## 📜 License
168
206
 
@@ -5,9 +5,41 @@
5
5
 
6
6
  ➡️ [View Demo Report](https://reporterplus.github.io/pytest-html-plus/)
7
7
 
8
- [![Docs](https://img.shields.io/badge/docs-online-blue)](https://pytest-html-plus.readthedocs.io/en/main/) [![PyPI Downloads](https://static.pepy.tech/badge/pytest-html-plus)](https://pepy.tech/projects/pytest-html-plus) ![PyPI](https://img.shields.io/pypi/v/pytest-html-plus) ![Python Versions](https://img.shields.io/pypi/pyversions/pytest-html-plus) ![License](https://img.shields.io/pypi/l/pytest-html-plus) [![Unit Tests](https://github.com/reach2jeyan/pytest-report-plus/actions/workflows/unit-test.yml/badge.svg)](https://github.com/reach2jeyan/pytest-report-plus/actions/workflows/unit-test.yml)
8
+ [![Docs](https://img.shields.io/badge/docs-online-blue)](https://pytest-html-plus.readthedocs.io/en/main/) [![PyPI Downloads](https://static.pepy.tech/badge/pytest-html-plus)](https://pepy.tech/projects/pytest-html-plus) ![PyPI](https://img.shields.io/pypi/v/pytest-html-plus) ![Python Versions](https://img.shields.io/pypi/pyversions/pytest-html-plus) ![License](https://img.shields.io/pypi/l/pytest-html-plus) [![Unit Tests](https://github.com/reporterplus/pytest-html-plus/actions/workflows/unit-test.yml/badge.svg)](https://github.com/reporterplus/pytest-html-plus/actions/workflows/unit-test.yml) [![codecov](https://codecov.io/gh/reporterplus/pytest-html-plus/branch/main/graph/badge.svg)](https://codecov.io/gh/reporterplus/pytest-html-plus)
9
9
 
10
- [![Discord](https://img.shields.io/discord/1377581416337903646?labelColor=black&logo=discord&logoColor=c20a71&style=for-the-badge&color=c20a71)](https://discord.gg/nUNZ9crf)
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
+ ---
11
43
 
12
44
  ## 🚀 Installation
13
45
 
@@ -19,7 +51,7 @@ poetry add pytest-html-plus
19
51
 
20
52
  ## Pytest HTML Plus Action
21
53
 
22
- 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.
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.
23
55
 
24
56
  [![🚀 Checkout on GitHub Marketplace](https://img.shields.io/badge/Marketplace-Pytest%20HTML%20Plus-blue?logo=github)](https://github.com/marketplace/actions/pytest-html-plus-action)
25
57
  [![Documentation](https://img.shields.io/badge/docs-readthedocs.io-brightgreen)](https://pytest-html-plus.readthedocs.io/en/main/marketplace/usage.html)
@@ -41,7 +73,7 @@ Export a fully merged JUnit XML report effortlessly — no external tools or plu
41
73
 
42
74
  ![ScreenRecording2025-07-06at11 38 21PM-ezgif com-video-to-gif-converter](https://github.com/user-attachments/assets/02da5cc9-7ef5-4a3a-a475-88907964a9c6)
43
75
 
44
- #### 🔄 Stop Guessing — See What’s Breaking Your Flaky Tests
76
+ #### 🔄 Stop Guessing — See What's Breaking Your Flaky Tests
45
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.
46
78
 
47
79
  ![ezgif com-video-to-gif-converter](https://github.com/user-attachments/assets/1f7e0cd8-d2f9-47fd-8909-6f12adf8a800)
@@ -82,7 +114,7 @@ Just start typing, and the dashboard will instantly filter tests by:
82
114
 
83
115
  #### 📧 Email Test Reports: Send your reports via email effortlessly using SendGrid integration.
84
116
 
85
- ![Screenshot 2025-05-28 at 4 38 49 PM](https://github.com/user-attachments/assets/3f40e206-5dfd-45e9-a511-4dd206cf3318)
117
+ ![Screenshot 2025-05-28 at 4 38 49 PM](https://github.com/user-attachments/assets/3f40e206-5dfd-45e9-a511-4dd206cf3318)
86
118
 
87
119
  #### 🐢 Spot Slow Tests: Highlights the slowest tests so you know where to optimize your suite.
88
120
 
@@ -92,7 +124,28 @@ Just start typing, and the dashboard will instantly filter tests by:
92
124
 
93
125
  ![ezgif-744a5d34a4c46d](https://github.com/user-attachments/assets/209cd2c0-d33b-48ec-b58b-8c8991ce35be)
94
126
 
95
- ### AND MANY MANY MORE
127
+ ### Complete Feature List
128
+
129
+ | Feature | Details |
130
+ |---|---|
131
+ | 📊 **Single-file HTML report** | Fully self-contained — no external CSS, JS, or image folders to archive |
132
+ | 🔄 **Flaky test detection** | Detects tests that fail then pass on retry; shows full retry history |
133
+ | 📸 **Automatic screenshots** | Selenium & Playwright screenshots captured and embedded with no conftest hooks |
134
+ | 🧩 **JUnit XML export** | Merged XML output compatible with TestRail, Xray, and Zephyr (`--generate-xml`) |
135
+ | 🔗 **Traceability links** | Attach Jira, Testmo, Notion, or any URL to a test; rendered and searchable in the report |
136
+ | 🏷️ **Dynamic markers** | Tag tests at runtime with `pytest.mark.*` — no marker pre-registration needed |
137
+ | 🔍 **Universal search** | Filter tests by name, issue ID, or any URL keyword in real time |
138
+ | 🐢 **Slow test highlighting** | Slowest tests in the run automatically flagged |
139
+ | 📋 **Copy-to-clipboard** | Copy test path, logs, trace, and errors in one click |
140
+ | 📦 **Run metadata** | Branch, commit SHA, environment, and custom metadata embedded in the report header |
141
+ | 📝 **Comprehensive log capture** | `print()`, logger output, and stdout/stderr automatically captured per test |
142
+ | ⚡ **xdist support** | Parallel runs with `pytest-xdist` produce a single merged report, no extra steps |
143
+ | 🌐 **Auto-open report** | `--should-open-report` opens the report in your browser after a run (always / failed / never) |
144
+ | 📄 **JSON report** | Raw JSON output (`--json-report`) for custom dashboards or post-processing |
145
+ | 🔎 **Unlinked test detection** | Instantly filter tests that have no associated issue or documentation link |
146
+ | ⚙️ **Reusable config profiles** | Define named profiles in `pyproject.toml` (`--profile=ci`) — no more repeated CLI flags |
147
+ | 📱 **Mobile-friendly layout** | Report renders cleanly on any screen size |
148
+ | 📧 **Email reports** | Send reports via SendGrid integration (`--send-email`) |
96
149
 
97
150
  ## Target Audience
98
151
 
@@ -104,36 +157,17 @@ This plugin is aimed at those who are:
104
157
 
105
158
  - Are frustrated with archiving folders full of assets, CSS, JS, and dashboards just to share test results.
106
159
 
107
- - Don’t want to refactor existing test suites or tag everything with new decorators just to integrate with a reporting tool.
160
+ - Don't want to refactor existing test suites or tag everything with new decorators just to integrate with a reporting tool.
108
161
 
109
162
  - Prefer simplicity — a zero-config, zero code, lightweight report that still looks clean, useful, and polished.
110
163
 
111
- - 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.
112
-
113
-
114
- ## Comparison with Alternatives
115
- Most existing pytest reporter tools:
116
-
117
- Only generate HTML reports from a single run (by making you write code for creating xmls like pytest-html) OR they generate all the JS and png files that are not the scope of test results and force you to archive it.
118
-
119
- Heavy duty with bloated charts and other test management features(when they arent your only test management system either) increasing your archive size.
120
-
121
- This plugin aims to fill those gaps by acting as a companion layer on top of the JSON report, focusing on:
122
-
123
- 🔄 Merge + flakiness intelligence
124
-
125
- 🔗 Traceability via metadata
126
-
127
- 🧼 HTML that’s both readable and minimal
128
-
129
- 🧼 Quickly copy test paths and run in your local
164
+ - 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.
130
165
 
131
166
  ## Contributing
132
167
 
133
168
  We welcome pull requests, issues, and feature suggestions from the community.
134
169
 
135
- See the [contribution guide](https://pytest-html-plus.readthedocs.io/en/latest/contributing.html) for setup instructions.
136
-
170
+ See the [contribution guide](CONTRIBUTING.md) for setup instructions.
137
171
 
138
172
  ## 📜 License
139
173
 
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "pytest-html-plus"
3
- version = "0.5.2"
3
+ version = "1.0.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"]
@@ -18,7 +18,7 @@ classifiers = [
18
18
  "Topic :: Software Development :: Testing",
19
19
  "Topic :: Software Development :: Quality Assurance",
20
20
  "Intended Audience :: Developers",
21
- "Development Status :: 4 - Beta",
21
+ "Development Status :: 5 - Production/Stable",
22
22
  ]
23
23
  keywords = [
24
24
  "pytest",
@@ -37,11 +37,13 @@ urls.Homepage = "https://github.com/reporterplus/pytest-html-plus"
37
37
  urls.Source = "https://github.com/reporterplus/pytest-html-plus"
38
38
  urls.Tracker = "https://github.com/reporterplus/pytest-html-plus/issues"
39
39
  urls.Documentation = "https://pytest-html-plus.readthedocs.io"
40
+ urls.Changelog = "https://github.com/reporterplus/pytest-html-plus/blob/main/CHANGELOG.md"
40
41
 
41
42
  [tool.poetry.dependencies]
42
43
  python = ">=3.10,<4.0"
43
44
  yagmail = ">=0.15.293,<0.16.0"
44
45
  keyring = ">=25.6.0,<26.0.0"
46
+ tomli = { version = ">=2.0.1,<3.0.0", python = "<3.11" }
45
47
 
46
48
  [tool.poetry.group.dev.dependencies]
47
49
  pytest-rerunfailures = "^15.1"
@@ -64,6 +66,15 @@ build-backend = "poetry.core.masonry.api"
64
66
  [tool.poetry.plugins."pytest11"]
65
67
  pytest_html_plus = "pytest_html_plus.plugin"
66
68
 
69
+ [tool.pytest-html-plus.profiles.ci]
70
+ generate-xml = true
71
+ xml-report = "final_xml_ci.xml"
72
+
73
+ [tool.pytest-html-plus.profiles.ci-warnings]
74
+ generate-xml = true
75
+ xml-report = "final_xml_ci_warnings.xml"
76
+ html-output = "report_output_warnings"
77
+
67
78
  [tool.ruff]
68
79
  line-length = 88
69
80
  target-version = "py39"
@@ -84,4 +95,4 @@ select = [
84
95
  "I", # isort
85
96
  "UP", # pyupgrade
86
97
  ]
87
- ignore = []
98
+ ignore = []
@@ -4,7 +4,6 @@ import json
4
4
  import os
5
5
  import shutil
6
6
  from datetime import datetime, timezone
7
- from sys import path
8
7
 
9
8
  from pytest_html_plus.compute_filter_counts import compute_filter_count
10
9
  from pytest_html_plus.utils import extract_error_block, extract_trace_block
@@ -9,6 +9,11 @@ from pathlib import Path
9
9
 
10
10
  import pytest
11
11
 
12
+ try:
13
+ import tomllib
14
+ except ModuleNotFoundError: # pragma: no cover - Python < 3.11
15
+ import tomli as tomllib
16
+
12
17
  from pytest_html_plus.compute_report_metadata import write_plus_metadata_if_main_worker
13
18
  from pytest_html_plus.extract_link import extract_links_from_item
14
19
  from pytest_html_plus.generate_html_report import JSONReporter
@@ -24,6 +29,21 @@ from pytest_html_plus.utils import (
24
29
 
25
30
  python_executable = shutil.which("python3") or shutil.which("python")
26
31
  test_screenshot_paths = {}
32
+ PROFILE_OPTION = "--plus-profile"
33
+ PROFILE_SECTION = ("tool", "pytest-html-plus", "profiles")
34
+ PROFILE_OPTION_MAP = {
35
+ "json-report": {"flag": "--json-report", "kind": "value"},
36
+ "capture-screenshots": {"flag": "--capture-screenshots", "kind": "value"},
37
+ "html-output": {"flag": "--html-output", "kind": "value"},
38
+ "screenshots": {"flag": "--screenshots", "kind": "value"},
39
+ "plus-email": {"flag": "--plus-email", "kind": "bool"},
40
+ "should-open-report": {"flag": "--should-open-report", "kind": "value"},
41
+ "generate-xml": {"flag": "--generate-xml", "kind": "bool"},
42
+ "xml-report": {"flag": "--xml-report", "kind": "value"},
43
+ "git-branch": {"flag": "--git-branch", "kind": "value"},
44
+ "git-commit": {"flag": "--git-commit", "kind": "value"},
45
+ "rp-env": {"flag": "--rp-env", "kind": "value"},
46
+ }
27
47
 
28
48
 
29
49
  logger = logging.getLogger()
@@ -36,6 +56,136 @@ if not logger.handlers:
36
56
  logger.addHandler(handler)
37
57
 
38
58
 
59
+ def _normalize_profile_key(key):
60
+ return key.replace("_", "-")
61
+
62
+
63
+ def _find_pyproject_toml(start_path=None):
64
+ current = Path(start_path or Path.cwd()).resolve()
65
+ for candidate in (current, *current.parents):
66
+ pyproject_file = candidate / "pyproject.toml"
67
+ if pyproject_file.exists():
68
+ return pyproject_file
69
+ return None
70
+
71
+
72
+ def _read_profiles_from_pyproject(start_path=None):
73
+ pyproject_file = _find_pyproject_toml(start_path=start_path)
74
+ if pyproject_file is None:
75
+ raise pytest.UsageError(
76
+ f"{PROFILE_OPTION} requires a pyproject.toml file in the current "
77
+ "directory or a parent directory"
78
+ )
79
+
80
+ try:
81
+ with pyproject_file.open("rb") as fh:
82
+ pyproject_data = tomllib.load(fh)
83
+ except tomllib.TOMLDecodeError as exc:
84
+ raise pytest.UsageError(f"Invalid TOML in {pyproject_file}: {exc}") from exc
85
+
86
+ profiles = pyproject_data
87
+ for section in PROFILE_SECTION:
88
+ profiles = profiles.get(section, {})
89
+
90
+ if not isinstance(profiles, dict):
91
+ raise pytest.UsageError(
92
+ f"Expected [{'.'.join(PROFILE_SECTION)}] to be a TOML table"
93
+ )
94
+
95
+ return profiles
96
+
97
+
98
+ def _build_profile_args(profile_name, start_path=None):
99
+ profiles = _read_profiles_from_pyproject(start_path=start_path)
100
+ profile = profiles.get(profile_name)
101
+
102
+ if profile is None:
103
+ available_profiles = ", ".join(sorted(profiles)) or "none"
104
+ raise pytest.UsageError(
105
+ f"Unknown profile '{profile_name}' for {PROFILE_OPTION}. "
106
+ f"Available profiles: {available_profiles}"
107
+ )
108
+
109
+ if not isinstance(profile, dict):
110
+ raise pytest.UsageError(
111
+ f"Profile '{profile_name}' must be defined as a TOML table"
112
+ )
113
+
114
+ profile_args = []
115
+ invalid_keys = []
116
+
117
+ for raw_key, value in profile.items():
118
+ key = _normalize_profile_key(raw_key)
119
+ option = PROFILE_OPTION_MAP.get(key)
120
+
121
+ if option is None:
122
+ invalid_keys.append(raw_key)
123
+ continue
124
+
125
+ if option["kind"] == "bool":
126
+ if not isinstance(value, bool):
127
+ raise pytest.UsageError(
128
+ f"Profile '{profile_name}' option '{raw_key}' must be true or false"
129
+ )
130
+ if value:
131
+ profile_args.append(option["flag"])
132
+ continue
133
+
134
+ if not isinstance(value, (str, int, float)):
135
+ raise pytest.UsageError(
136
+ f"Profile '{profile_name}' option '{raw_key}' "
137
+ "must be a string-like value"
138
+ )
139
+
140
+ profile_args.append(f"{option['flag']}={value}")
141
+
142
+ if invalid_keys:
143
+ valid_keys = ", ".join(sorted(PROFILE_OPTION_MAP))
144
+ invalid = ", ".join(sorted(invalid_keys))
145
+ raise pytest.UsageError(
146
+ f"Invalid key(s) in profile '{profile_name}': {invalid}. "
147
+ f"Valid keys: {valid_keys}"
148
+ )
149
+
150
+ return profile_args
151
+
152
+
153
+ def apply_plus_profile_args(args, start_path=None):
154
+ profile_name = None
155
+ remaining_args = []
156
+ skip_next = False
157
+
158
+ for index, arg in enumerate(args):
159
+ if skip_next:
160
+ skip_next = False
161
+ continue
162
+
163
+ if arg == PROFILE_OPTION:
164
+ if profile_name is not None:
165
+ raise pytest.UsageError(f"{PROFILE_OPTION} can only be specified once")
166
+ if index + 1 >= len(args):
167
+ raise pytest.UsageError(f"{PROFILE_OPTION} requires a profile name")
168
+ profile_name = args[index + 1]
169
+ skip_next = True
170
+ continue
171
+
172
+ if arg.startswith(f"{PROFILE_OPTION}="):
173
+ if profile_name is not None:
174
+ raise pytest.UsageError(f"{PROFILE_OPTION} can only be specified once")
175
+ profile_name = arg.split("=", 1)[1]
176
+ if not profile_name:
177
+ raise pytest.UsageError(f"{PROFILE_OPTION} requires a profile name")
178
+ continue
179
+
180
+ remaining_args.append(arg)
181
+
182
+ if not profile_name:
183
+ return list(args)
184
+
185
+ profile_args = _build_profile_args(profile_name, start_path=start_path)
186
+ return profile_args + remaining_args
187
+
188
+
39
189
  @pytest.hookimpl(tryfirst=True)
40
190
  def pytest_runtest_setup(item):
41
191
  if "caplog" not in item.fixturenames:
@@ -263,6 +413,7 @@ def pytest_sessionstart(session):
263
413
 
264
414
 
265
415
  def pytest_load_initial_conftests(args):
416
+ args[:] = apply_plus_profile_args(args, start_path=Path.cwd())
266
417
  if not any(arg.startswith("--capture") for arg in args):
267
418
  args.append("--capture=tee-sys")
268
419
 
@@ -270,6 +421,12 @@ def pytest_load_initial_conftests(args):
270
421
  def pytest_addoption(parser):
271
422
  group = parser.getgroup("pytest-html-plus", "pytest-html-plus reporting options")
272
423
 
424
+ group.addoption(
425
+ PROFILE_OPTION,
426
+ action="store",
427
+ default=None,
428
+ help="Load pytest-html-plus options from a named profile in pyproject.toml",
429
+ )
273
430
  group.addoption(
274
431
  "--json-report",
275
432
  action="store",
@@ -291,12 +448,6 @@ def pytest_addoption(parser):
291
448
  default=False,
292
449
  help="Send HTML test report via email after test run",
293
450
  )
294
- group.addoption(
295
- "--detect-flake",
296
- action="store",
297
- default=False,
298
- help="Helps capture flaky tests in the last n number of builds",
299
- )
300
451
  group.addoption(
301
452
  "--should-open-report",
302
453
  action="store",