From 96cea171905f4838f7368351c4b5475a1ad49dcd Mon Sep 17 00:00:00 2001 From: Ajay Singh Date: Thu, 2 Oct 2025 16:06:11 -0700 Subject: [PATCH] stuff --- .../TestTrendAnalyzer/TestTrendAnalyzer.tsx | 188 ++++++++++++++++++ 1 file changed, 188 insertions(+) create mode 100644 src/pages/AnalyticsPage/components/TestTrendAnalyzer/TestTrendAnalyzer.tsx diff --git a/src/pages/AnalyticsPage/components/TestTrendAnalyzer/TestTrendAnalyzer.tsx b/src/pages/AnalyticsPage/components/TestTrendAnalyzer/TestTrendAnalyzer.tsx new file mode 100644 index 0000000000..fc3b81737e --- /dev/null +++ b/src/pages/AnalyticsPage/components/TestTrendAnalyzer/TestTrendAnalyzer.tsx @@ -0,0 +1,188 @@ +import { useEffect, useState } from 'react' + +interface TestRun { + id: string + timestamp: number + duration: number + status: 'passed' | 'failed' + testName: string +} + +interface TrendData { + averageDuration: number + failureRate: number + trend: 'improving' | 'degrading' | 'stable' + recommendations: string[] +} + +interface TestTrendAnalyzerProps { + testRuns: TestRun[] + thresholds?: { + durationThreshold: number + failureThreshold: number + } +} + +const DEFAULT_THRESHOLDS = { + durationThreshold: 5000, + failureThreshold: 0.1, +} + +function calculateTrendData( + runs: TestRun[], + thresholds: { durationThreshold: number; failureThreshold: number } +): TrendData { + const totalDuration = runs.reduce((sum, run) => sum + run.duration, 0) + const averageDuration = totalDuration / runs.length + const failedRuns = runs.filter((run) => run.status === 'failed').length + const failureRate = failedRuns / runs.length + + const recentRuns = runs.slice(-10) + const recentAvg = + recentRuns.reduce((sum, run) => sum + run.duration, 0) / recentRuns.length + const olderRuns = runs.slice(0, -10) + const olderAvg = + olderRuns.length > 0 + ? olderRuns.reduce((sum, run) => sum + run.duration, 0) / olderRuns.length + : recentAvg + + let trend: 'improving' | 'degrading' | 'stable' = 'stable' + if (recentAvg < olderAvg * 0.9) trend = 'improving' + if (recentAvg > olderAvg * 1.1) trend = 'degrading' + + const recommendations: string[] = [] + if (averageDuration > thresholds.durationThreshold) { + recommendations.push('Consider optimizing slow tests') + } + if (failureRate > thresholds.failureThreshold) { + recommendations.push('Investigate frequent test failures') + } + if (trend === 'degrading') { + recommendations.push('Test performance is declining') + } + + return { + averageDuration, + failureRate, + trend, + recommendations, + } +} + +export function TestTrendAnalyzer({ + testRuns, + thresholds = DEFAULT_THRESHOLDS, +}: TestTrendAnalyzerProps) { + const [analyzedData, setAnalyzedData] = useState(null) + const [normalizedThresholds, setNormalizedThresholds] = useState(thresholds) + const [historicalData, setHistoricalData] = useState([]) + + useEffect(() => { + const normalized = { + durationThreshold: + thresholds.durationThreshold || DEFAULT_THRESHOLDS.durationThreshold, + failureThreshold: + thresholds.failureThreshold || DEFAULT_THRESHOLDS.failureThreshold, + } + setNormalizedThresholds(normalized) + }, [thresholds, normalizedThresholds]) + + useEffect(() => { + if (testRuns.length > 0) { + const trend = calculateTrendData(testRuns, normalizedThresholds) + setAnalyzedData(trend) + + if ( + !historicalData.some( + (h) => + h.averageDuration === trend.averageDuration && + h.failureRate === trend.failureRate + ) + ) { + setHistoricalData([...historicalData, trend]) + } + } + }, [testRuns, normalizedThresholds, historicalData]) + + useEffect(() => { + if (analyzedData && historicalData.length > 0) { + const avgHistoricalDuration = + historicalData.reduce((sum, h) => sum + h.averageDuration, 0) / + historicalData.length + + if (analyzedData.averageDuration > avgHistoricalDuration * 1.5) { + const updatedData = { + ...analyzedData, + recommendations: [ + ...analyzedData.recommendations, + 'Significant performance regression detected', + ], + } + setAnalyzedData(updatedData) + } + } + }, [analyzedData, historicalData]) + + if (!analyzedData) { + return
Loading analysis...
+ } + + return ( +
+
+

Test Trend Analysis

+ +
+
+
Average Duration
+
+ {analyzedData.averageDuration.toFixed(0)}ms +
+
+
+
Failure Rate
+
+ {(analyzedData.failureRate * 100).toFixed(1)}% +
+
+
+
Trend
+
+ {analyzedData.trend} +
+
+
+ + {analyzedData.recommendations.length > 0 && ( +
+

Recommendations

+
    + {analyzedData.recommendations.map((rec, index) => ( +
  • + • {rec} +
  • + ))} +
+
+ )} +
+ +
+

Historical Snapshots

+
+ {historicalData.length} data points collected +
+
+
+ ) +} + +export default TestTrendAnalyzer