pytest-pulse-report
Python port of playwright-pulse — the same rich interactive dashboard, now for pytest-playwright (and plain pytest).
Features
| Feature | Description |
|---|---|
| Same JSON format | 100 % compatible with the JS reporter's output format |
| Interactive HTML report | Dark-themed dashboard with Highcharts charts |
| Self-contained static report | All assets embedded — share a single .html file |
| Email summary | Lightweight HTML email + optional full-report attachment |
| Step recording | @step decorator and pulse_step context manager |
| Severity & tags | @pytest.mark.pulse_severity / @pytest.mark.pulse_tag |
| Artifact collection | Auto-discovers screenshots / videos / traces from pytest-playwright |
| pytest-xdist | Each worker writes a shard; master merges them |
| Sequential runs | Accumulate reports across runs with --pulse-no-reset |
| AI Failure Analyzer | Client-side Claude / OpenAI analysis in the report |
| Trend history | Archive runs for historical charts |
Installation
pip install pytest-pulse-report
# Optional: image compression
pip install pytest-pulse-report[compression]
The plugin is auto-registered via the pytest11 entry point — no conftest.py changes needed.
Quick start
# Run your tests
pytest tests/ --pulse-output-dir=pulse-report
# Generate the interactive HTML report
generate-pulse-report
# Open pulse-report/playwright-pulse-static-report.html
Configuration
Command-line options
| Option | Default | Description |
|---|---|---|
--pulse-output-dir |
pulse-report |
Output directory |
--pulse-output-file |
playwright-pulse-report.json |
JSON filename |
--pulse-no-reset |
— | Accumulate reports across runs |
--pulse-individual-subdir |
pulse-results |
Sub-dir for individual run JSONs |
--pulse-description |
— | Custom text in report header |
--pulse-logo |
— | Path to a custom logo image |
pytest.ini / pyproject.toml
[pytest]
addopts = --pulse-output-dir=pulse-report --pulse-description="My CI Suite"
Step Recording
⚡ Super Easy Mode: The @step Decorator
The most efficient way to record steps, especially within Page Object Models (POM). No fixtures needed.
from pytest_pulse import step
class LoginPage:
def __init__(self, page):
self.page = page
@step("Login to Application")
def login(self, username, password):
self.enter_credentials(username, password)
self.submit_form()
@step("Enter Credentials")
def enter_credentials(self, username, password):
self.page.fill("#user", username)
self.page.fill("#pass", password)
@step("Submit Login Form")
def submit_form(self):
self.page.click("#login-button")
The pulse_step Context Manager
Ideal for wrapping specific blocks of code directly inside your test functions.
from pytest_pulse import pulse_step
def test_example(page):
with pulse_step("Navigate to Home Page"):
page.goto("https://example.com")
with pulse_step("Perform Search"):
page.fill("#search", "Playwright Pulse")
page.press("#search", "Enter")
with pulse_step("Verify Results"):
assert page.is_visible(".results-count")
Attaching Files with pulse_attach
You can manually attach any file (logs, CSVs, custom screenshots) to the test result using the pulse_attach fixture.
def test_export(page, pulse_attach):
page.click("#export-csv")
pulse_attach("/tmp/export.csv")
Markers
import pytest
@pytest.mark.pulse_severity("Critical") # Minor / Low / Medium / High / Critical
@pytest.mark.pulse_tag("smoke")
@pytest.mark.pulse_tag("regression")
@pytest.mark.pulse_annotation("jira", "PROJ-123")
def test_checkout(page, pulse_step):
with pulse_step("Go to checkout"):
page.goto("/checkout")
with pulse_step("Fill in payment"):
page.fill("#card", "4242424242424242")
with pulse_step("Submit order"):
page.click("#pay")
page.wait_for_url("**/confirmation")
CLI commands
| Command | Description |
|---|---|
generate-pulse-report |
Self-contained static HTML (all assets embedded) |
generate-report |
Dynamic HTML (references attachments/ dir) |
merge-pulse-report |
Merge sharded or sequential reports |
send-email |
Send report via SMTP |
generate-email-report |
Lightweight email summary HTML |
generate-trend |
Archive current run for trend history |
All commands accept --outputDir / -o flag.
Email sending
Set environment variables (supports .env files via python-dotenv):
PULSE_MAIL_HOST=gmail # gmail | outlook | smtp
PULSE_MAIL_USERNAME=you@gmail.com
PULSE_MAIL_PASSWORD=app_password
RECIPIENT_EMAIL_1=team@example.com
RECIPIENT_EMAIL_2=boss@example.com
send-email --attach-html
pytest-playwright integration
When pytest-playwright is installed, the plugin automatically:
- Detects the browser name from the
browser_namefixture / callspec params - Scans pytest-playwright's
--outputdirectory (default:test-results) for screenshots, videos and traces after each test - Copies and optionally compresses those artefacts into
pulse-report/attachments/
pytest tests/ --browser chromium --video on --screenshot on \
--pulse-output-dir=pulse-report
generate-pulse-report
pytest-xdist (parallel runs)
pytest tests/ -n 4 --pulse-output-dir=pulse-report
generate-pulse-report
Each worker writes a temporary shard file. The master process merges all shards at session end.
Sequential runs (--pulse-no-reset)
pytest tests/smoke/ --pulse-no-reset
pytest tests/regression/ --pulse-no-reset
merge-pulse-report # combines both into one report
generate-pulse-report
JSON report format
The output JSON is identical to the JS playwright-pulse format, so existing tooling (CI dashboards, the JS generate-pulse-report script, etc.) works without changes.
Github repository
Learning from the documentation or, the readme file sometimes is a big ask. So I have created this repository to serve as a quick reference for the users. Here is the link to the Github repository:
Author
Arghajit Singha — playwright-pulse
Metadata
Release files for pytest-pulse-report 1.0.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| pytest_pulse_report-1.0.1.tar.gz | 263.6 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| pytest_pulse_report-1.0.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 530.2 kB
Release files / pytest_pulse_report-1.0.1.tar.gz
| Download URL | pytest_pulse_report-1.0.1.tar.gz |
|---|---|
| Size | 263.6 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
4a7e5cead64fa82a18300273926ee7233d07f0d96b6c22657eaa4eee52460323
|
|
BLAKE2b-256 checksum How to use checksums |
bd2685835143a2d1c2473acfe2a8b16c43598e08dd901f0564563ef0fe99bfbc
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.14.4
|
Release files / pytest_pulse_report-1.0.1-py3-none-any.whl
| Download URL | pytest_pulse_report-1.0.1-py3-none-any.whl |
|---|---|
| Size | 266.6 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
b76314904ace40c89dd98528148b22dd75bc28a098a90cffb22232314b64b020
|
|
BLAKE2b-256 checksum How to use checksums |
9e0c19520210cbe10eedc0cf81f2e2627f952adeeaaf866bff4233bcf3e081c9
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.14.4
|