fix: frontend calls test variants individually to avoid timeout

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
ValueOn AG 2026-02-17 16:33:36 +01:00
parent c56e3e669e
commit 9aaf988932
2 changed files with 133 additions and 13 deletions

View file

@ -325,17 +325,50 @@ export async function fetchVoices(languageCode: string): Promise<VoiceOption[]>
}
/**
* 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<TestVariantInfo[]> {
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<AuthTestResult> {
const payload: Record<string, string> = { 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<AuthTestResults> {
const payload: Record<string, string> = { 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;
}

View file

@ -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<string | null>(null);
const [testResults, setTestResults] = useState<AuthTestResults | null>(null);
const [testError, setTestError] = useState<string | null>(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 && (
<div className={styles.testProgress}>
<FaSpinner className={styles.spinner} />
5 Browser-Varianten werden getestet (~8-10 Minuten)...
{testRunningVariant
? `Teste: ${testRunningVariant}...`
: 'Varianten werden geladen...'}
</div>
)}