fix: poll for interstitial buttons instead of one-shot check, race all selectors

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
ValueOn AG 2026-02-18 21:37:15 +01:00
parent 72f57f062d
commit a981ae6bd8

View file

@ -250,40 +250,51 @@ export class BotOrchestrator {
timeout: 30000, timeout: 30000,
}); });
// Teams might show a "Continue on this browser" interstitial or redirect // Teams may show interstitials before the pre-join screen.
// Wait for the page to settle // Poll for ALL possible next-step buttons simultaneously so we don't
await this._page!.waitForTimeout(3000); // miss one if it appears slowly.
const currentUrl = this._page!.url(); const currentUrl = this._page!.url();
this._logger.info(`Auth join: URL after meeting navigation: ${currentUrl.substring(0, 150)}`); this._logger.info(`Auth join: URL after meeting navigation: ${currentUrl.substring(0, 150)}`);
// Handle "Continue on this browser" if shown (same as anonymous flow) // Race: wait for whichever button appears first (interstitial OR pre-join)
try { const interstitialSelectors = [
const continueBtn = await this._page!.$('button:has-text("Continue on this browser"), button:has-text("In diesem Browser fortfahren")'); 'button:has-text("Continue on this browser")',
if (continueBtn) { 'button:has-text("In diesem Browser fortfahren")',
await continueBtn.click(); 'button:has-text("Weiter in diesem Browser")',
this._logger.info('Clicked "Continue on this browser"');
await this._page!.waitForTimeout(3000);
}
} catch { /* not shown for auth users — expected */ }
// Handle "Join" button if Teams shows the chat view first
// (some meeting URLs redirect to the chat thread with a Join button)
const chatJoinSelectors = [
'button[data-tid="chat-join-button"]', 'button[data-tid="chat-join-button"]',
'button[data-tid="join-call-button"]', 'button[data-tid="join-call-button"]',
]; ];
let chatJoinClicked = false; const preJoinSelectors = [
for (const selector of chatJoinSelectors) { 'button:has-text("Join now")',
'button:has-text("Jetzt teilnehmen")',
'button[data-tid="prejoin-join-button"]',
];
const allSelectors = [...interstitialSelectors, ...preJoinSelectors].join(', ');
// Poll up to 30s for ANY of these buttons
this._logger.info('Waiting for interstitial or pre-join button...');
try { try {
const btn = await this._page!.$(selector); const firstBtn = await this._page!.waitForSelector(allSelectors, {
if (btn) { timeout: 30000, state: 'visible',
await btn.click(); });
chatJoinClicked = true; if (firstBtn) {
this._logger.info(`Clicked chat "Join" button: ${selector}`); const btnText = await firstBtn.textContent().catch(() => '');
const btnTid = await firstBtn.getAttribute('data-tid').catch(() => '');
this._logger.info(`First visible button: "${btnText?.trim()}" (data-tid="${btnTid}")`);
// If it's an interstitial button (not pre-join), click it and wait for the next screen
const isPreJoin = preJoinSelectors.some(s =>
s.includes(btnTid || '__none__') || (btnText && s.includes(btnText.trim()))
);
if (!isPreJoin) {
await firstBtn.click();
this._logger.info('Clicked interstitial button, waiting for pre-join screen...');
await this._page!.waitForTimeout(3000); await this._page!.waitForTimeout(3000);
break;
} }
} catch { /* continue */ } }
} catch {
this._logger.warn('No interstitial or pre-join button found within 30s');
await this._takeScreenshot('auth-no-buttons');
} }
// STEP 5: Pre-Join screen → Click "Join now" // STEP 5: Pre-Join screen → Click "Join now"