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
102 changes: 102 additions & 0 deletions src/agentunit/reporting/html.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
from __future__ import annotations

from html import escape
from typing import TYPE_CHECKING


if TYPE_CHECKING:
from agentunit.reporting.results import SuiteResult


def render_html_report(result: SuiteResult) -> str:
scenarios = result.scenarios

total_runs = sum(len(s.runs) for s in scenarios)
failed_runs = sum(1 for s in scenarios for r in s.runs if not r.success)
passed_runs = total_runs - failed_runs
duration = (result.finished_at - result.started_at).total_seconds()

scenario_rows: list[str] = []

for scenario in scenarios:
scenario_rows.append(
f"""
<tr>
<td>{escape(scenario.name)}</td>
<td>{scenario.success_rate:.2%}</td>
<td>{len(scenario.runs)}</td>
</tr>
"""
)

return f"""<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>AgentUnit Report</title>
<style>
body {{
font-family: system-ui, -apple-system, BlinkMacSystemFont, sans-serif;
padding: 24px;
}}
h1, h2 {{
margin-bottom: 0.5em;
}}
table {{
width: 100%;
border-collapse: collapse;
margin-top: 12px;
}}
th, td {{
border: 1px solid #ddd;
padding: 8px;
text-align: left;
}}
th {{
background-color: #f4f4f4;
}}
.bar {{
height: 18px;
margin: 6px 0;
}}
.passed {{
background-color: #4CAF50;
width: {passed_runs * 20}px;
}}
.failed {{
background-color: #F44336;
width: {failed_runs * 20}px;
Comment on lines +62 to +68
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot Dec 24, 2025

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Bar chart width calculation creates UX issues with larger test suites.

The fixed-pixel width calculation (passed_runs * 20px) causes horizontal scrolling when test suites have many runs. For example, a suite with 100 test runs produces 2000px-wide bars, making the report difficult to view. Consider using percentage-based widths or a capped maximum width with proportional scaling.

🔎 Proposed fix using percentage-based widths

Modify the CSS and HTML to use a container with proportional bars:

     .bar {{
-      height: 18px;
+      display: inline-block;
+      height: 20px;
       margin: 6px 0;
+      color: white;
+      padding: 2px 8px;
+      font-size: 0.85em;
     }}
+    .bar-container {{
+      display: flex;
+      width: 100%;
+      max-width: 600px;
+      margin: 12px 0;
+    }}
     .passed {{
       background-color: #4CAF50;
-      width: {passed_runs * 20}px;
     }}
     .failed {{
       background-color: #F44336;
-      width: {failed_runs * 20}px;
     }}

And update the HTML section:

 <h2>Summary</h2>
 <p>Passed: {passed_runs} · Failed: {failed_runs}</p>

-<div class="bar passed"></div>
-<div class="bar failed"></div>
+<div class="bar-container">
+  <div class="bar passed" style="flex: {passed_runs}">Passed: {passed_runs}</div>
+  <div class="bar failed" style="flex: {failed_runs}">Failed: {failed_runs}</div>
+</div>

This approach uses flexbox to proportionally distribute space and includes text labels within the bars.

Also applies to: 87-88

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

@anshiky73-svg pls fix this issue

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Seems like the humans are having a chat. I'll hop back into my burrow for now. If you need me again, just tag @coderabbitai in a new comment, and I'll come hopping out!

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.

ok i will fix this issue @aviralgarg05

}}
.meta {{
color: #555;
font-size: 0.9em;
}}
</style>
</head>

<body>

<h1>AgentUnit HTML Report</h1>
<p class="meta">
Duration: {duration:.2f}s · Total runs: {total_runs}
</p>

<h2>Summary</h2>
<p>Passed: {passed_runs} · Failed: {failed_runs}</p>

<div class="bar passed"></div>
<div class="bar failed"></div>

<h2>Scenarios</h2>
<table>
<tr>
<th>Name</th>
<th>Success rate</th>
<th>Runs</th>
</tr>
{"".join(scenario_rows)}
</table>

</body>
</html>
"""
12 changes: 12 additions & 0 deletions src/agentunit/reporting/results.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
from pathlib import Path
from typing import TYPE_CHECKING

from agentunit.reporting.html import render_html_report


if TYPE_CHECKING:
from collections.abc import Iterable
Expand Down Expand Up @@ -128,6 +130,16 @@ def to_junit(self, path: str | Path) -> Path:
tree.write(target, encoding="utf-8", xml_declaration=True)
return target

def to_html(self, path: str | Path) -> Path:
"""
Export results as a self-contained HTML report.
"""
target = Path(path)
target.parent.mkdir(parents=True, exist_ok=True)
html = render_html_report(self)
target.write_text(html, encoding="utf-8")
return target


def merge_results(results: Iterable[SuiteResult]) -> SuiteResult:
results = list(results)
Expand Down