Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@ Versions follow [Semantic Versioning](https://semver.org/).

_Changes merged to `main` but not yet released._

### Added

* Add --plus-no-html to skip generate HTML report.

---

## [1.2.0] — 2026-08-11
Expand Down
30 changes: 17 additions & 13 deletions docs/cli/cli.rst
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,14 @@ Overview
- **Description**
- **Default**
- **Use Case**
* - ``--plus-profile``
- Load a named profile from ``pyproject.toml``
- ``None``
- Reuse a standard reporting configuration across local runs and CI
* - ``--plus-output``
- Control which captured stdout/stderr streams are included in reports
- ``all``
- Reduce report size by omitting output from passing tests or all tests
* - ``--json-report``
- Name of the JSON report file generated alongside the HTML report
- ``final_report.json``
Expand All @@ -21,26 +29,22 @@ Overview
- When to capture screenshots
- ``failed``
- Useful in flaky UI tests to get screenshots on failure
* - ``--plus-output``
- Control which captured stdout/stderr streams are included in reports
- ``all``
- Reduce report size by omitting output from passing tests or all tests
* - ``--plus-no-html``
- Disable HTML report generation
- ``False``
- Useful when integrating. ``--plus-email`` will force HTML generation even if this flag is set
* - ``--html-output``
- Directory for HTML output
- ``report_output``
- Customize output directory per CI job
* - ``--plus-profile``
- Load a named profile from ``pyproject.toml``
- ``None``
- Reuse a standard reporting configuration across local runs and CI
* - ``--plus-email``
- Send HTML report via email
- ``False``
- Enable in scheduled test runs (nightly builds)
* - ``--should-open-report``
- Auto-open report after run
- ``failed``
- Open only when failures occur locally
* - ``--plus-email``
- Send HTML report via email
- ``False``
- Enable in scheduled test runs (nightly builds)
* - ``--generate-xml``
- Generate a combined XML for CI/coverage
- ``False``
Expand All @@ -49,7 +53,7 @@ Overview
- Path for XML report
- ``None``
- Useful when generating multiple output types
* - ``--env`` or ``--environment`` or ``--rp-env`
* - ``--env`` or ``--environment`` or ``--rp-env``
- Include environment variables in the execution metadata.
- Default: None
- Useful for adding CI or custom environment metadata (safe values only).
Expand Down
106 changes: 64 additions & 42 deletions pytest_html_plus/plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
"json-report": {"flag": "--json-report", "kind": "value"},
"capture-screenshots": {"flag": "--capture-screenshots", "kind": "value"},
"html-output": {"flag": "--html-output", "kind": "value"},
"plus-no-html": {"flag": "--plus-no-html", "kind": "bool"},
"screenshots": {"flag": "--screenshots", "kind": "value"},
"plus-email": {"flag": "--plus-email", "kind": "bool"},
"should-open-report": {"flag": "--should-open-report", "kind": "value"},
Expand Down Expand Up @@ -338,30 +339,35 @@ def pytest_sessionfinish(session, exitstatus):
output_path=json_path,
)

script_path = os.path.join(os.path.dirname(__file__), "generate_html_report.py")
if not os.path.exists(script_path):
logger.warning(
f"Report generation script not found at {script_path}. "
f"Skipping HTML report generation."
)
return
should_generate_html = session.config.getoption(
"--plus-email"
) or not session.config.getoption("--plus-no-html")

try:
subprocess.run(
[
sys.executable,
script_path,
"--report",
json_path,
"--screenshots",
screenshots_path,
"--output",
html_output,
],
check=True,
)
except Exception as e:
raise RuntimeError(f"Exception during HTML report generation: {e}") from e
if should_generate_html:
script_path = os.path.join(os.path.dirname(__file__), "generate_html_report.py")
if not os.path.exists(script_path):
logger.warning(
f"Report generation script not found at {script_path}. "
f"Skipping HTML report generation."
)
return

try:
subprocess.run(
[
sys.executable,
script_path,
"--report",
json_path,
"--screenshots",
screenshots_path,
"--output",
html_output,
],
check=True,
)
except Exception as e:
raise RuntimeError(f"Exception during HTML report generation: {e}") from e

# ---- Generate XML ----
if session.config.getoption("--generate-xml"):
Expand All @@ -387,12 +393,13 @@ def pytest_sessionfinish(session, exitstatus):
except Exception as e:
raise RuntimeError(f"Failed to send email: {e}") from e

# ---- Open report (controller only) ----
open_html_report(
report_path=os.path.join(html_output, "report.html"),
json_path=json_path,
config=session.config,
)
if should_generate_html:
# ---- Open report (controller only) ----
open_html_report(
report_path=os.path.join(html_output, "report.html"),
json_path=json_path,
config=session.config,
)


def pytest_sessionstart(session):
Expand Down Expand Up @@ -431,50 +438,63 @@ def pytest_load_initial_conftests(args):
def pytest_addoption(parser):
group = parser.getgroup("pytest-html-plus", "pytest-html-plus reporting options")

# General options
group.addoption(
PROFILE_OPTION,
action="store",
default=None,
help="Load pytest-html-plus options from a named profile in pyproject.toml",
)
group.addoption(
OUTPUT_OPTION,
action="store",
default="all",
choices=OUTPUT_CHOICES,
help=(
"Include captured stdout/stderr in reports: all (default), "
"failed-only, or none"
),
)
group.addoption(
"--json-report",
action="store",
default="final_report.json",
help="Name of the JSON report file generated alongside the HTML report",
)

# Screenshot options
group.addoption(
"--capture-screenshots",
action="store",
default="failed",
choices=["failed", "all", "none"],
help="Capture screenshots: failed (default), all, or none",
)
group.addoption(
OUTPUT_OPTION,
action="store",
default="all",
choices=OUTPUT_CHOICES,
help=(
"Include captured stdout/stderr in reports: all (default), "
"failed-only, or none"
),
)
group.addoption("--html-output", default="report_output")
group.addoption("--screenshots", default="screenshots")

# HTML options
group.addoption(
"--plus-email",

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Combining --plus-no-html with --plus-email silently disables email. Is this mentioned in the documentation? or do you suggest having validators in place for incompatible combinations?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To balance the impact of two options --plus-email force generate html may be good choice. I will fix this and mention this in doc.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would still feel lets not force generate, this will again come at a cost in time. I would prefer to keep in the docs that, if they have no html, --plus email will not work. --plus email is essentially just for emailing the html report so if they use --no-html then they are making a concious decision that it wont be available for email

"--plus-no-html",
action="store_true",
default=False,
help="Send HTML test report via email after test run",
help="Disable HTML report generation from the final JSON report",
)
group.addoption("--html-output", default="report_output")
group.addoption(
"--should-open-report",
action="store",
default="failed",
choices=["always", "failed", "never"],
help="When to open the HTML report: always, failed, or never (default: failed)",
)
group.addoption(
"--plus-email",
action="store_true",
default=False,
help="Send HTML test report via email after test run",
)

# XML options
group.addoption(
"--generate-xml",
action="store_true",
Expand All @@ -487,6 +507,8 @@ def pytest_addoption(parser):
default=None,
help="Name of the XML report file generated alongside the HTML report (used with --generate-xml)", # noqa
)

# Other options
group.addoption(
"--git-branch",
action="store",
Expand Down
Loading