import React, { useState, useEffect, useRef, useCallback } from 'react'; import { Client } from '@stomp/stompjs'; import SockJS from 'sockjs-client'; import { Card, CardHeader, CardContent } from '@/components/ui/card'; import { ScrollArea } from '@/components/ui/scroll-area'; import { Button } from '@/components/ui/button'; import { Tabs, TabsList, TabsTrigger, TabsContent } from '@/components/ui/tabs'; import { cn } from '@/lib/utils'; import { useMonaco } from '@monaco-editor/react'; const LoadTestResult = ({ contextPath = '/', testId }) => { const [results, setResults] = useState([]); const [selectedResult, setSelectedResult] = useState(null); const [activeTab, setActiveTab] = useState('body'); const stompClientRef = useRef(null); const monaco = useMonaco(); const editorRef = useRef(null); useEffect(() => { // Initialize Monaco editor if (monaco && !editorRef.current) { editorRef.current = monaco.editor.create(document.getElementById('test-output'), { value: '', language: 'json', automaticLayout: true, readOnly: true, minimap: { enabled: false }, theme: 'vs-dark' }); } return () => { if (editorRef.current) { editorRef.current.dispose(); editorRef.current = null; } }; }, [monaco]); useEffect(() => { if (!testId) return; // Initialize WebSocket connection const socket = new SockJS(`${contextPath}load-test-result`); const client = new Client({ webSocketFactory: () => socket, onConnect: () => { client.subscribe(`/topic/${testId}`, (message) => { const result = JSON.parse(message.body); setResults(prev => [...prev, result]); }); }, onStompError: (error) => { console.error('STOMP error:', error); } }); stompClientRef.current = client; client.activate(); return () => { if (client.connected) { client.deactivate(); } }; }, [testId, contextPath]); const reset = useCallback(() => { setResults([]); setSelectedResult(null); if (editorRef.current) { editorRef.current.setValue(''); } }, []); const formatResponse = useCallback((response) => { if (!response) return ''; if (response.headers) { const sortedHeaders = Object.entries(response.headers) .sort(([a], [b]) => a.localeCompare(b)) .map(([key, value]) => `${key}: ${value}`) .join('\n'); return sortedHeaders; } try { return JSON.stringify(JSON.parse(response.body || '{}'), null, 2); } catch { return response.body || ''; } }, []); const handleResultSelect = useCallback((result) => { setSelectedResult(result); if (editorRef.current) { const content = result.type === 'TCP' ? `[TCP Response]\n${result.response.body}` : `[HTTP Response]\nStatus: ${result.response.status}\n\n[Headers]\n${formatResponse(result.response.headers)}\n\n[Body]\n${result.response.body}`; editorRef.current.setValue(content); } }, [formatResponse]); return (
{/* Results List */} Test Results
{results.map((result, index) => (
handleResultSelect(result)} className={cn( "p-2 rounded cursor-pointer hover:bg-accent", selectedResult === result && "bg-accent" )} >
{result.request.name}
Status: {result.response.status || 'N/A'}
))}
{/* Result Details */}
Result Details
Body Console
{results.map((result, index) => (
{`[${new Date(result.timestamp).toISOString()}] ${result.request.name}\n`} {`Status: ${result.response.status}\n`} {`Time: ${result.response.time}ms\n`} {`Size: ${result.response.size} bytes\n`} {'='.repeat(50)}
))}
); }; export default LoadTestResult;