/
klischa
/
RuView
Обзор
Документация
Войти
/
klischa
/
RuView
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
ui/tests/integration-test.html
578 строк
23 KB
rUv
updates
07 июн 2025, 16:55
07 июн 2025, 16:55
7b5df5c
Код
Авторство
О чём код?
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>WiFi DensePose Integration Test</title> <link rel="stylesheet" href="../style.css"> <style> .test-controls { position: fixed; top: 20px; right: 20px; background: white; padding: 20px; border-radius: 8px; box-shadow: 0 4px 12px rgba(0,0,0,0.15); z-index: 1000; min-width: 250px; } .test-controls h3 { margin-top: 0; color: #333; } .test-button { display: block; width: 100%; margin-bottom: 10px; padding: 8px 16px; background: #007bff; color: white; border: none; border-radius: 4px; cursor: pointer; font-size: 14px; } .test-button:hover { background: #0056b3; } .test-button.danger { background: #dc3545; } .test-button.danger:hover { background: #c82333; } .test-status { margin-top: 15px; padding: 10px; border-radius: 4px; font-size: 12px; } .test-status.success { background: #d4edda; color: #155724; border: 1px solid #c3e6cb; } .test-status.error { background: #f8d7da; color: #721c24; border: 1px solid #f5c6cb; } .test-status.info { background: #d1ecf1; color: #0c5460; border: 1px solid #bee5eb; } .mock-indicator { position: fixed; bottom: 20px; right: 20px; background: #28a745; color: white; padding: 10px 15px; border-radius: 20px; font-size: 12px; font-weight: bold; z-index: 1000; } .mock-indicator.inactive { background: #6c757d; } </style> </head> <body> <!-- Test Controls Panel --> <div class="test-controls"> <h3>Integration Tests</h3> <button class="test-button" onclick="toggleMockMode()">Toggle Mock Mode</button> <button class="test-button" onclick="checkBackendStatus()">Check Backend Status</button> <button class="test-button" onclick="testHealthAPI()">Test Health API</button> <button class="test-button" onclick="testPoseAPI()">Test Pose API</button> <button class="test-button" onclick="testWebSocketStream()">Test WebSocket</button> <button class="test-button" onclick="testFullIntegration()">Full Integration Test</button> <button class="test-button" onclick="simulateErrors()">Simulate Errors</button> <div class="test-status" id="testStatus" style="display: none;"></div> </div> <!-- Mock Server Indicator --> <div class="mock-indicator inactive" id="mockIndicator">Mock Server: Offline</div> <!-- Main Application --> <div class="container"> <!-- Header --> <header class="header"> <h1>WiFi DensePose</h1> <p class="subtitle">Human Tracking Through Walls Using WiFi Signals</p> <div class="header-info"> <span class="api-version"></span> <span class="api-environment"></span> <span class="overall-health"></span> </div> </header> <!-- Navigation --> <nav class="nav-tabs"> <button class="nav-tab active" data-tab="dashboard">Dashboard</button> <button class="nav-tab" data-tab="hardware">Hardware</button> <button class="nav-tab" data-tab="demo">Live Demo</button> <button class="nav-tab" data-tab="architecture">Architecture</button> </nav> <!-- Dashboard Tab --> <section id="dashboard" class="tab-content active"> <div class="hero-section"> <h2>Integration Test Dashboard</h2> <p class="hero-description"> This page demonstrates the full WiFi-DensePose UI with mock backend integration. Use the test controls to interact with different components. </p> <!-- Error container --> <div class="error-container" style="display: none;"></div> <!-- Live Status Panel --> <div class="live-status-panel"> <h3>System Status</h3> <div class="status-grid"> <div class="component-status" data-component="api"> <span class="component-name">API Server</span> <span class="status-text">-</span> <span class="status-message"></span> </div> <div class="component-status" data-component="hardware"> <span class="component-name">Hardware</span> <span class="status-text">-</span> <span class="status-message"></span> </div> <div class="component-status" data-component="inference"> <span class="component-name">Inference</span> <span class="status-text">-</span> <span class="status-message"></span> </div> <div class="component-status" data-component="streaming"> <span class="component-name">Streaming</span> <span class="status-text">-</span> <span class="status-message"></span> </div> </div> </div> <!-- System Metrics --> <div class="system-metrics-panel"> <h3>System Metrics</h3> <div class="metrics-grid"> <div class="metric-item"> <span class="metric-label">CPU Usage</span> <div class="progress-bar" data-type="cpu"> <div class="progress-fill normal" style="width: 0%"></div> </div> <span class="cpu-usage">0%</span> </div> <div class="metric-item"> <span class="metric-label">Memory Usage</span> <div class="progress-bar" data-type="memory"> <div class="progress-fill normal" style="width: 0%"></div> </div> <span class="memory-usage">0%</span> </div> <div class="metric-item"> <span class="metric-label">Disk Usage</span> <div class="progress-bar" data-type="disk"> <div class="progress-fill normal" style="width: 0%"></div> </div> <span class="disk-usage">0%</span> </div> </div> </div> <!-- Features Status --> <div class="features-panel"> <h3>Features</h3> <div class="features-status"></div> </div> <!-- Live Statistics --> <div class="live-stats-panel"> <h3>Live Statistics</h3> <div class="stats-grid"> <div class="stat-item"> <span class="stat-label">Active Persons</span> <span class="person-count">0</span> </div> <div class="stat-item"> <span class="stat-label">Avg Confidence</span> <span class="avg-confidence">0%</span> </div> <div class="stat-item"> <span class="stat-label">Total Detections</span> <span class="detection-count">0</span> </div> </div> <div class="zones-panel"> <h4>Zone Occupancy</h4> <div class="zones-summary"></div> </div> </div> </div> </section> <!-- Hardware Tab --> <section id="hardware" class="tab-content"> <h2>Hardware Configuration</h2> <div class="hardware-grid"> <div class="antenna-section"> <h3>3×3 Antenna Array</h3> <p class="help-text">Click antennas to toggle their state</p> <div class="antenna-array"> <div class="antenna-grid"> <div class="antenna tx active" data-type="TX1"></div> <div class="antenna tx active" data-type="TX2"></div> <div class="antenna tx active" data-type="TX3"></div> <div class="antenna rx active" data-type="RX1"></div> <div class="antenna rx active" data-type="RX2"></div> <div class="antenna rx active" data-type="RX3"></div> <div class="antenna rx active" data-type="RX4"></div> <div class="antenna rx active" data-type="RX5"></div> <div class="antenna rx active" data-type="RX6"></div> </div> <div class="antenna-legend"> <div class="legend-item"> <div class="legend-color tx"></div> <span>Transmitters (3)</span> </div> <div class="legend-item"> <div class="legend-color rx"></div> <span>Receivers (6)</span> </div> </div> <div class="array-status"></div> </div> </div> <div class="config-section"> <h3>WiFi Configuration</h3> <div class="config-grid"> <div class="config-item"> <label>Frequency</label> <div class="config-value">2.4GHz ± 20MHz</div> </div> <div class="config-item"> <label>Subcarriers</label> <div class="config-value">30</div> </div> <div class="config-item"> <label>Sampling Rate</label> <div class="config-value">100 Hz</div> </div> <div class="config-item"> <label>Total Cost</label> <div class="config-value">$30</div> </div> </div> <div class="csi-data"> <h4>Real-time CSI Data</h4> <div class="csi-display"> <div class="csi-row"> <span>Amplitude:</span> <div class="csi-bar"> <div class="csi-fill amplitude" style="width: 75%"></div> </div> <span class="csi-value">0.75</span> </div> <div class="csi-row"> <span>Phase:</span> <div class="csi-bar"> <div class="csi-fill phase" style="width: 60%"></div> </div> <span class="csi-value">1.2π</span> </div> </div> </div> </div> </div> </section> <!-- Demo Tab --> <section id="demo" class="tab-content"> <h2>Live Demonstration</h2> <div class="demo-controls"> <button id="startDemo" class="btn btn--primary">Start Stream</button> <button id="stopDemo" class="btn btn--secondary" disabled>Stop Stream</button> <div class="demo-status"> <span class="status status--info" id="demoStatus">Ready</span> </div> </div> <div class="demo-grid"> <div class="signal-panel"> <h3>WiFi Signal Analysis</h3> <div class="signal-display"> <canvas id="signalCanvas" width="400" height="200"></canvas> </div> <div class="signal-metrics"> <div class="metric"> <span>Signal Strength:</span> <span id="signalStrength">-45 dBm</span> </div> <div class="metric"> <span>Processing Latency:</span> <span id="latency">12 ms</span> </div> </div> </div> <div class="pose-panel"> <h3>Human Pose Detection</h3> <div class="pose-display"> <canvas id="poseCanvas" width="400" height="300"></canvas> </div> <div class="detection-info"> <div class="info-item"> <span>Persons Detected:</span> <span id="personCount">0</span> </div> <div class="info-item"> <span>Confidence:</span> <span id="confidence">0.0%</span> </div> <div class="info-item"> <span>Keypoints:</span> <span id="keypoints">0/0</span> </div> </div> </div> </div> </section> <!-- Architecture Tab --> <section id="architecture" class="tab-content"> <h2>System Architecture</h2> <div class="implementation-note"> <h3>Integration Test Mode</h3> <p>This page is running in integration test mode with a mock backend server. All API calls and WebSocket connections are intercepted and handled by mock implementations that simulate the real WiFi-DensePose backend.</p> </div> </section> </div> <!-- Error Toast --> <div id="globalErrorToast" class="error-toast"></div> <!-- Load application scripts as modules --> <script type="module"> import { mockServer } from '../utils/mock-server.js'; import { WiFiDensePoseApp } from '../app.js'; import { API_CONFIG } from '../config/api.config.js'; import { backendDetector } from '../utils/backend-detector.js'; // Global test functions window.mockServer = mockServer; window.app = null; window.toggleMockMode = async () => { try { // Toggle mock mode API_CONFIG.MOCK_SERVER.ENABLED = !API_CONFIG.MOCK_SERVER.ENABLED; // Force backend detector to recheck backendDetector.forceCheck(); if (API_CONFIG.MOCK_SERVER.ENABLED) { mockServer.start(); updateMockIndicator(true); showTestStatus('Mock mode enabled - using test data', 'success'); } else { mockServer.stop(); updateMockIndicator(false); showTestStatus('Mock mode disabled - using real backend', 'info'); } // Reinitialize app with new configuration if (!window.app) { window.app = new WiFiDensePoseApp(); await window.app.init(); } } catch (error) { showTestStatus(`Failed to toggle mock mode: ${error.message}`, 'error'); } }; window.checkBackendStatus = async () => { try { showTestStatus('Checking backend status...', 'info'); const isAvailable = await backendDetector.checkBackendAvailability(); const useMock = await backendDetector.shouldUseMockServer(); if (isAvailable && !useMock) { showTestStatus('✅ Real backend is available and being used', 'success'); updateMockIndicator(false); } else if (useMock) { showTestStatus('🧪 Using mock server (testing mode)', 'success'); updateMockIndicator(true); } else { showTestStatus('❌ Backend unavailable, mock server available', 'error'); updateMockIndicator(false); } } catch (error) { showTestStatus(`Backend check failed: ${error.message}`, 'error'); } }; window.testHealthAPI = async () => { try { showTestStatus('Testing health API...', 'info'); const response = await fetch('/health/health'); const data = await response.json(); if (data.status === 'healthy') { showTestStatus('Health API test passed', 'success'); } else { showTestStatus('Health API returned non-healthy status', 'error'); } } catch (error) { showTestStatus(`Health API test failed: ${error.message}`, 'error'); } }; window.testPoseAPI = async () => { try { showTestStatus('Testing pose API...', 'info'); const response = await fetch('/api/v1/pose/current'); const data = await response.json(); if (data.timestamp && Array.isArray(data.persons)) { showTestStatus(`Pose API test passed. Found ${data.persons.length} persons`, 'success'); } else { showTestStatus('Pose API returned invalid data format', 'error'); } } catch (error) { showTestStatus(`Pose API test failed: ${error.message}`, 'error'); } }; window.testWebSocketStream = () => { try { showTestStatus('Testing WebSocket stream...', 'info'); const ws = new WebSocket('ws://localhost/api/v1/stream/pose'); ws.onopen = () => { showTestStatus('WebSocket connection opened', 'success'); }; ws.onmessage = (event) => { const data = JSON.parse(event.data); showTestStatus(`WebSocket message received: ${data.type}`, 'success'); // Close after first message setTimeout(() => ws.close(), 1000); }; ws.onerror = (error) => { showTestStatus(`WebSocket error: ${error.message}`, 'error'); }; ws.onclose = () => { showTestStatus('WebSocket connection closed', 'info'); }; } catch (error) { showTestStatus(`WebSocket test failed: ${error.message}`, 'error'); } }; window.testFullIntegration = async () => { try { showTestStatus('Running full integration test...', 'info'); // Start mock server if not running if (!mockServer.isRunning) { mockServer.start(); updateMockIndicator(true); } // Test health await testHealthAPI(); await new Promise(resolve => setTimeout(resolve, 500)); // Test pose await testPoseAPI(); await new Promise(resolve => setTimeout(resolve, 500)); // Test WebSocket testWebSocketStream(); showTestStatus('Full integration test completed', 'success'); } catch (error) { showTestStatus(`Integration test failed: ${error.message}`, 'error'); } }; window.simulateErrors = () => { try { showTestStatus('Simulating server errors...', 'info'); // Add error endpoints mockServer.simulateError('GET', '/health/health', 500, 'Simulated server error'); mockServer.simulateError('GET', '/api/v1/pose/current', 503, 'Service unavailable'); showTestStatus('Error simulation enabled. Health and Pose APIs will return errors.', 'success'); } catch (error) { showTestStatus(`Failed to simulate errors: ${error.message}`, 'error'); } }; function updateMockIndicator(isActive) { const indicator = document.getElementById('mockIndicator'); if (isActive) { indicator.textContent = 'Mock Server: Online'; indicator.classList.remove('inactive'); } else { indicator.textContent = 'Mock Server: Offline'; indicator.classList.add('inactive'); } } function showTestStatus(message, type) { const status = document.getElementById('testStatus'); status.textContent = message; status.className = `test-status ${type}`; status.style.display = 'block'; // Auto-hide after 5 seconds for success/info messages if (type === 'success' || type === 'info') { setTimeout(() => { status.style.display = 'none'; }, 5000); } } // Auto-check backend status on load document.addEventListener('DOMContentLoaded', async () => { await checkBackendStatus(); // Initialize app if (!window.app) { window.app = new WiFiDensePoseApp(); await window.app.init(); } }); </script> </body> </html>