diff --git a/src/api/teamsbotApi.ts b/src/api/teamsbotApi.ts index 58b3732..29a3ca8 100644 --- a/src/api/teamsbotApi.ts +++ b/src/api/teamsbotApi.ts @@ -325,17 +325,50 @@ export async function fetchVoices(languageCode: string): Promise } /** - * Run auth detection tests against a Teams meeting URL. - * Tests 5 browser configuration variants to determine which ones - * receive the /v2/ (authenticated) vs light-meetings (anonymous) page. - * Does NOT join the meeting. + * Get list of available test variants from the Browser Bot. + */ +export interface TestVariantInfo { + id: string; + name: string; + description: string; +} + +export async function getTestAuthVariants(instanceId: string): Promise { + const response = await api.get(`/api/teamsbot/${instanceId}/test-auth/variants`, { + timeout: 30000, + }); + return response.data; +} + +/** + * Run a single test variant. Call this once per variant sequentially. + * Each call stays within Azure's 240s timeout. + */ +export async function testAuthSingleVariant( + instanceId: string, + variantId: string, + meetingUrl: string, + botEmail?: string, + botPassword?: string, +): Promise { + const payload: Record = { variantId, meetingUrl }; + if (botEmail) payload.botEmail = botEmail; + if (botPassword) payload.botPassword = botPassword; + const response = await api.post(`/api/teamsbot/${instanceId}/test-auth/variant`, payload, { + timeout: 200000, // 3+ minutes per variant + }); + return response.data; +} + +/** + * Run ALL auth detection tests in one request (legacy — may timeout). */ export async function testAuth(instanceId: string, meetingUrl: string, botEmail?: string, botPassword?: string): Promise { const payload: Record = { meetingUrl }; if (botEmail) payload.botEmail = botEmail; if (botPassword) payload.botPassword = botPassword; const response = await api.post(`/api/teamsbot/${instanceId}/test-auth`, payload, { - timeout: 900000, // 15 minutes — 5 browser variants run sequentially + timeout: 900000, }); return response.data; } diff --git a/src/pages/views/teamsbot/TeamsbotSettingsView.tsx b/src/pages/views/teamsbot/TeamsbotSettingsView.tsx index 191a048..a09c698 100644 --- a/src/pages/views/teamsbot/TeamsbotSettingsView.tsx +++ b/src/pages/views/teamsbot/TeamsbotSettingsView.tsx @@ -42,6 +42,7 @@ export const TeamsbotSettingsView: React.FC = () => { const [testBotEmail, setTestBotEmail] = useState(''); const [testBotPassword, setTestBotPassword] = useState(''); const [testRunning, setTestRunning] = useState(false); + const [testRunningVariant, setTestRunningVariant] = useState(null); const [testResults, setTestResults] = useState(null); const [testError, setTestError] = useState(null); const [screenshotPreview, setScreenshotPreview] = useState<{ src: string; caption: string } | null>(null); @@ -157,19 +158,103 @@ export const TeamsbotSettingsView: React.FC = () => { setTestRunning(true); setTestResults(null); setTestError(null); + setTestRunningVariant(null); try { - const results = await teamsbotApi.testAuth( - instanceId, - testMeetingUrl.trim(), - testBotEmail.trim() || undefined, - testBotPassword || undefined, - ); - setTestResults(results); + // Step 1: Get available variants + const variants = await teamsbotApi.getTestAuthVariants(instanceId); + + // Initialize results shell so UI shows progress + const initialResults: AuthTestResults = { + meetingUrl: testMeetingUrl.trim(), + timestamp: new Date().toISOString(), + variants: variants.map(v => ({ + variantId: v.id, + variantName: v.name, + success: false, + pageType: 'unknown' as const, + finalUrl: '', + hasSignInLink: false, + hasNameInput: false, + hasJoinButton: false, + authAttempted: false, + authSuccess: null, + durationMs: 0, + detectedSignals: [], + logs: ['Warte...'], + })), + recommendation: 'Test laeuft...', + }; + setTestResults(initialResults); + + // Step 2: Run each variant sequentially + const completedVariants: AuthTestResult[] = []; + for (const variantInfo of variants) { + setTestRunningVariant(variantInfo.name); + try { + const result = await teamsbotApi.testAuthSingleVariant( + instanceId, + variantInfo.id, + testMeetingUrl.trim(), + testBotEmail.trim() || undefined, + testBotPassword || undefined, + ); + completedVariants.push(result); + } catch (err: any) { + completedVariants.push({ + variantId: variantInfo.id, + variantName: variantInfo.name, + success: false, + pageType: 'error', + finalUrl: '', + hasSignInLink: false, + hasNameInput: false, + hasJoinButton: false, + authAttempted: false, + authSuccess: null, + durationMs: 0, + error: err.message || 'Fehler', + detectedSignals: [], + logs: [`[ERROR] ${err.message || 'Unbekannter Fehler'}`], + }); + } + + // Update UI with results so far + setTestResults(prev => prev ? { + ...prev, + variants: [ + ...completedVariants, + ...variants.slice(completedVariants.length).map(v => ({ + variantId: v.id, + variantName: v.name, + success: false, + pageType: 'unknown' as const, + finalUrl: '', + hasSignInLink: false, + hasNameInput: false, + hasJoinButton: false, + authAttempted: false, + authSuccess: null, + durationMs: 0, + detectedSignals: [], + logs: ['Warte...'], + })), + ], + } : prev); + } + + // Final update with recommendation + setTestResults({ + meetingUrl: testMeetingUrl.trim(), + timestamp: new Date().toISOString(), + variants: completedVariants, + recommendation: `Test abgeschlossen. ${completedVariants.filter(v => v.pageType === 'v2').length} von ${completedVariants.length} Varianten auf /v2/.`, + }); } catch (err: any) { setTestError(err.message || 'Auth-Test fehlgeschlagen'); } finally { setTestRunning(false); + setTestRunningVariant(null); } }; @@ -286,7 +371,9 @@ export const TeamsbotSettingsView: React.FC = () => { {testRunning && (
- 5 Browser-Varianten werden getestet (~8-10 Minuten)... + {testRunningVariant + ? `Teste: ${testRunningVariant}...` + : 'Varianten werden geladen...'}
)}