Advanced Usage

Full Configuration

Configure the reporter via pytest.ini or command line arguments:

CLI Argument pytest.ini Key Default Description
--pulse-output-dir pulse_output_dir 'pulse-report' Root directory for all report assets.
--pulse-logo pulse_logo None Local path to a custom logo image.
--pulse-description pulse_description None Custom text to display in the report header.
--pulse-reset-on-each-run pulse_reset_on_each_run True If False, merges results from multiple pytest calls in the same directory.

Step Recording Guide

Pytest Pulse Report allows you to break down complex tests into logical, named steps. This significantly improves report readability and helps identify exactly where a test failed.

You can implement steps using either a static decorator or a context manager.

1. The @step Decorator

The most efficient way to record steps, especially within Page Object Models (POM). It automatically handles the step lifecycle and supports deep nesting.

  • Zero Fixture Boilerplate: No need to pass a pulse_step fixture into your methods.
  • Clean POMs: Keeps your Page Objects readable and focused on logic.
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")

2. The pulse_step Context Manager

Ideal for wrapping specific blocks of code directly inside your test functions or for ad-hoc step creation.

from pytest_pulse import pulse_step

def test_checkout_flow(page):
    with pulse_step("Search for Product"):
        page.fill("[placeholder='Search']", "iPhone 15")
        page.press("[placeholder='Search']", "Enter")

    with pulse_step("Add to Cart"):
        page.click("text=Add to cart")
        
    with pulse_step("Verify Cart"):
        assert page.is_visible(".cart-count")
💡 Pro Tip: You can nest decorators and context managers interchangeably. The reporter will automatically build the correct hierarchy in the dashboard.

CI/CD Workflow

# .github/workflows/pytest.yml
name: Pytest Tests
on: [push, pull_request]

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v4
    - name: Set up Python
      uses: actions/setup-python@v5
      with:
        python-version: '3.14'
    - name: Install dependencies
      run: |
        pip install pytest-pulse-report playwright
        playwright install --with-deps
    - name: Run tests
      run: pytest
    - name: Generate Report
      run: generate-pulse-report
    - uses: actions/upload-artifact@v4
      if: always()
      with:
        name: pulse-report
        path: pulse-report/

Handling Sequential Test Runs

To accumulate results from multiple pytest commands into a single report, disable reset_on_each_run.

# pytest.ini
[pytest]
addopts = --pulse-report --pulse-no-reset

This will store individual run data in pulse-results/ and automatically merge them into the master JSON on each run.

Test Severity Levels

Categorize your tests using the pulse_severity marker:

import pytest

@pytest.mark.pulse_severity("Critical")
def test_payment_gateway():
    # Critical business logic
    pass

@pytest.mark.pulse_severity("Minor")
def test_ui_typo():
    # Low priority fix
    pass

The dashboard will display a breakdown of these levels in the summary charts.