From 94a6f2ecbb82a5e5d4e2498158b191fd74372c53 Mon Sep 17 00:00:00 2001 From: Georgi Hristov Date: Mon, 2 Nov 2026 09:55:58 +0200 Subject: [PATCH 1/6] refactor: remove request summary section from debug page --- .../Rendering/HtmlRendererTrendTests.cs | 193 ------------------ .../Assets/css/debugprobe.css | 57 ------ DebugProbe.AspNetCore/Assets/html/index.html | 25 --- .../Internal/Rendering/HtmlRenderer.cs | 98 +-------- 4 files changed, 1 insertion(+), 372 deletions(-) diff --git a/DebugProbe.AspNetCore.Tests/Rendering/HtmlRendererTrendTests.cs b/DebugProbe.AspNetCore.Tests/Rendering/HtmlRendererTrendTests.cs index 207e4df..7b22aac 100644 --- a/DebugProbe.AspNetCore.Tests/Rendering/HtmlRendererTrendTests.cs +++ b/DebugProbe.AspNetCore.Tests/Rendering/HtmlRendererTrendTests.cs @@ -11,199 +11,6 @@ namespace DebugProbe.AspNetCore.Tests.Rendering; public class HtmlRendererTrendTests { - [Fact] - public void Render_index_page_with_no_data_generates_flat_sparkline() - { - var html = HtmlRenderer.RenderIndexPage([], new DebugProbeOptions { TrendLookbackMinutes = 30 }); - - // Flat sparkline check: Y values should all be 14 - Assert.Contains("14", html); - Assert.Contains("trend-neutral", html); - Assert.Contains("→", html); - } - - [Fact] - public void Render_index_page_with_increased_errors_shows_trend_up() - { - var now = DateTimeOffset.UtcNow; - var options = new DebugProbeOptions { TrendLookbackMinutes = 10 }; - - var items = new List - { - // Preceding half: [now - 10m, now - 5m). 1 request, 0 errors -> 0% error rate. - new() { Id = "1", Timestamp = now.AddMinutes(-7), StatusCode = 200, Method = "GET", Path = "/api" }, - // Current half: [now - 5m, now]. 1 request, 1 error -> 100% error rate. - new() { Id = "2", Timestamp = now.AddMinutes(-2), StatusCode = 500, Method = "GET", Path = "/api" } - }; - - var html = HtmlRenderer.RenderIndexPage(items, options); - - Assert.Contains("trend-up", html); - Assert.Contains("↑", html); - } - - [Fact] - public void Render_index_page_with_decreased_errors_shows_trend_down() - { - var now = DateTimeOffset.UtcNow; - var options = new DebugProbeOptions { TrendLookbackMinutes = 10 }; - - var items = new List - { - // Preceding half: [now - 10m, now - 5m). 1 request, 1 error -> 100% error rate. - new() { Id = "1", Timestamp = now.AddMinutes(-7), StatusCode = 500, Method = "GET", Path = "/api" }, - // Current half: [now - 5m, now]. 1 request, 0 errors -> 0% error rate. - new() { Id = "2", Timestamp = now.AddMinutes(-2), StatusCode = 200, Method = "GET", Path = "/api" } - }; - - var html = HtmlRenderer.RenderIndexPage(items, options); - - Assert.Contains("trend-down", html); - Assert.Contains("↓", html); - } - - [Fact] - public void Render_index_page_with_unchanged_errors_shows_trend_neutral() - { - var now = DateTimeOffset.UtcNow; - var options = new DebugProbeOptions { TrendLookbackMinutes = 10 }; - - var items = new List - { - // Preceding half: [now - 10m, now - 5m). 1 request, 0 errors -> 0% error rate. - new() { Id = "1", Timestamp = now.AddMinutes(-7), StatusCode = 200, Method = "GET", Path = "/api" }, - // Current half: [now - 5m, now]. 1 request, 0 errors -> 0% error rate. - new() { Id = "2", Timestamp = now.AddMinutes(-2), StatusCode = 200, Method = "GET", Path = "/api" } - }; - - var html = HtmlRenderer.RenderIndexPage(items, options); - - Assert.Contains("trend-neutral", html); - Assert.Contains("→", html); - } - - [Fact] - public void Render_index_page_scenario_a_and_b_regression_test() - { - var options = new DebugProbeOptions { MaxEntries = 10, TrendLookbackMinutes = 2 }; - - var now = DateTimeOffset.UtcNow; - - // Scenario A: 8 successes at t = now - 90s, then 5 errors at t = now - 5s - // Since MaxEntries = 10, 3 successes are evicted. 5 successes remain in previous window, 5 errors in current. - // TotalB = 5 > 0, TotalA = 5 > 0. - var itemsA = new List(); - for (int i = 0; i < 5; i++) - { - itemsA.Add(new DebugEntry { Id = $"success-{i}", Timestamp = now.AddSeconds(-90), StatusCode = 200, Method = "GET", Path = "/api" }); - } - for (int i = 0; i < 5; i++) - { - itemsA.Add(new DebugEntry { Id = $"error-{i}", Timestamp = now.AddSeconds(-5), StatusCode = 500, Method = "GET", Path = "/api" }); - } - - // Expected: should show Trend Up (↑) because previous window is valid and error rate went up from 0% to 100% - var htmlA = HtmlRenderer.RenderIndexPage(itemsA, options); - Assert.Contains("trend-up", htmlA); - Assert.Contains("↑", htmlA); - - // Scenario B: 8 recovery successes are sent, evicting all baseline successes and some errors. - // Queue now has 8 recovery successes and 2 errors (all in current window). - // Previous window is empty (TotalB = 0). - var itemsB = new List(); - for (int i = 0; i < 2; i++) - { - itemsB.Add(new DebugEntry { Id = $"error-{i}", Timestamp = now.AddSeconds(-5), StatusCode = 500, Method = "GET", Path = "/api" }); - } - for (int i = 0; i < 8; i++) - { - itemsB.Add(new DebugEntry { Id = $"recovery-{i}", Timestamp = now.AddSeconds(-2), StatusCode = 200, Method = "GET", Path = "/api" }); - } - - // Expected: should show Trend Neutral (→) because previous window is empty - var htmlB = HtmlRenderer.RenderIndexPage(itemsB, options); - Assert.Contains("trend-neutral", htmlB); - Assert.Contains("→", htmlB); - } - - [Fact] - public void Render_index_page_previous_window_evicted_shows_neutral() - { - var options = new DebugProbeOptions { MaxEntries = 10, TrendLookbackMinutes = 2 }; - var items = new List(); - - var now = DateTimeOffset.UtcNow; - // All baseline entries from previous window are evicted. Previous window has 0 entries. - for (int i = 0; i < 10; i++) - { - items.Add(new DebugEntry { Id = $"recovery-{i}", Timestamp = now.AddSeconds(-2), StatusCode = 200, Method = "GET", Path = "/api" }); - } - - var html = HtmlRenderer.RenderIndexPage(items, options); - Assert.Contains("trend-neutral", html); - Assert.Contains("→", html); - } - - [Fact] - public void Render_index_page_previous_window_no_traffic_shows_neutral() - { - var options = new DebugProbeOptions { MaxEntries = 100, TrendLookbackMinutes = 2 }; - var items = new List(); - - var now = DateTimeOffset.UtcNow; - // Only 5 errors are sent now. No traffic occurred in the previous window. - for (int i = 0; i < 5; i++) - { - items.Add(new DebugEntry { Id = $"error-{i}", Timestamp = now.AddSeconds(-5), StatusCode = 500, Method = "GET", Path = "/api" }); - } - - var html = HtmlRenderer.RenderIndexPage(items, options); - Assert.Contains("trend-neutral", html); - Assert.Contains("→", html); - } - - [Fact] - public void Render_index_page_happy_path_with_no_eviction_flips_trend() - { - var options = new DebugProbeOptions { MaxEntries = 100, TrendLookbackMinutes = 2 }; - var store = new DebugEntryStore(options); - - var now = DateTimeOffset.UtcNow; - // Phase 1: 8 successes at t = now - 90s (previous window) - for (int i = 0; i < 8; i++) - { - store.Add(new DebugEntry { Id = $"success-{i}", Timestamp = now.AddSeconds(-90), StatusCode = 200, Method = "GET", Path = "/api" }); - } - - // Phase 2: 5 errors at t = now - 5s (current window) - for (int i = 0; i < 5; i++) - { - store.Add(new DebugEntry { Id = $"error-{i}", Timestamp = now.AddSeconds(-5), StatusCode = 500, Method = "GET", Path = "/api" }); - } - - var htmlErrors = HtmlRenderer.RenderIndexPage(store.GetAll(), options); - Assert.Contains("trend-up", htmlErrors); - Assert.Contains("↑", htmlErrors); - - store.Clear(); - - // Phase 3: 5 errors at t = now - 90s (previous window) - for (int i = 0; i < 5; i++) - { - store.Add(new DebugEntry { Id = $"error-{i}", Timestamp = now.AddSeconds(-90), StatusCode = 500, Method = "GET", Path = "/api" }); - } - - // Phase 4: 8 successes at t = now - 5s (current window) - for (int i = 0; i < 8; i++) - { - store.Add(new DebugEntry { Id = $"success-{i}", Timestamp = now.AddSeconds(-5), StatusCode = 200, Method = "GET", Path = "/api" }); - } - - var htmlRecovery = HtmlRenderer.RenderIndexPage(store.GetAll(), options); - Assert.Contains("trend-down", htmlRecovery); - Assert.Contains("↓", htmlRecovery); - } - [Fact] public void Options_validator_rejects_trend_lookback_less_than_two() { diff --git a/DebugProbe.AspNetCore/Assets/css/debugprobe.css b/DebugProbe.AspNetCore/Assets/css/debugprobe.css index eaf0ae6..5f9024d 100644 --- a/DebugProbe.AspNetCore/Assets/css/debugprobe.css +++ b/DebugProbe.AspNetCore/Assets/css/debugprobe.css @@ -75,59 +75,6 @@ h4 { margin-bottom: 14px; } -.stats-bar { - display: grid; - grid-template-columns: repeat(5, minmax(150px, 1fr)); - gap: 10px; - margin-bottom: 14px; -} - -.stat-tile { - display: flex; - align-items: center; - justify-content: center; - gap: 8px; - min-height: 52px; - padding: 0 16px; - background: #fff; - border: 1px solid #e9e9e9; - border-radius: 8px; - text-align: center; -} - -.stat-tile strong { - color: #1f2937; - font-size: 22px; - line-height: 1; -} - -.stat-tile span { - color: #666; - font-size: 13px; - font-weight: 700; - text-transform: uppercase; -} - -.trend-arrow { - display: inline-block; - font-size: 16px; - margin-left: 4px; - vertical-align: middle; - line-height: 1; -} - -.trend-up { - color: #e74c3c; -} - -.trend-down { - color: #27ae60; -} - -.trend-neutral { - color: #9ca3af; -} - .filters input, .filters select { @@ -687,10 +634,6 @@ tbody tr:last-child td { grid-template-columns: 1fr; } - .stats-bar { - grid-template-columns: repeat(2, minmax(0, 1fr)); - } - .compare-controls { grid-template-columns: 1fr; } diff --git a/DebugProbe.AspNetCore/Assets/html/index.html b/DebugProbe.AspNetCore/Assets/html/index.html index e330e94..19d6593 100644 --- a/DebugProbe.AspNetCore/Assets/html/index.html +++ b/DebugProbe.AspNetCore/Assets/html/index.html @@ -6,31 +6,6 @@

Requests

-
-
- {{total_requests}} - Requests -
-
- {{avg_response_time}} - Avg -
-
- {{slow_requests}} - Over 1s -
-
- {{error_rate}}{{error_trend}} - Errors -
-
-
- {{sparkline}} -
- Activity -
-
-