Skip to main content

Behave Modern HTML Report

The modern, beautiful, single-file HTML report formatter for Behave. Dark mode, charts, instant search, attachments, zero external requests.

PyPI Python License: MIT CI

behave-modern-html-report is a drop-in formatter for Behave that produces a single, self-contained HTML file — everything (CSS, JS, icons, attachments) is embedded so the report works offline, on any machine, forever.

Features

  • 🌓 Dark / Light / Auto themes, modern Material-3 inspired UI
  • 📊 Interactive charts (status pie, duration histogram, slowest scenarios, tag pass rate, timeline) — pure vanilla JS, no Chart.js CDN
  • 🏷️ Tag analytics page: per-tag counts, pass rate, duration, and a dedicated chart
  • 📋 Gherkin Rules support: scenarios under a Rule are grouped and tagged correctly (Behave 1.3.x)
  • 🔍 Instant client-side search across features, scenarios, steps and tags
  • 🎚️ Filter by status with one click
  • 📁 Expandable features → scenarios → steps with rich metadata
  • 🧯 Modern error viewer with copy-to-clipboard tracebacks
  • 🖼️ Attachments: images (with lightbox), JSON, text, binaries
  • 🚀 Copy-reproduce-command per scenario (behave "features/example.feature:3")
  • 📊 Inline step duration bars to spot slow steps at a glance
  • ♿ Accessible: keyboard navigation, ARIA labels, reduced-motion support
  • 📦 Single HTML file, works offline, no web server, no CDN
  • 📌 Fixed sidebar navigation that stays in place while content scrolls
  • 🧩 Clean architecture — formatter / collector / models / renderer separation, fully testable
  • 🛠️ Extensible — custom CSS/JS, custom title/logo/company, JSON sidecar, future plugin system
  • 📋 Step catalog — static analysis formatter that extracts all step definitions with patterns, params, source and metrics

Installation

pip install behave-modern-html-report

Quick start

In your project's behave.ini (or setup.cfg / tox.ini with the same section):

[behave.formatters]
modern-html = behave_modern_html_report.formatter:ModernHTMLFormatter
steps-catalog = behave_modern_html_report.step_catalog_formatter:StepCatalogFormatter

Then run:

behave -f modern-html -o report.html

Open report.html in any browser. Done.

Useful variations

Run a single feature file:

behave -f modern-html -o report.html features/login.feature

Keep the console output while generating the report (Behave supports multiple formatters at once):

behave -f pretty -o /dev/null -f modern-html -o report.html

On Windows use NUL instead of /dev/null.

Configuration

All reporter options are read from behave's userdata section. Set them in behave.ini, setup.cfg, or via -D on the command line:

[behave.userdata]
bmr.title         = My Awesome Suite
bmr.company       = Acme Inc.
bmr.logo          = https://example.com/logo.svg
bmr.favicon       = https://example.com/favicon.ico
bmr.theme         = auto          ; auto | dark | light
bmr.primary_color = #3b82f6
bmr.accent_color  = #22c55e
bmr.default_view  = dashboard     ; dashboard | features | scenarios | ...
bmr.hidden_views    = rules,statistics
bmr.expand_by_default = false
bmr.max_slowest   = 10
bmr.show_copy_command = true
bmr.show_environment_vars = true
bmr.footer_text   = Build #12345
bmr.link_to_ci    = https://ci.example.com/build/12345
bmr.json_sidecar  = true          ; writes report.json next to report.html
bmr.custom_css    = path/to/extra.css
bmr.custom_js     = path/to/extra.js

Available options:

  • bmr.title — report title (default Behave Modern Report).
  • bmr.company — company name shown under the title.
  • bmr.logo / bmr.favicon — URL or base64 data URI for a logo/favicon.
  • bmr.theme — auto, dark or light.
  • bmr.primary_color / bmr.accent_color — override the report colors.
  • bmr.default_view — initial view (dashboard, features, rules, scenarios, results, tags, statistics, environment).
  • bmr.hidden_views — comma-separated views to hide (e.g. rules,statistics).
  • bmr.expand_by_default — expand all features, rules and scenarios on load (default false).
  • bmr.max_slowest — number of slowest scenarios on the dashboard (default 10).
  • bmr.show_copy_command — show the copy reproduce command button (default true).
  • bmr.show_environment_vars — show the environment variables card (default true).
  • bmr.footer_text — custom footer line.
  • bmr.link_to_ci — "View in CI" button URL.
  • bmr.json_sidecar — write report.json next to the HTML report (default false).
  • bmr.custom_css / bmr.custom_js — embed custom CSS/JS files (paths must be readable from where Behave runs).
  • bmr.steps_dir — directory to scan for step definitions when using the steps-catalog formatter (default features/steps).

Note: bmr.* options must be set in behave.ini or via -D — setting them from environment.py has no effect, because the formatter reads userdata when it is instantiated, before before_all runs.

Setting options from the command line

Use -D / --define to override any option without touching behave.ini:

behave -f modern-html -o report.html -D bmr.title="API Tests" -D bmr.theme=dark

Full example behave.ini

[behave]
format = modern-html
outfiles = report.html
show_skipped = true
show_timings = true

[behave.formatters]
modern-html = behave_modern_html_report.formatter:ModernHTMLFormatter

[behave.userdata]
bmr.title = My Suite
bmr.company = Acme Inc.
bmr.theme = auto
bmr.json_sidecar = true

Environment variables and secrets

The Environment view captures CI-related environment variables (prefixed CI, GITHUB, GITLAB, BITBUCKET, JENKINS, TRAVIS, CIRCLE, BUILD, AGENT, TF_, AZURE, plus PATH, HOME, USER, SHELL, LANG and TERM). Names containing TOKEN, SECRET, PASSWORD, PASSWD, CREDENTIAL, PRIVATE, AUTH, COOKIE, CERT, APIKEY, API_KEY or _KEY are automatically redacted as *** so secrets are never embedded into the report.

Behave 1.3.x and Gherkin Rules compatibility

behave-modern-html-report is tested against Behave 1.3.x and fully supports the Gherkin Rule keyword.

  • Scenarios under a Rule keep their parent rule name and inherit their Rule tags correctly.
  • Extended final statuses (error, hook_error, cleanup_error, xfailed, xpassed, pending_warn) are normalised and displayed in the UI.
  • Error-like statuses are grouped as failures for feature status and tag analytics.
Feature: Checkout

  Rule: Payment required
    @payment
    Scenario: Card payment succeeds
      Given the user has items in cart
      When they pay with a valid card
      Then the order is confirmed

Attachments from your environment.py

Use the public helper API — no need to reach into the formatter:

from behave_modern_html_report import attach_screenshot, attach_text, log

def after_step(context, step):
    if step.status == "failed":
        attach_screenshot(context, context.browser, name="failure.png")
        attach_text(context, str(step.exception), name="error.txt")
        log(context, f"URL at failure: {context.browser.current_url}")

The helpers also work with Playwright, Selenium, PIL images, bytes, files, and JSON data. Behave's native context.attach(mime_type, data) is captured too, via the formatter's embedding() hook.

Reminder: environment.py hooks must live inside features/ (Behave only loads features/environment.py), not at the project root.

Step Catalog

The package also includes a step catalog formatter that statically analyses your features/steps/ directory and produces an HTML catalog of all step definitions. Behave still executes the suite normally (the catalog ignores the test events) — add --dry-run if you only want the catalog.

Register it in behave.ini:

[behave.formatters]
steps-catalog = behave_modern_html_report.step_catalog_formatter:StepCatalogFormatter

Then run:

behave -f steps-catalog -o steps.html --dry-run

The catalog includes:

  • All @given, @when, @then and @step decorated functions.
  • Step pattern, function name, file path and line number.
  • Extracted parameters from {placeholder} patterns.
  • Function docstrings and source code snippets.
  • Metrics: total steps, by keyword, by file, parameterised, documented, regex.
  • Searchable, sortable table with keyword filters.
  • Detail panel showing the full source code of each step.

You can customise the steps directory with bmr.steps_dir:

[behave.userdata]
bmr.steps_dir = features/steps

Programmatic usage

from behave_modern_html_report import scan_directory
from behave_modern_html_report.step_catalog_formatter import render_catalog
from pathlib import Path

catalog = scan_directory(Path("features/steps"))
html = render_catalog(catalog, title="My Step Catalog")
Path("steps.html").write_text(html, encoding="utf-8")

Report views

The generated report is a single-page application with a sidebar navigation. Change the initial view with bmr.default_view and hide views with bmr.hidden_views.

  • Dashboard — high-level summary: totals, pass rate, status distribution, duration histogram, slowest scenarios, tag pass rate, error distribution, and a one-click summary for Slack or chat.
  • Features — all features with status badges, tags, description and duration. Expand a feature to see its scenarios; Compact/Detailed toggle shows or hides rule and scenario details.
  • Rules — all Gherkin Rule groups across every feature (Behave 1.3.x).
  • Scenarios — all scenarios as collapsible cards with steps, background steps, attachments, error traces and scenario outline banners.
  • Results — compact table of every scenario with status, feature, rule, duration and tags.
  • Tags — per-tag analytics: scenario count, pass rate with colour bars and accumulated duration.
  • Statistics — raw metrics: status distribution, duration percentiles, per-feature summary and error distribution by exception type.
  • Environment — host and runtime info captured at execution time: Python and Behave versions, platform, hostname, CPU, memory, git data, and CI environment variables (with secret redaction).

Examples

The repository includes two example projects under examples/.

Demo generator

examples/demo_generator/ builds a synthetic execution and renders it as HTML — useful for previews, screenshots and design iteration without a real suite:

python examples/demo_generator/generate_demo.py

Output: examples/demo_generator/demo-report.html.

Functional Behave project

examples/behave_project/ is a complete Behave project with features, steps, environment.py hooks, and behave.ini configured for the formatter:

cd examples/behave_project
pip install -r requirements.txt   # installs behave + this package (-e ../..)
behave                            # generates report.html

It exercises: backgrounds and scenario outlines, Gherkin Rule groups, passing/failing/skipped/undefined scenarios, attachments on failure, slow scenarios, and custom bmr.* userdata options. Run a subset with behave --tags=login|checkout|smoke.

Report screenshots

Report views (click to expand)

Dashboard view

Dashboard

Features view

Features

Rules view

Rules

Scenarios view

Scenarios

Results view

Results

Tags view

Tags

Statistics view

Statistics

Environment view

Environment

Step catalog

Step Catalog

Step detail panel

Step metrics

Architecture

behave-modern-html-report follows a strict layered architecture — each layer has a single responsibility and depends only on the layers above it:

┌──────────────────────────────────────────┐
│  formatter.py   (Behave adapter)         │  ← only this layer knows about Behave
├──────────────────────────────────────────┤
│  collector.py   (event → model builder)  │
├──────────────────────────────────────────┤
│  models.py      (pure dataclasses)       │  ← no I/O, no framework imports
│  statistics.py  (aggregations)           │
├──────────────────────────────────────────┤
│  renderer.py    (Jinja2 → single HTML)   │
│  assets.py      (CSS/JS bundling)        │
│  templates/     (HTML components)        │
│  assets/        (CSS / JS / icons)       │
└──────────────────────────────────────────┘

Data flow:

  1. Behave invokes the formatter for each feature/scenario/step result.
  2. The formatter delegates to a Collector, which builds an Execution tree of dataclasses.
  3. On close(), the formatter calls Collector.finalize() which runs statistics.compute() to derive aggregates.
  4. A Renderer loads Jinja2 templates and the bundled CSS/JS, embeds everything (and the execution as JSON for client-side rendering), and writes a single .html file.

Why it matters:

  • Testability — the collector accepts duck-typed stubs; the renderer accepts an Execution, so both can be tested without ever running Behave.
  • Reusability — anything that can build an Execution (e.g. a JSON loader) can render the same report.
  • Future-proofing — new outputs or plugins only touch one layer.

The renderer never references external URLs: CSS, JS, icons (inline SVG sprite), attachments (base64) and the execution payload are all embedded. The output file works offline forever.

Development

git clone https://github.com/MathiasPaulenko/behave-modern-html-report.git
cd behave-modern-html-report
python -m venv .venv
. .venv/Scripts/activate   # PowerShell: .venv\Scripts\Activate.ps1
pip install -e ".[dev]"
pytest
ruff check .

Or use the Makefile: make install-dev, make test, make lint, make format, make demo, make report.

See CONTRIBUTING.md for the full process, conventions and release steps, and SECURITY.md for the security policy.

License

MIT © Mathias Paulenko

Metadata

Release files for behave-modern-html-report 2.4.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for behave-modern-html-report 2.4.0
File Size Uploaded
behave_modern_html_report-2.4.0.tar.gz 164.9 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for behave-modern-html-report 2.4.0
File Interpreter ABI Platform
behave_modern_html_report-2.4.0-py3-none-any.whl Python 3 none any Details

Total release size: 232.2 kB

Release files / behave_modern_html_report-2.4.0.tar.gz

Download URL behave_modern_html_report-2.4.0.tar.gz
Size 164.9 kB
Tags Source
SHA-256 checksum
How to use checksums
793136d2ade766b10dcc71f3e0178c2ef984c50f124a8de2ad8d495102cb38be
BLAKE2b-256 checksum
How to use checksums
bc9ce65ffdf09af779eef8cad74905efbe7482aaffe34b502174106267170cf4
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 3, 2026.

Transparency log

Release files / behave_modern_html_report-2.4.0-py3-none-any.whl

Download URL behave_modern_html_report-2.4.0-py3-none-any.whl
Size 67.3 kB
Tags Python 3
SHA-256 checksum
How to use checksums
45d8a3181cc6532973bf338f1b330e776c3ab5f61db2b369cc59ba19ce8e7220
BLAKE2b-256 checksum
How to use checksums
b51ea4a8de33462768b81dbaf731dcb4e510b9973cd154ae04036ba9eaa7ce5b
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 3, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

2.4.0 This release

2 release files

2.3.0

2 release files

2.2.2

2 release files

2.2.1

2 release files

2.2.0

2 release files

2.1.0

2 release files

2.0.0

2 release files

1.0.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page