diff --git a/src/main/java/com/seleniumboot/reporting/HtmlReportGenerator.java b/src/main/java/com/seleniumboot/reporting/HtmlReportGenerator.java
index 7a6a012..6cfc7f7 100644
--- a/src/main/java/com/seleniumboot/reporting/HtmlReportGenerator.java
+++ b/src/main/java/com/seleniumboot/reporting/HtmlReportGenerator.java
@@ -185,6 +185,7 @@ static String buildTrendData(int maxRuns) {
: name);
run.put("passRate", n.path("passRate").asDouble(0));
run.put("failed", n.path("failedTests").asInt(0));
+ run.put("flakyTests", n.path("flakyTests").asInt(0));
long ms = n.path("suiteDurationMs").asLong(0);
run.put("durationSec", Math.round((ms > 0 ? ms : n.path("totalTimeMs").asLong(0)) / 100.0) / 10.0);
} catch (Exception ignored) {
diff --git a/src/main/resources/report-template.html b/src/main/resources/report-template.html
index d3bb0ae..08c7211 100644
--- a/src/main/resources/report-template.html
+++ b/src/main/resources/report-template.html
@@ -439,6 +439,10 @@
Selenium Boot Report
+
@@ -602,6 +606,7 @@ Selenium Boot Report
});
line('trendRateChart', 'Pass rate (%)', trendData.map(r => r.passRate), '#43a047', 100);
line('trendTimeChart', 'Duration (s)', trendData.map(r => r.durationSec), '#303f9f');
+ line('trendFlakyChart', 'Flaky tests', trendData.map(r => r.flakyTests), '#f57c00');
}
// ── Collapse / expand class groups ──
diff --git a/src/test/java/com/seleniumboot/reporting/HtmlReportGeneratorTest.java b/src/test/java/com/seleniumboot/reporting/HtmlReportGeneratorTest.java
index 8f3765e..ab36bf4 100644
--- a/src/test/java/com/seleniumboot/reporting/HtmlReportGeneratorTest.java
+++ b/src/test/java/com/seleniumboot/reporting/HtmlReportGeneratorTest.java
@@ -109,7 +109,7 @@ public void trendData_isChronological_andLimitedToLastRuns() throws Exception {
try {
for (int i = 1; i <= 3; i++) {
java.nio.file.Files.writeString(dir.resolve("selenium-boot-metrics-2026101" + i + "-10300" + i + ".json"),
- "{\"passRate\":" + (i * 30) + ".0,\"failedTests\":" + i + ",\"suiteDurationMs\":" + (i * 2000) + "}");
+ "{\"passRate\":" + (i * 30) + ".0,\"failedTests\":" + i + ",\"flakyTests\":" + i + ",\"suiteDurationMs\":" + (i * 2000) + "}");
}
java.nio.file.Files.writeString(dir.resolve("selenium-boot-metrics-20261019-103000.json"), "not json");
@@ -117,11 +117,14 @@ public void trendData_isChronological_andLimitedToLastRuns() throws Exception {
assertEquals(trend.size(), 1, "last 2 files taken, the unreadable one skipped");
assertEquals(trend.get(0).get("passRate").asDouble(), 90.0);
assertEquals(trend.get(0).get("durationSec").asDouble(), 6.0);
+ assertEquals(trend.get(0).get("flakyTests").asInt(), 3, "flakyTests carried into trend entry");
assertEquals(trend.get(0).get("label").asText(), "10-13 10:30");
JsonNode all = new ObjectMapper().readTree(HtmlReportGenerator.buildTrendData(20));
assertEquals(all.size(), 3);
assertEquals(all.get(0).get("passRate").asDouble(), 30.0, "oldest first");
+ assertEquals(all.get(0).get("flakyTests").asInt(), 1, "flakyTests on oldest run");
+ assertEquals(all.get(2).get("flakyTests").asInt(), 3, "flakyTests on newest run");
} finally {
System.clearProperty("seleniumboot.history.dir");
}