/** * MYP Platform - Service Worker Debug & Test Utility * Diagnose und Test-Tool für Service Worker Probleme */ class ServiceWorkerDebugger { constructor() { this.isDebugging = false; this.testResults = []; this.init(); } init() { console.log('[SW-Debug] Service Worker Debugger initialisiert'); // Automatische Diagnose beim Laden if ('serviceWorker' in navigator) { this.runDiagnostics(); } else { console.error('[SW-Debug] Service Worker werden nicht unterstützt'); } } async runDiagnostics() { console.log('[SW-Debug] Starte Service Worker Diagnose...'); try { // 1. Service Worker Status prüfen await this.checkServiceWorkerStatus(); // 2. Registrierte Service Worker auflisten await this.listRegisteredServiceWorkers(); // 3. Cache-Status prüfen await this.checkCacheStatus(); // 4. Test-Requests durchführen await this.runTestRequests(); // 5. Ergebnisse ausgeben this.outputResults(); } catch (error) { console.error('[SW-Debug] Diagnose fehlgeschlagen:', error); } } async checkServiceWorkerStatus() { console.log('[SW-Debug] Prüfe Service Worker Status...'); try { const registration = await navigator.serviceWorker.getRegistration(); if (registration) { console.log('[SW-Debug] ✅ Service Worker registriert:', registration.scope); if (registration.active) { console.log('[SW-Debug] ✅ Service Worker aktiv:', registration.active.scriptURL); this.testResults.push({ test: 'Service Worker Status', status: 'PASS', details: `Aktiv: ${registration.active.scriptURL}` }); } else { console.warn('[SW-Debug] ⚠️ Service Worker nicht aktiv'); this.testResults.push({ test: 'Service Worker Status', status: 'WARN', details: 'Service Worker registriert aber nicht aktiv' }); } if (registration.waiting) { console.log('[SW-Debug] 🔄 Service Worker wartet auf Aktivierung'); } if (registration.installing) { console.log('[SW-Debug] 🔄 Service Worker wird installiert'); } } else { console.error('[SW-Debug] ❌ Kein Service Worker registriert'); this.testResults.push({ test: 'Service Worker Status', status: 'FAIL', details: 'Kein Service Worker registriert' }); } } catch (error) { console.error('[SW-Debug] Fehler beim Prüfen des Service Worker Status:', error); this.testResults.push({ test: 'Service Worker Status', status: 'ERROR', details: error.message }); } } async listRegisteredServiceWorkers() { console.log('[SW-Debug] Liste registrierte Service Worker...'); try { const registrations = await navigator.serviceWorker.getRegistrations(); console.log(`[SW-Debug] ${registrations.length} Service Worker gefunden:`); registrations.forEach((registration, index) => { console.log(`[SW-Debug] ${index + 1}. Scope: ${registration.scope}`); if (registration.active) { console.log(`[SW-Debug] Aktiv: ${registration.active.scriptURL}`); } if (registration.waiting) { console.log(`[SW-Debug] Wartend: ${registration.waiting.scriptURL}`); } if (registration.installing) { console.log(`[SW-Debug] Installierend: ${registration.installing.scriptURL}`); } }); this.testResults.push({ test: 'Service Worker Registrierungen', status: registrations.length > 0 ? 'PASS' : 'WARN', details: `${registrations.length} Service Worker registriert` }); } catch (error) { console.error('[SW-Debug] Fehler beim Auflisten der Service Worker:', error); this.testResults.push({ test: 'Service Worker Registrierungen', status: 'ERROR', details: error.message }); } } async checkCacheStatus() { console.log('[SW-Debug] Prüfe Cache Status...'); try { const cacheNames = await caches.keys(); console.log(`[SW-Debug] ${cacheNames.length} Caches gefunden:`); let totalEntries = 0; for (const cacheName of cacheNames) { const cache = await caches.open(cacheName); const keys = await cache.keys(); console.log(`[SW-Debug] - ${cacheName}: ${keys.length} Einträge`); totalEntries += keys.length; } this.testResults.push({ test: 'Cache Status', status: 'PASS', details: `${cacheNames.length} Caches mit ${totalEntries} Einträgen` }); } catch (error) { console.error('[SW-Debug] Fehler beim Prüfen des Cache Status:', error); this.testResults.push({ test: 'Cache Status', status: 'ERROR', details: error.message }); } } async runTestRequests() { console.log('[SW-Debug] Führe Test-Requests durch...'); const testUrls = [ '/static/css/tailwind.min.css', '/static/js/ui-components.js', '/api/dashboard', '/dashboard' ]; for (const url of testUrls) { try { console.log(`[SW-Debug] Teste Request: ${url}`); const startTime = performance.now(); const response = await fetch(url); const endTime = performance.now(); const responseTime = Math.round(endTime - startTime); const servedBy = response.headers.get('X-Served-By') || 'Network'; if (response.ok) { console.log(`[SW-Debug] ✅ ${url} - ${response.status} (${responseTime}ms, ${servedBy})`); this.testResults.push({ test: `Request Test: ${url}`, status: 'PASS', details: `${response.status} - ${responseTime}ms - ${servedBy}` }); } else { console.warn(`[SW-Debug] ⚠️ ${url} - ${response.status} ${response.statusText}`); this.testResults.push({ test: `Request Test: ${url}`, status: 'WARN', details: `${response.status} ${response.statusText}` }); } } catch (error) { console.error(`[SW-Debug] ❌ ${url} - Fehler:`, error); this.testResults.push({ test: `Request Test: ${url}`, status: 'ERROR', details: error.message }); } } } outputResults() { console.log('[SW-Debug] === DIAGNOSE-ERGEBNISSE ==='); const passed = this.testResults.filter(r => r.status === 'PASS').length; const warned = this.testResults.filter(r => r.status === 'WARN').length; const failed = this.testResults.filter(r => r.status === 'FAIL').length; const errors = this.testResults.filter(r => r.status === 'ERROR').length; console.log(`[SW-Debug] Gesamt: ${this.testResults.length} Tests`); console.log(`[SW-Debug] ✅ Erfolgreich: ${passed}`); console.log(`[SW-Debug] ⚠️ Warnungen: ${warned}`); console.log(`[SW-Debug] ❌ Fehlgeschlagen: ${failed}`); console.log(`[SW-Debug] 💥 Fehler: ${errors}`); // Detaillierte Ergebnisse this.testResults.forEach(result => { const icon = this.getStatusIcon(result.status); console.log(`[SW-Debug] ${icon} ${result.test}: ${result.details}`); }); // Empfehlungen ausgeben this.outputRecommendations(); } getStatusIcon(status) { switch (status) { case 'PASS': return '✅'; case 'WARN': return '⚠️'; case 'FAIL': return '❌'; case 'ERROR': return '💥'; default: return '❓'; } } outputRecommendations() { console.log('[SW-Debug] === EMPFEHLUNGEN ==='); const hasErrors = this.testResults.some(r => r.status === 'ERROR' || r.status === 'FAIL'); if (hasErrors) { console.log('[SW-Debug] 🔧 Probleme erkannt:'); console.log('[SW-Debug] - Service Worker Cache leeren: await caches.keys().then(names => Promise.all(names.map(name => caches.delete(name))))'); console.log('[SW-Debug] - Service Worker neu registrieren: navigator.serviceWorker.getRegistrations().then(regs => regs.forEach(reg => reg.unregister()))'); console.log('[SW-Debug] - Browser-Cache leeren und Seite neu laden'); } else { console.log('[SW-Debug] ✅ Service Worker funktioniert korrekt'); } } // Utility-Methoden für manuelle Tests async clearAllCaches() { console.log('[SW-Debug] Lösche alle Caches...'); try { const cacheNames = await caches.keys(); await Promise.all(cacheNames.map(name => caches.delete(name))); console.log('[SW-Debug] ✅ Alle Caches gelöscht'); } catch (error) { console.error('[SW-Debug] Fehler beim Löschen der Caches:', error); } } async unregisterAllServiceWorkers() { console.log('[SW-Debug] Deregistriere alle Service Worker...'); try { const registrations = await navigator.serviceWorker.getRegistrations(); await Promise.all(registrations.map(reg => reg.unregister())); console.log('[SW-Debug] ✅ Alle Service Worker deregistriert'); } catch (error) { console.error('[SW-Debug] Fehler beim Deregistrieren der Service Worker:', error); } } async forceServiceWorkerUpdate() { console.log('[SW-Debug] Erzwinge Service Worker Update...'); try { const registration = await navigator.serviceWorker.getRegistration(); if (registration) { await registration.update(); console.log('[SW-Debug] ✅ Service Worker Update angefordert'); } else { console.warn('[SW-Debug] Kein Service Worker zum Aktualisieren gefunden'); } } catch (error) { console.error('[SW-Debug] Fehler beim Service Worker Update:', error); } } // Event-Listener für Service Worker Events setupEventListeners() { if ('serviceWorker' in navigator) { navigator.serviceWorker.addEventListener('controllerchange', () => { console.log('[SW-Debug] 🔄 Service Worker Controller hat gewechselt'); }); navigator.serviceWorker.addEventListener('message', (event) => { console.log('[SW-Debug] 📨 Message vom Service Worker:', event.data); }); } } } // Globale Instanz für Debugging window.swDebugger = new ServiceWorkerDebugger(); // Utility-Funktionen für die Konsole window.swDebug = { run: () => window.swDebugger.runDiagnostics(), clearCaches: () => window.swDebugger.clearAllCaches(), unregisterAll: () => window.swDebugger.unregisterAllServiceWorkers(), forceUpdate: () => window.swDebugger.forceServiceWorkerUpdate() }; console.log('[SW-Debug] Service Worker Debugger geladen. Verwende swDebug.run() für Diagnose.');