Skip to content
Merged
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
16 changes: 15 additions & 1 deletion src/openutm_verification/core/reporting/reporting.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
from loguru import logger

from openutm_verification.core.execution.config_models import AppConfig, ReportingConfig
from openutm_verification.core.flight_phase import FLIGHT_PHASE_LABELS
from openutm_verification.core.flight_phase import FLIGHT_PHASE_LABELS, FlightPhase
from openutm_verification.core.reporting._viz_engine import (
extract_step_payload,
label_from_step_id,
Expand Down Expand Up @@ -194,8 +194,22 @@ def _generate_html_report(report_data: ReportData, output_dir: Path, base_filena
loader=FileSystemLoader(template_dir),
autoescape=select_autoescape(enabled_extensions=("html", "xml"), default_for_string=True, default=True),
)
_phase_rank: dict[str, int] = {p.value: i for i, p in enumerate(FlightPhase)}

def _phase_groupby(steps: list[dict]) -> list[tuple[str, list[dict]]]:
"""Group steps by phase and return groups in canonical flight phase order."""
groups: dict[str, list[dict]] = {}
for step in steps:
phase = step.get("phase") or ""
groups.setdefault(phase, []).append(step)
return sorted(
groups.items(),
key=lambda item: _phase_rank.get(item[0], len(_phase_rank)),
)
Comment thread
atti92 marked this conversation as resolved.

env.filters["markdown"] = lambda text: markdown.markdown(text) if text else ""
env.filters["default_phase"] = lambda steps: [{**s, "phase": s.get("phase") or ""} for s in steps]
env.filters["phase_groupby"] = _phase_groupby
template = env.get_template("report_template.html")

html_content = template.render(
Expand Down
10 changes: 5 additions & 5 deletions src/openutm_verification/core/templates/report_template.html
Original file line number Diff line number Diff line change
Expand Up @@ -130,21 +130,21 @@ <h4>Documentation:</h4>
<h4>Steps:</h4>
{% set has_phases = result.steps | selectattr('phase') | list | length > 0 %}
{% if has_phases %}
{% for phase_group in result.steps | default_phase | groupby('phase') %}
{% for phase, steps in result.steps | default_phase | phase_groupby %}
{% set phase_index = loop.index %}
<div class="phase-group">
{% if phase_group.grouper %}
{% if phase %}
<div class="phase-header">
<span class="phase-badge">{{ phase_group.grouper }}</span>
{{ (phase_labels or {}).get(phase_group.grouper, phase_group.grouper) }}
<span class="phase-badge">{{ phase }}</span>
{{ (phase_labels or {}).get(phase, phase) }}
</div>
{% else %}
<div class="phase-header">Other Steps</div>
{% endif %}
<table class="steps-table">
<thead><tr><th>Step Name</th><th>Status</th><th>Duration (s)</th><th>Result</th></tr></thead>
<tbody>
{% for step in phase_group.list %}
{% for step in steps %}
{% set result_json = step.result | tojson(indent=2) %}
{% set line_count = result_json.split('\n') | length %}
<tr>
Expand Down
6 changes: 6 additions & 0 deletions tests/test_reporting_output.py
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,12 @@ def test_report_html_groups_steps_by_phase(tmp_path: Path):
assert "Stream telemetry" in html
assert "Cleanup" in html

# Phase headers must appear in canonical flight order: PRE FLIGHT -> CRUISE -> POST FLIGHT
pre_pos = html.index(">PRE FLIGHT<")
cruise_pos = html.index(">CRUISE<")
post_pos = html.index(">POST FLIGHT<")
assert pre_pos < cruise_pos < post_pos, "Phase groups must appear in canonical flight phase order"


def test_report_html_no_phases_renders_flat_table(tmp_path: Path):
app_config = _make_app_config(tmp_path)
Expand Down
Loading