apmt-reports 0.1.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.
- apmt_reports-0.1.0/MANIFEST.in +1 -0
- apmt_reports-0.1.0/PKG-INFO +136 -0
- apmt_reports-0.1.0/README.md +116 -0
- apmt_reports-0.1.0/pyproject.toml +33 -0
- apmt_reports-0.1.0/setup.cfg +4 -0
- apmt_reports-0.1.0/setup.py +18 -0
- apmt_reports-0.1.0/src/apmt_reports.egg-info/PKG-INFO +136 -0
- apmt_reports-0.1.0/src/apmt_reports.egg-info/SOURCES.txt +15 -0
- apmt_reports-0.1.0/src/apmt_reports.egg-info/dependency_links.txt +1 -0
- apmt_reports-0.1.0/src/apmt_reports.egg-info/entry_points.txt +2 -0
- apmt_reports-0.1.0/src/apmt_reports.egg-info/requires.txt +2 -0
- apmt_reports-0.1.0/src/apmt_reports.egg-info/top_level.txt +1 -0
- apmt_reports-0.1.0/src/pytest_apmt_reporter/__init__.py +188 -0
- apmt_reports-0.1.0/src/pytest_apmt_reporter/html_generator.py +62 -0
- apmt_reports-0.1.0/src/pytest_apmt_reporter/model.py +91 -0
- apmt_reports-0.1.0/src/pytest_apmt_reporter/plugin.py +245 -0
- apmt_reports-0.1.0/src/pytest_apmt_reporter/templates/report_template.html +1463 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
recursive-include src/pytest_apmt_reporter/templates *.html
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: apmt-reports
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: A premium, feature-rich, and beautiful automated testing HTML reporter for pytest, python, and playwright.
|
|
5
|
+
License: MIT
|
|
6
|
+
Classifier: Framework :: Pytest
|
|
7
|
+
Classifier: Programming Language :: Python :: 3
|
|
8
|
+
Classifier: Programming Language :: Python :: 3.8
|
|
9
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
10
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
11
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
12
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
13
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
14
|
+
Classifier: Operating System :: OS Independent
|
|
15
|
+
Classifier: Topic :: Software Development :: Testing
|
|
16
|
+
Requires-Python: >=3.8
|
|
17
|
+
Description-Content-Type: text/markdown
|
|
18
|
+
Requires-Dist: pytest>=7.0.0
|
|
19
|
+
Requires-Dist: jinja2>=3.0.0
|
|
20
|
+
|
|
21
|
+
# ⚡ pytest-apmt-reporter
|
|
22
|
+
|
|
23
|
+
`pytest-apmt-reporter` is a premium, feature-rich, and visually stunning automated testing HTML reporter for **Python**, **Pytest**, and **Playwright**. It is designed as a modern, high-fidelity alternative to Allure and Robot Framework, providing responsive layouts, glowing glassmorphic dark-mode dashboards, interactive SVG charts, expandable execution step logs, failure tracebacks, and seamlessly embedded Playwright screenshots.
|
|
24
|
+
|
|
25
|
+
## ✨ Features
|
|
26
|
+
|
|
27
|
+
- **🔌 True Plug-and-Play (Auto-Detect):** By hooking directly into standard pytest entry points, the reporter is automatically active the moment you `pip install` it. No configuration changes required!
|
|
28
|
+
- **🌐 100% Offline-First (Self-Contained):** The final report compiles all layout, styles (CSS), logic (JS), and screenshots (base64 encoded PNGs) into a **single, standalone HTML file**. It requires absolutely zero Internet connection or CDNs to load, making it perfect for secure environments or CI/CD artifacts.
|
|
29
|
+
- **🎨 Premium Visual Dashboard:** Designed with premium glassmorphism card layouts, smooth transition animations, sleek dark mode (with a light theme toggle), and neon indicators for passed/failed tests.
|
|
30
|
+
- **📊 Interactive SVG Charts:** Includes clean, responsive circular progress indicators and data distributions drawn directly via SVG and animated with vanilla JS—no heavy charting libraries (like Chart.js) needed.
|
|
31
|
+
- **📸 Auto Playwright Failure screenshots:** If a test case utilizes a Playwright `page` fixture and fails, the reporter **automatically captures and embeds** a failure screenshot inside the report.
|
|
32
|
+
- **📝 Hierarchical Step Logging:** Allows defining nested execution steps using either standard decorators (`@apmt.step`) or context managers (`with apmt.step`), mirroring Allure and Robot Framework.
|
|
33
|
+
- **📎 Multi-format Attachments:** Programmatically attach raw logs, JSON blobs, HTML widgets, and custom screenshots to any step or stage.
|
|
34
|
+
|
|
35
|
+
---
|
|
36
|
+
|
|
37
|
+
## 🚀 Installation
|
|
38
|
+
|
|
39
|
+
You can easily install the reporter directly into your Python virtual environment from your project directory:
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
# Clone the repository and install in editable mode
|
|
43
|
+
pip install -e .
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
---
|
|
47
|
+
|
|
48
|
+
## 🛠️ Usage
|
|
49
|
+
|
|
50
|
+
Once installed, running pytest will automatically enable the reporter and generate a file named `report.html` in your working directory.
|
|
51
|
+
|
|
52
|
+
### Basic Commands
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
# Run pytest tests and generate the report with default parameters
|
|
56
|
+
pytest
|
|
57
|
+
|
|
58
|
+
# Specify a custom report name or output directory
|
|
59
|
+
pytest --apmt-html=outputs/custom_dashboard.html
|
|
60
|
+
|
|
61
|
+
# Provide a custom title for your report dashboard
|
|
62
|
+
pytest --apmt-title="E2E Portal Smoketests"
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
---
|
|
66
|
+
|
|
67
|
+
## 📝 Code API Examples
|
|
68
|
+
|
|
69
|
+
### 1. Step-by-Step Logging
|
|
70
|
+
|
|
71
|
+
Organize your test cases into nested, readable, and timed blocks:
|
|
72
|
+
|
|
73
|
+
```python
|
|
74
|
+
import pytest_apmt_reporter as apmt
|
|
75
|
+
|
|
76
|
+
# Using step decorator
|
|
77
|
+
@apmt.step("Authenticate credentials")
|
|
78
|
+
def login(username, password):
|
|
79
|
+
...
|
|
80
|
+
|
|
81
|
+
def test_user_purchase_flow():
|
|
82
|
+
# Using step context manager
|
|
83
|
+
with apmt.step("Initialize customer basket"):
|
|
84
|
+
basket_id = 9988
|
|
85
|
+
|
|
86
|
+
login("test_user", "password123")
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
### 2. Attaching Screenshots and Metadata
|
|
90
|
+
|
|
91
|
+
Enrich your reports with logs, JSON responses, or manual Playwright screenshots:
|
|
92
|
+
|
|
93
|
+
```python
|
|
94
|
+
import pytest_apmt_reporter as apmt
|
|
95
|
+
|
|
96
|
+
def test_payment_gateway_api():
|
|
97
|
+
# Attach plain text logs
|
|
98
|
+
apmt.attach("Connecting to stripe sandbox...", name="Stripe API Connection")
|
|
99
|
+
|
|
100
|
+
# Attach JSON payload
|
|
101
|
+
apmt.attach('{"id": "ch_3M4", "status": "succeeded"}', name="Stripe Response", attachment_type=apmt.AttachmentType.JSON)
|
|
102
|
+
|
|
103
|
+
def test_dashboard_visual(page):
|
|
104
|
+
# Capture and attach a playwright page screenshot manually
|
|
105
|
+
page.goto("https://admin.portal.local")
|
|
106
|
+
apmt.attach_screenshot(page, name="Dashboard Main Panel")
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
### 3. Custom Dashboard Environment Stats
|
|
110
|
+
|
|
111
|
+
Display important execution parameters (like environment, server names, CI build IDs) directly on the metrics header:
|
|
112
|
+
|
|
113
|
+
```python
|
|
114
|
+
import pytest_apmt_reporter as apmt
|
|
115
|
+
|
|
116
|
+
def test_initialize():
|
|
117
|
+
apmt.set_environment_info("Environment", "Staging-US-East")
|
|
118
|
+
apmt.set_environment_info("Release Version", "v4.12.0-rc2")
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
---
|
|
122
|
+
|
|
123
|
+
## 📊 Try the Demo
|
|
124
|
+
|
|
125
|
+
Run the pre-configured demo test suite in the repository to see all features in action:
|
|
126
|
+
|
|
127
|
+
```bash
|
|
128
|
+
# Run the demo tests
|
|
129
|
+
pytest demo/test_playwright_demo.py --apmt-html=demo_report.html
|
|
130
|
+
|
|
131
|
+
# Open the beautiful dashboard!
|
|
132
|
+
# Windows (PowerShell):
|
|
133
|
+
Start-Process demo_report.html
|
|
134
|
+
# macOS/Linux:
|
|
135
|
+
open demo_report.html
|
|
136
|
+
```
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
# ⚡ pytest-apmt-reporter
|
|
2
|
+
|
|
3
|
+
`pytest-apmt-reporter` is a premium, feature-rich, and visually stunning automated testing HTML reporter for **Python**, **Pytest**, and **Playwright**. It is designed as a modern, high-fidelity alternative to Allure and Robot Framework, providing responsive layouts, glowing glassmorphic dark-mode dashboards, interactive SVG charts, expandable execution step logs, failure tracebacks, and seamlessly embedded Playwright screenshots.
|
|
4
|
+
|
|
5
|
+
## ✨ Features
|
|
6
|
+
|
|
7
|
+
- **🔌 True Plug-and-Play (Auto-Detect):** By hooking directly into standard pytest entry points, the reporter is automatically active the moment you `pip install` it. No configuration changes required!
|
|
8
|
+
- **🌐 100% Offline-First (Self-Contained):** The final report compiles all layout, styles (CSS), logic (JS), and screenshots (base64 encoded PNGs) into a **single, standalone HTML file**. It requires absolutely zero Internet connection or CDNs to load, making it perfect for secure environments or CI/CD artifacts.
|
|
9
|
+
- **🎨 Premium Visual Dashboard:** Designed with premium glassmorphism card layouts, smooth transition animations, sleek dark mode (with a light theme toggle), and neon indicators for passed/failed tests.
|
|
10
|
+
- **📊 Interactive SVG Charts:** Includes clean, responsive circular progress indicators and data distributions drawn directly via SVG and animated with vanilla JS—no heavy charting libraries (like Chart.js) needed.
|
|
11
|
+
- **📸 Auto Playwright Failure screenshots:** If a test case utilizes a Playwright `page` fixture and fails, the reporter **automatically captures and embeds** a failure screenshot inside the report.
|
|
12
|
+
- **📝 Hierarchical Step Logging:** Allows defining nested execution steps using either standard decorators (`@apmt.step`) or context managers (`with apmt.step`), mirroring Allure and Robot Framework.
|
|
13
|
+
- **📎 Multi-format Attachments:** Programmatically attach raw logs, JSON blobs, HTML widgets, and custom screenshots to any step or stage.
|
|
14
|
+
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
## 🚀 Installation
|
|
18
|
+
|
|
19
|
+
You can easily install the reporter directly into your Python virtual environment from your project directory:
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
# Clone the repository and install in editable mode
|
|
23
|
+
pip install -e .
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
---
|
|
27
|
+
|
|
28
|
+
## 🛠️ Usage
|
|
29
|
+
|
|
30
|
+
Once installed, running pytest will automatically enable the reporter and generate a file named `report.html` in your working directory.
|
|
31
|
+
|
|
32
|
+
### Basic Commands
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
# Run pytest tests and generate the report with default parameters
|
|
36
|
+
pytest
|
|
37
|
+
|
|
38
|
+
# Specify a custom report name or output directory
|
|
39
|
+
pytest --apmt-html=outputs/custom_dashboard.html
|
|
40
|
+
|
|
41
|
+
# Provide a custom title for your report dashboard
|
|
42
|
+
pytest --apmt-title="E2E Portal Smoketests"
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
---
|
|
46
|
+
|
|
47
|
+
## 📝 Code API Examples
|
|
48
|
+
|
|
49
|
+
### 1. Step-by-Step Logging
|
|
50
|
+
|
|
51
|
+
Organize your test cases into nested, readable, and timed blocks:
|
|
52
|
+
|
|
53
|
+
```python
|
|
54
|
+
import pytest_apmt_reporter as apmt
|
|
55
|
+
|
|
56
|
+
# Using step decorator
|
|
57
|
+
@apmt.step("Authenticate credentials")
|
|
58
|
+
def login(username, password):
|
|
59
|
+
...
|
|
60
|
+
|
|
61
|
+
def test_user_purchase_flow():
|
|
62
|
+
# Using step context manager
|
|
63
|
+
with apmt.step("Initialize customer basket"):
|
|
64
|
+
basket_id = 9988
|
|
65
|
+
|
|
66
|
+
login("test_user", "password123")
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
### 2. Attaching Screenshots and Metadata
|
|
70
|
+
|
|
71
|
+
Enrich your reports with logs, JSON responses, or manual Playwright screenshots:
|
|
72
|
+
|
|
73
|
+
```python
|
|
74
|
+
import pytest_apmt_reporter as apmt
|
|
75
|
+
|
|
76
|
+
def test_payment_gateway_api():
|
|
77
|
+
# Attach plain text logs
|
|
78
|
+
apmt.attach("Connecting to stripe sandbox...", name="Stripe API Connection")
|
|
79
|
+
|
|
80
|
+
# Attach JSON payload
|
|
81
|
+
apmt.attach('{"id": "ch_3M4", "status": "succeeded"}', name="Stripe Response", attachment_type=apmt.AttachmentType.JSON)
|
|
82
|
+
|
|
83
|
+
def test_dashboard_visual(page):
|
|
84
|
+
# Capture and attach a playwright page screenshot manually
|
|
85
|
+
page.goto("https://admin.portal.local")
|
|
86
|
+
apmt.attach_screenshot(page, name="Dashboard Main Panel")
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
### 3. Custom Dashboard Environment Stats
|
|
90
|
+
|
|
91
|
+
Display important execution parameters (like environment, server names, CI build IDs) directly on the metrics header:
|
|
92
|
+
|
|
93
|
+
```python
|
|
94
|
+
import pytest_apmt_reporter as apmt
|
|
95
|
+
|
|
96
|
+
def test_initialize():
|
|
97
|
+
apmt.set_environment_info("Environment", "Staging-US-East")
|
|
98
|
+
apmt.set_environment_info("Release Version", "v4.12.0-rc2")
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
---
|
|
102
|
+
|
|
103
|
+
## 📊 Try the Demo
|
|
104
|
+
|
|
105
|
+
Run the pre-configured demo test suite in the repository to see all features in action:
|
|
106
|
+
|
|
107
|
+
```bash
|
|
108
|
+
# Run the demo tests
|
|
109
|
+
pytest demo/test_playwright_demo.py --apmt-html=demo_report.html
|
|
110
|
+
|
|
111
|
+
# Open the beautiful dashboard!
|
|
112
|
+
# Windows (PowerShell):
|
|
113
|
+
Start-Process demo_report.html
|
|
114
|
+
# macOS/Linux:
|
|
115
|
+
open demo_report.html
|
|
116
|
+
```
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=61.0.0", "wheel"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "apmt-reports"
|
|
7
|
+
version = "0.1.0"
|
|
8
|
+
description = "A premium, feature-rich, and beautiful automated testing HTML reporter for pytest, python, and playwright."
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
requires-python = ">=3.8"
|
|
11
|
+
license = {text = "MIT"}
|
|
12
|
+
classifiers = [
|
|
13
|
+
"Framework :: Pytest",
|
|
14
|
+
"Programming Language :: Python :: 3",
|
|
15
|
+
"Programming Language :: Python :: 3.8",
|
|
16
|
+
"Programming Language :: Python :: 3.9",
|
|
17
|
+
"Programming Language :: Python :: 3.10",
|
|
18
|
+
"Programming Language :: Python :: 3.11",
|
|
19
|
+
"Programming Language :: Python :: 3.12",
|
|
20
|
+
"License :: OSI Approved :: MIT License",
|
|
21
|
+
"Operating System :: OS Independent",
|
|
22
|
+
"Topic :: Software Development :: Testing",
|
|
23
|
+
]
|
|
24
|
+
dependencies = [
|
|
25
|
+
"pytest>=7.0.0",
|
|
26
|
+
"jinja2>=3.0.0",
|
|
27
|
+
]
|
|
28
|
+
|
|
29
|
+
[project.entry-points.pytest11]
|
|
30
|
+
apmt_reporter = "pytest_apmt_reporter.plugin"
|
|
31
|
+
|
|
32
|
+
[tool.setuptools.packages.find]
|
|
33
|
+
where = ["src"]
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
from setuptools import setup, find_packages
|
|
2
|
+
|
|
3
|
+
setup(
|
|
4
|
+
name="apmt-reports",
|
|
5
|
+
version="0.1.0",
|
|
6
|
+
package_dir={"": "src"},
|
|
7
|
+
packages=find_packages(where="src"),
|
|
8
|
+
include_package_data=True,
|
|
9
|
+
install_requires=[
|
|
10
|
+
"pytest>=7.0.0",
|
|
11
|
+
"jinja2>=3.0.0",
|
|
12
|
+
],
|
|
13
|
+
entry_points={
|
|
14
|
+
"pytest11": [
|
|
15
|
+
"apmt_reporter = pytest_apmt_reporter.plugin",
|
|
16
|
+
],
|
|
17
|
+
},
|
|
18
|
+
)
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: apmt-reports
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: A premium, feature-rich, and beautiful automated testing HTML reporter for pytest, python, and playwright.
|
|
5
|
+
License: MIT
|
|
6
|
+
Classifier: Framework :: Pytest
|
|
7
|
+
Classifier: Programming Language :: Python :: 3
|
|
8
|
+
Classifier: Programming Language :: Python :: 3.8
|
|
9
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
10
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
11
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
12
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
13
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
14
|
+
Classifier: Operating System :: OS Independent
|
|
15
|
+
Classifier: Topic :: Software Development :: Testing
|
|
16
|
+
Requires-Python: >=3.8
|
|
17
|
+
Description-Content-Type: text/markdown
|
|
18
|
+
Requires-Dist: pytest>=7.0.0
|
|
19
|
+
Requires-Dist: jinja2>=3.0.0
|
|
20
|
+
|
|
21
|
+
# ⚡ pytest-apmt-reporter
|
|
22
|
+
|
|
23
|
+
`pytest-apmt-reporter` is a premium, feature-rich, and visually stunning automated testing HTML reporter for **Python**, **Pytest**, and **Playwright**. It is designed as a modern, high-fidelity alternative to Allure and Robot Framework, providing responsive layouts, glowing glassmorphic dark-mode dashboards, interactive SVG charts, expandable execution step logs, failure tracebacks, and seamlessly embedded Playwright screenshots.
|
|
24
|
+
|
|
25
|
+
## ✨ Features
|
|
26
|
+
|
|
27
|
+
- **🔌 True Plug-and-Play (Auto-Detect):** By hooking directly into standard pytest entry points, the reporter is automatically active the moment you `pip install` it. No configuration changes required!
|
|
28
|
+
- **🌐 100% Offline-First (Self-Contained):** The final report compiles all layout, styles (CSS), logic (JS), and screenshots (base64 encoded PNGs) into a **single, standalone HTML file**. It requires absolutely zero Internet connection or CDNs to load, making it perfect for secure environments or CI/CD artifacts.
|
|
29
|
+
- **🎨 Premium Visual Dashboard:** Designed with premium glassmorphism card layouts, smooth transition animations, sleek dark mode (with a light theme toggle), and neon indicators for passed/failed tests.
|
|
30
|
+
- **📊 Interactive SVG Charts:** Includes clean, responsive circular progress indicators and data distributions drawn directly via SVG and animated with vanilla JS—no heavy charting libraries (like Chart.js) needed.
|
|
31
|
+
- **📸 Auto Playwright Failure screenshots:** If a test case utilizes a Playwright `page` fixture and fails, the reporter **automatically captures and embeds** a failure screenshot inside the report.
|
|
32
|
+
- **📝 Hierarchical Step Logging:** Allows defining nested execution steps using either standard decorators (`@apmt.step`) or context managers (`with apmt.step`), mirroring Allure and Robot Framework.
|
|
33
|
+
- **📎 Multi-format Attachments:** Programmatically attach raw logs, JSON blobs, HTML widgets, and custom screenshots to any step or stage.
|
|
34
|
+
|
|
35
|
+
---
|
|
36
|
+
|
|
37
|
+
## 🚀 Installation
|
|
38
|
+
|
|
39
|
+
You can easily install the reporter directly into your Python virtual environment from your project directory:
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
# Clone the repository and install in editable mode
|
|
43
|
+
pip install -e .
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
---
|
|
47
|
+
|
|
48
|
+
## 🛠️ Usage
|
|
49
|
+
|
|
50
|
+
Once installed, running pytest will automatically enable the reporter and generate a file named `report.html` in your working directory.
|
|
51
|
+
|
|
52
|
+
### Basic Commands
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
# Run pytest tests and generate the report with default parameters
|
|
56
|
+
pytest
|
|
57
|
+
|
|
58
|
+
# Specify a custom report name or output directory
|
|
59
|
+
pytest --apmt-html=outputs/custom_dashboard.html
|
|
60
|
+
|
|
61
|
+
# Provide a custom title for your report dashboard
|
|
62
|
+
pytest --apmt-title="E2E Portal Smoketests"
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
---
|
|
66
|
+
|
|
67
|
+
## 📝 Code API Examples
|
|
68
|
+
|
|
69
|
+
### 1. Step-by-Step Logging
|
|
70
|
+
|
|
71
|
+
Organize your test cases into nested, readable, and timed blocks:
|
|
72
|
+
|
|
73
|
+
```python
|
|
74
|
+
import pytest_apmt_reporter as apmt
|
|
75
|
+
|
|
76
|
+
# Using step decorator
|
|
77
|
+
@apmt.step("Authenticate credentials")
|
|
78
|
+
def login(username, password):
|
|
79
|
+
...
|
|
80
|
+
|
|
81
|
+
def test_user_purchase_flow():
|
|
82
|
+
# Using step context manager
|
|
83
|
+
with apmt.step("Initialize customer basket"):
|
|
84
|
+
basket_id = 9988
|
|
85
|
+
|
|
86
|
+
login("test_user", "password123")
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
### 2. Attaching Screenshots and Metadata
|
|
90
|
+
|
|
91
|
+
Enrich your reports with logs, JSON responses, or manual Playwright screenshots:
|
|
92
|
+
|
|
93
|
+
```python
|
|
94
|
+
import pytest_apmt_reporter as apmt
|
|
95
|
+
|
|
96
|
+
def test_payment_gateway_api():
|
|
97
|
+
# Attach plain text logs
|
|
98
|
+
apmt.attach("Connecting to stripe sandbox...", name="Stripe API Connection")
|
|
99
|
+
|
|
100
|
+
# Attach JSON payload
|
|
101
|
+
apmt.attach('{"id": "ch_3M4", "status": "succeeded"}', name="Stripe Response", attachment_type=apmt.AttachmentType.JSON)
|
|
102
|
+
|
|
103
|
+
def test_dashboard_visual(page):
|
|
104
|
+
# Capture and attach a playwright page screenshot manually
|
|
105
|
+
page.goto("https://admin.portal.local")
|
|
106
|
+
apmt.attach_screenshot(page, name="Dashboard Main Panel")
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
### 3. Custom Dashboard Environment Stats
|
|
110
|
+
|
|
111
|
+
Display important execution parameters (like environment, server names, CI build IDs) directly on the metrics header:
|
|
112
|
+
|
|
113
|
+
```python
|
|
114
|
+
import pytest_apmt_reporter as apmt
|
|
115
|
+
|
|
116
|
+
def test_initialize():
|
|
117
|
+
apmt.set_environment_info("Environment", "Staging-US-East")
|
|
118
|
+
apmt.set_environment_info("Release Version", "v4.12.0-rc2")
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
---
|
|
122
|
+
|
|
123
|
+
## 📊 Try the Demo
|
|
124
|
+
|
|
125
|
+
Run the pre-configured demo test suite in the repository to see all features in action:
|
|
126
|
+
|
|
127
|
+
```bash
|
|
128
|
+
# Run the demo tests
|
|
129
|
+
pytest demo/test_playwright_demo.py --apmt-html=demo_report.html
|
|
130
|
+
|
|
131
|
+
# Open the beautiful dashboard!
|
|
132
|
+
# Windows (PowerShell):
|
|
133
|
+
Start-Process demo_report.html
|
|
134
|
+
# macOS/Linux:
|
|
135
|
+
open demo_report.html
|
|
136
|
+
```
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
MANIFEST.in
|
|
2
|
+
README.md
|
|
3
|
+
pyproject.toml
|
|
4
|
+
setup.py
|
|
5
|
+
src/apmt_reports.egg-info/PKG-INFO
|
|
6
|
+
src/apmt_reports.egg-info/SOURCES.txt
|
|
7
|
+
src/apmt_reports.egg-info/dependency_links.txt
|
|
8
|
+
src/apmt_reports.egg-info/entry_points.txt
|
|
9
|
+
src/apmt_reports.egg-info/requires.txt
|
|
10
|
+
src/apmt_reports.egg-info/top_level.txt
|
|
11
|
+
src/pytest_apmt_reporter/__init__.py
|
|
12
|
+
src/pytest_apmt_reporter/html_generator.py
|
|
13
|
+
src/pytest_apmt_reporter/model.py
|
|
14
|
+
src/pytest_apmt_reporter/plugin.py
|
|
15
|
+
src/pytest_apmt_reporter/templates/report_template.html
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
pytest_apmt_reporter
|
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
import base64
|
|
2
|
+
import inspect
|
|
3
|
+
import threading
|
|
4
|
+
from typing import Any, Callable, List, Optional, Union
|
|
5
|
+
import functools
|
|
6
|
+
import time
|
|
7
|
+
|
|
8
|
+
from .model import TestCase, Step, Attachment, TestStage
|
|
9
|
+
|
|
10
|
+
# Thread-local state to track active test cases and step hierarchies
|
|
11
|
+
class APMTRuntimeState(threading.local):
|
|
12
|
+
def __init__(self):
|
|
13
|
+
self.active_test: Optional[TestCase] = None
|
|
14
|
+
self.active_stage_name: str = "call" # "setup", "call", "teardown"
|
|
15
|
+
self.step_stack: List[Step] = []
|
|
16
|
+
self.environment: dict = {}
|
|
17
|
+
|
|
18
|
+
state = APMTRuntimeState()
|
|
19
|
+
|
|
20
|
+
class AttachmentType:
|
|
21
|
+
TEXT = "text/plain"
|
|
22
|
+
HTML = "text/html"
|
|
23
|
+
JSON = "application/json"
|
|
24
|
+
PNG = "image/png"
|
|
25
|
+
JPG = "image/jpeg"
|
|
26
|
+
SVG = "image/svg+xml"
|
|
27
|
+
|
|
28
|
+
class StepContext:
|
|
29
|
+
def __init__(self, name: str):
|
|
30
|
+
self.name = name
|
|
31
|
+
self.step: Optional[Step] = None
|
|
32
|
+
|
|
33
|
+
def __enter__(self):
|
|
34
|
+
self.step = Step(name=self.name)
|
|
35
|
+
if state.step_stack:
|
|
36
|
+
# Nest within parent step
|
|
37
|
+
state.step_stack[-1].steps.append(self.step)
|
|
38
|
+
else:
|
|
39
|
+
# Add to active test stage
|
|
40
|
+
if state.active_test:
|
|
41
|
+
stage = state.active_test.stages[state.active_stage_name]
|
|
42
|
+
stage.steps.append(self.step)
|
|
43
|
+
# Also mirror to test flattend steps
|
|
44
|
+
state.active_test.steps.append(self.step)
|
|
45
|
+
|
|
46
|
+
state.step_stack.append(self.step)
|
|
47
|
+
return self.step
|
|
48
|
+
|
|
49
|
+
def __exit__(self, exc_type, exc_val, exc_tb):
|
|
50
|
+
if not self.step:
|
|
51
|
+
return False
|
|
52
|
+
|
|
53
|
+
status = "passed"
|
|
54
|
+
exception_msg = None
|
|
55
|
+
tb_str = None
|
|
56
|
+
|
|
57
|
+
if exc_type:
|
|
58
|
+
status = "failed"
|
|
59
|
+
exception_msg = f"{exc_type.__name__}: {str(exc_val)}"
|
|
60
|
+
import traceback
|
|
61
|
+
tb_str = "".join(traceback.format_exception(exc_type, exc_val, exc_tb))
|
|
62
|
+
|
|
63
|
+
self.step.finish(status=status, exception_message=exception_msg, traceback=tb_str)
|
|
64
|
+
|
|
65
|
+
if state.step_stack and state.step_stack[-1] == self.step:
|
|
66
|
+
state.step_stack.pop()
|
|
67
|
+
|
|
68
|
+
# Let exceptions bubble up
|
|
69
|
+
return False
|
|
70
|
+
|
|
71
|
+
def __call__(self, func: Callable) -> Callable:
|
|
72
|
+
@functools.wraps(func)
|
|
73
|
+
def wrapper(*args, **kwargs):
|
|
74
|
+
with StepContext(self.name):
|
|
75
|
+
return func(*args, **kwargs)
|
|
76
|
+
return wrapper
|
|
77
|
+
|
|
78
|
+
def step(name_or_func: Union[str, Callable]) -> Any:
|
|
79
|
+
"""Decorator or context manager for defining steps.
|
|
80
|
+
|
|
81
|
+
Usage as decorator:
|
|
82
|
+
@step("Perform login")
|
|
83
|
+
def login(user, password):
|
|
84
|
+
...
|
|
85
|
+
|
|
86
|
+
Usage as context manager:
|
|
87
|
+
with step("Perform login"):
|
|
88
|
+
...
|
|
89
|
+
"""
|
|
90
|
+
if isinstance(name_or_func, str):
|
|
91
|
+
return StepContext(name_or_func)
|
|
92
|
+
else:
|
|
93
|
+
# Direct decorator without name (use func name)
|
|
94
|
+
func = name_or_func
|
|
95
|
+
@functools.wraps(func)
|
|
96
|
+
def wrapper(*args, **kwargs):
|
|
97
|
+
step_name = func.__name__.replace('_', ' ').capitalize()
|
|
98
|
+
with StepContext(step_name):
|
|
99
|
+
return func(*args, **kwargs)
|
|
100
|
+
return wrapper
|
|
101
|
+
|
|
102
|
+
def attach(
|
|
103
|
+
body: Union[str, bytes],
|
|
104
|
+
name: str = "Attachment",
|
|
105
|
+
attachment_type: str = AttachmentType.TEXT
|
|
106
|
+
) -> None:
|
|
107
|
+
"""Attach data or files to the current running test case or step.
|
|
108
|
+
|
|
109
|
+
Args:
|
|
110
|
+
body: String content or binary bytes.
|
|
111
|
+
name: User-friendly name for the attachment.
|
|
112
|
+
attachment_type: MIME type of attachment (e.g. image/png, text/plain).
|
|
113
|
+
"""
|
|
114
|
+
if not state.active_test:
|
|
115
|
+
return # No active test running to attach to
|
|
116
|
+
|
|
117
|
+
is_base64 = False
|
|
118
|
+
content_str = ""
|
|
119
|
+
|
|
120
|
+
# Process content based on type
|
|
121
|
+
if isinstance(body, bytes):
|
|
122
|
+
if "image" in attachment_type or attachment_type in (AttachmentType.PNG, AttachmentType.JPG):
|
|
123
|
+
content_str = base64.b64encode(body).decode('utf-8')
|
|
124
|
+
is_base64 = True
|
|
125
|
+
else:
|
|
126
|
+
try:
|
|
127
|
+
content_str = body.decode('utf-8')
|
|
128
|
+
except UnicodeDecodeError:
|
|
129
|
+
content_str = base64.b64encode(body).decode('utf-8')
|
|
130
|
+
is_base64 = True
|
|
131
|
+
else:
|
|
132
|
+
content_str = str(body)
|
|
133
|
+
if attachment_type in (AttachmentType.PNG, AttachmentType.JPG):
|
|
134
|
+
# Already encoded base64 string
|
|
135
|
+
is_base64 = True
|
|
136
|
+
|
|
137
|
+
attachment = Attachment(name=name, content=content_str, mime_type=attachment_type, is_base64=is_base64)
|
|
138
|
+
|
|
139
|
+
# Add to active step if any, else active stage, else active test
|
|
140
|
+
if state.step_stack:
|
|
141
|
+
state.step_stack[-1].attachments.append(attachment)
|
|
142
|
+
else:
|
|
143
|
+
stage = state.active_test.stages[state.active_stage_name]
|
|
144
|
+
stage.attachments.append(attachment)
|
|
145
|
+
state.active_test.attachments.append(attachment)
|
|
146
|
+
|
|
147
|
+
def attach_screenshot(page: Any, name: str = "Screenshot") -> None:
|
|
148
|
+
"""Helper to attach a Playwright screenshot. Works with both Sync and Async pages.
|
|
149
|
+
|
|
150
|
+
Args:
|
|
151
|
+
page: Playwright Page instance.
|
|
152
|
+
name: Name of the screenshot attachment.
|
|
153
|
+
"""
|
|
154
|
+
# Check if page is sync or async
|
|
155
|
+
screenshot_func = getattr(page, "screenshot", None)
|
|
156
|
+
if not screenshot_func:
|
|
157
|
+
return
|
|
158
|
+
|
|
159
|
+
# Check if this is a coroutine function (async page)
|
|
160
|
+
if inspect.iscoroutinefunction(screenshot_func):
|
|
161
|
+
# We are inside sync code, so executing async is harder without direct await.
|
|
162
|
+
# But we can try to get the current running loop or advise using manual attach.
|
|
163
|
+
# However, many async tests run under pytest-asyncio, so we can run it in a thread/loop if possible,
|
|
164
|
+
# or grab the existing async context.
|
|
165
|
+
# A simpler fallback is to let the user know, or execute it safely:
|
|
166
|
+
try:
|
|
167
|
+
import asyncio
|
|
168
|
+
loop = asyncio.get_event_loop()
|
|
169
|
+
if loop.is_running():
|
|
170
|
+
# We are in a running loop, scheduled as a task.
|
|
171
|
+
# Since we can't block, we can schedule the capture, but the test might finish.
|
|
172
|
+
# For safety, let's advise capturing bytes and attaching:
|
|
173
|
+
# apmt.attach(await page.screenshot(), "name", apmt.AttachmentType.PNG)
|
|
174
|
+
# But let's try to block if we can, or log a warning.
|
|
175
|
+
pass
|
|
176
|
+
except Exception:
|
|
177
|
+
pass
|
|
178
|
+
else:
|
|
179
|
+
# Sync Playwright page - easy!
|
|
180
|
+
try:
|
|
181
|
+
screenshot_bytes = page.screenshot(type="png")
|
|
182
|
+
attach(screenshot_bytes, name=name, attachment_type=AttachmentType.PNG)
|
|
183
|
+
except Exception as e:
|
|
184
|
+
attach(f"Failed to capture screenshot: {str(e)}", name=f"{name} (Failed Capture)", attachment_type=AttachmentType.TEXT)
|
|
185
|
+
|
|
186
|
+
def set_environment_info(key: str, value: str) -> None:
|
|
187
|
+
"""Sets a global environment variable to be displayed on the report dashboard."""
|
|
188
|
+
state.environment[key] = str(value)
|