From 35dd781d90e21b15d92e29a88cd41d1d452c3b82 Mon Sep 17 00:00:00 2001
From: ValueOn AG
Date: Tue, 17 Feb 2026 17:25:40 +0100
Subject: [PATCH] refactor: drastically shortened auth test flow - direct login
to chat to pre-join to meeting
Co-authored-by: Cursor
---
src/bot/authTestProcedure.ts | 342 +++++++++--------------------------
1 file changed, 88 insertions(+), 254 deletions(-)
diff --git a/src/bot/authTestProcedure.ts b/src/bot/authTestProcedure.ts
index e57d98d..1e1808b 100644
--- a/src/bot/authTestProcedure.ts
+++ b/src/bot/authTestProcedure.ts
@@ -234,7 +234,7 @@ async function _runVariant(
}
// =====================================================================
- // STEP 1: Navigate to teams.microsoft.com
+ // STEP 1: Navigate to teams.microsoft.com → MS Login
// =====================================================================
_log('info', 'Step 1: Navigate to teams.microsoft.com');
await page.goto('https://teams.microsoft.com', {
@@ -242,7 +242,6 @@ async function _runVariant(
timeout: 30000,
});
- // Wait for login redirect OR the Teams landing page to appear
_log('info', 'Waiting for login.microsoftonline.com redirect...');
try {
await page.waitForURL('**/login.microsoftonline.com/**', { timeout: 30000 });
@@ -251,37 +250,31 @@ async function _runVariant(
_log('warn', `No login redirect, current URL: ${page.url().substring(0, 150)}`);
}
- // Wait for the login page to FULLY RENDER (email input visible)
- _log('info', 'Waiting for login page to fully render...');
+ // Wait for login page to render
try {
- await page.waitForSelector(
- 'input[name="loginfmt"], input[type="email"], button:has-text("Sign in"), button:has-text("Join a meeting")',
- { timeout: 15000, state: 'visible' },
- );
+ await page.waitForSelector('input[name="loginfmt"], input[type="email"]', { timeout: 15000, state: 'visible' });
await page.waitForTimeout(1000);
} catch {
- _log('warn', 'Login page elements not found, taking screenshot anyway');
+ _log('warn', 'Login page elements not found');
await page.waitForTimeout(2000);
}
await _screenshotStep('1 - Login-Seite');
// =====================================================================
- // STEP 2: Microsoft Login
+ // STEP 2: Microsoft Authentication
// =====================================================================
if (botAccountEmail && botAccountPassword) {
authAttempted = true;
-
- // Check if we're on login.microsoftonline.com or on the Teams landing page
const currentUrl = page.url();
const onMsLogin = currentUrl.includes('login.microsoftonline.com') || currentUrl.includes('login.live.com');
if (onMsLogin) {
- _log('info', `On MS login page, authenticating as ${botAccountEmail}`);
+ _log('info', `Authenticating as ${botAccountEmail}`);
const authProcedure = new AuthProcedure(page, logger);
authSuccess = await authProcedure.authenticateWithMicrosoft(botAccountEmail, botAccountPassword, true);
_log(authSuccess ? 'info' : 'warn', `Auth result: ${authSuccess ? 'success' : 'failed'}`);
} else {
- _log('info', 'Not on MS login page — Teams may already be loaded. Skipping auth step.');
+ _log('info', 'Not on MS login page, skipping auth');
authSuccess = null;
}
} else {
@@ -289,11 +282,11 @@ async function _runVariant(
}
// =====================================================================
- // STEP 3: Wait for Teams landing page to fully render
+ // STEP 3: Wait for Teams Chat page (= landing page after auth)
+ // After login, bot lands directly on the Teams chat page with "Join" button
// =====================================================================
- _log('info', 'Waiting for Teams landing page to fully render...');
+ _log('info', 'Step 3: Waiting for Teams chat page to load...');
- // Wait for redirect back to Teams (if we were on login page)
if (authSuccess) {
try {
await page.waitForURL('**/teams.microsoft.com/**', { timeout: 30000 });
@@ -302,243 +295,37 @@ async function _runVariant(
}
}
- // Wait for either "Sign in" or "Join a meeting" button to be visible
- // This is the Teams landing page ("Everyone together in Teams")
- _log('info', 'Waiting for "Sign in" or "Join a meeting" button to appear...');
- try {
- await page.waitForSelector(
- 'button:has-text("Sign in"), button:has-text("Join a meeting"), button:has-text("Anmelden"), button:has-text("An Besprechung teilnehmen")',
- { timeout: 30000, state: 'visible' },
- );
- await page.waitForTimeout(1000);
- _log('info', 'Teams landing page loaded');
- } catch {
- _log('warn', 'Landing page buttons not found after 30s');
- await page.waitForTimeout(2000);
- }
- await _screenshotStep('2 - Teams Landingpage');
-
- // Log all visible buttons for debugging
- try {
- const buttons = await page.evaluate(() => {
- const btns = document.querySelectorAll('button, a[role="button"]');
- return Array.from(btns).slice(0, 20).map(b => {
- const text = (b.textContent || '').trim().substring(0, 80);
- const tid = b.getAttribute('data-tid') || '';
- return `[${b.tagName} tid="${tid}"] ${text}`;
- });
- });
- buttons.forEach(b => _log('info', ` Visible button: ${b}`));
- } catch {
- // Ignore
- }
-
- // =====================================================================
- // STEP 4: Click "Join a meeting"
- // =====================================================================
- _log('info', 'Step 4: Clicking "Join a meeting" on Teams landing page...');
- const joinSelectors = [
- 'button:has-text("Join a meeting")',
- 'button:has-text("An Besprechung teilnehmen")',
- 'a:has-text("Join a meeting")',
- 'a:has-text("An Besprechung teilnehmen")',
- ];
-
- let clicked = false;
- for (const selector of joinSelectors) {
- try {
- const btn = await page.waitForSelector(selector, { timeout: 5000, state: 'visible' });
- if (btn) {
- await btn.click();
- _log('info', `Clicked: ${selector}`);
- clicked = true;
- break;
- }
- } catch {
- // Try next
- }
- }
-
- if (!clicked) {
- _log('warn', '"Join a meeting" button not found on landing page');
- }
-
- // Wait for the "Join a meeting" form to load (wait for Meeting ID input)
- _log('info', 'Waiting for Join a meeting form to load...');
- try {
- await page.waitForSelector('input[placeholder*="meeting" i], input[placeholder*="Meeting" i], input[placeholder*="ID" i]', {
- timeout: 15000, state: 'visible',
- });
- await page.waitForTimeout(1000);
- } catch {
- _log('warn', 'Meeting form input not found, continuing');
- await page.waitForTimeout(2000);
- }
- await _screenshotStep('3 - Join a meeting Formular');
-
- // Parse meeting URL to extract Meeting ID and Passcode
- // URL format: https://teams.microsoft.com/meet/36438888781520?p=5fGqrujxzewPFjJacW
- const { meetingId, passcode } = _parseMeetingUrl(meetingUrl);
- _log('info', `Parsed meeting URL: ID="${meetingId}", Passcode="${passcode ? passcode.substring(0, 5) + '...' : 'none'}"`);
-
- // Fill Meeting ID field
- if (meetingId) {
- _log('info', 'Looking for Meeting ID input...');
- const idInputSelectors = [
- 'input[placeholder*="meeting" i]',
- 'input[placeholder*="Meeting ID" i]',
- 'input[placeholder*="ID" i]',
- 'input[aria-label*="Meeting ID" i]',
- 'input[type="text"]:first-of-type',
- ];
-
- let idFilled = false;
- for (const selector of idInputSelectors) {
- try {
- const input = await page.waitForSelector(selector, { timeout: 5000, state: 'visible' });
- if (input) {
- await input.fill(meetingId);
- _log('info', `Entered Meeting ID in: ${selector}`);
- idFilled = true;
- await page.waitForTimeout(1000);
- break;
- }
- } catch {
- // Try next
- }
- }
- if (!idFilled) {
- _log('warn', 'Meeting ID input not found');
- }
- }
-
- // Fill Passcode field
- if (passcode) {
- _log('info', 'Looking for Passcode input...');
- const passcodeSelectors = [
- 'input[placeholder*="passcode" i]',
- 'input[placeholder*="Passcode" i]',
- 'input[placeholder*="password" i]',
- 'input[aria-label*="passcode" i]',
- 'input[aria-label*="Passcode" i]',
- ];
-
- let passcodeFilled = false;
- for (const selector of passcodeSelectors) {
- try {
- const input = await page.waitForSelector(selector, { timeout: 5000, state: 'visible' });
- if (input) {
- await input.fill(passcode);
- _log('info', `Entered Passcode in: ${selector}`);
- passcodeFilled = true;
- await page.waitForTimeout(1000);
- break;
- }
- } catch {
- // Try next
- }
- }
- if (!passcodeFilled) {
- _log('warn', 'Passcode input not found');
- }
- }
-
- await _screenshotStep('4 - Meeting-Daten eingegeben');
-
- // Click "Join meeting" button
- _log('info', 'Looking for "Join meeting" button...');
- const joinBtnSelectors = [
- 'button:has-text("Join meeting")',
- 'button:has-text("Besprechung beitreten")',
- 'button:has-text("Join now")',
- 'button:has-text("Jetzt teilnehmen")',
- 'button[data-tid="joinMeetingButton"]',
- 'button[data-tid="join-meeting-button"]',
- ];
-
- let joinClicked = false;
- for (const selector of joinBtnSelectors) {
- try {
- const btn = await page.waitForSelector(selector, { timeout: 5000, state: 'visible' });
- if (btn) {
- await btn.click();
- _log('info', `Clicked "Join meeting": ${selector}`);
- joinClicked = true;
- break;
- }
- } catch {
- // Try next
- }
- }
-
- if (!joinClicked) {
- _log('warn', '"Join meeting" button not found — logging all visible buttons');
- try {
- const buttons = await page.evaluate(() => {
- const btns = document.querySelectorAll('button');
- return Array.from(btns).slice(0, 20).map(b => {
- const text = (b.textContent || '').trim().substring(0, 80);
- const tid = b.getAttribute('data-tid') || '';
- const disabled = b.disabled ? ' DISABLED' : '';
- return `[BUTTON tid="${tid}"${disabled}] ${text}`;
- });
- });
- buttons.forEach(b => _log('info', ` ${b}`));
- } catch {
- // Ignore
- }
- }
-
- // Wait for resulting page after clicking Join
- if (joinClicked) {
- _log('info', 'Waiting for page after Join meeting...');
- await page.waitForTimeout(3000);
- try {
- await page.waitForLoadState('networkidle', { timeout: 20000 });
- } catch {
- _log('warn', 'networkidle timeout after Join, continuing');
- }
- await page.waitForTimeout(5000);
- }
- await _screenshotStep('5 - Nach Join meeting');
-
- // =====================================================================
- // STEP 6: Click "Join" button in Teams chat header to join the call
- // =====================================================================
- _log('info', 'Step 6: Looking for "Join" button in Teams chat header...');
-
- // Wait for the Teams chat page to fully render
+ // Wait for the "Join" button in the chat header — this confirms we're on the chat page
try {
await page.waitForSelector(
'button[data-tid="chat-join-button"], button[data-tid="join-call-button"]',
{ timeout: 30000, state: 'visible' },
);
- _log('info', 'Teams chat page loaded, "Join" button found');
+ _log('info', 'Teams chat page loaded, "Join" button found in header');
} catch {
- _log('warn', '"Join" button not found in chat header after 30s — logging all buttons');
+ _log('warn', '"Join" button not found in chat header after 30s');
+ // Log all visible buttons for debugging
try {
const buttons = await page.evaluate(() => {
const btns = document.querySelectorAll('button');
- return Array.from(btns).slice(0, 30).map(b => {
+ return Array.from(btns).slice(0, 25).map(b => {
const text = (b.textContent || '').trim().substring(0, 80);
const tid = b.getAttribute('data-tid') || '';
return `[BUTTON tid="${tid}"] ${text}`;
});
});
buttons.forEach(b => _log('info', ` ${b}`));
- } catch {
- // Ignore
- }
+ } catch { /* ignore */ }
}
+ await _screenshotStep('2 - Teams Chat');
- await _screenshotStep('6 - Teams Chat (vor Join-Klick)');
-
- // Click the "Join" button in the chat header
+ // =====================================================================
+ // STEP 4: Click "Join" in chat header → Pre-Join screen
+ // =====================================================================
+ _log('info', 'Step 4: Clicking "Join" in chat header...');
const chatJoinSelectors = [
'button[data-tid="chat-join-button"]',
'button[data-tid="join-call-button"]',
- 'button:has-text("Join")',
- 'button:has-text("Beitreten")',
];
let chatJoinClicked = false;
@@ -547,40 +334,89 @@ async function _runVariant(
const btn = await page.waitForSelector(selector, { timeout: 5000, state: 'visible' });
if (btn) {
await btn.click();
- _log('info', `Clicked chat "Join" button: ${selector}`);
+ _log('info', `Clicked: ${selector}`);
chatJoinClicked = true;
break;
}
- } catch {
- // Try next
- }
+ } catch { /* try next */ }
}
if (!chatJoinClicked) {
_log('warn', '"Join" button in chat header not found');
}
- // Wait for the meeting to load after clicking Join
+ // Wait for pre-join screen (camera preview, "Join now" button)
if (chatJoinClicked) {
- _log('info', 'Waiting for meeting view to load...');
- await page.waitForTimeout(5000);
-
- // Wait for meeting UI elements (hangup button, video controls, etc.)
+ _log('info', 'Waiting for pre-join screen...');
try {
await page.waitForSelector(
- 'button[id="hangup-button"], button[data-tid="hangup-button"], [data-tid="prejoin-join-button"], [data-tid="calling-prejoin"]',
+ 'button:has-text("Join now"), button:has-text("Jetzt teilnehmen"), button[data-tid="prejoin-join-button"]',
{ timeout: 30000, state: 'visible' },
);
- _log('info', 'Meeting UI elements detected');
+ _log('info', 'Pre-join screen loaded');
} catch {
- _log('warn', 'Meeting UI elements not found after 30s');
+ _log('warn', 'Pre-join "Join now" button not found after 30s');
}
-
- await page.waitForTimeout(5000);
+ await page.waitForTimeout(2000);
}
- await _screenshotStep('7 - Nach Join (Meeting-Ansicht)');
+ await _screenshotStep('3 - Pre-Join Ansicht');
- // Log all visible buttons on the final page for debugging
+ // =====================================================================
+ // STEP 5: Click "Join now" → Enter the meeting
+ // =====================================================================
+ _log('info', 'Step 5: Clicking "Join now"...');
+ const joinNowSelectors = [
+ 'button:has-text("Join now")',
+ 'button:has-text("Jetzt teilnehmen")',
+ 'button[data-tid="prejoin-join-button"]',
+ ];
+
+ let joinNowClicked = false;
+ for (const selector of joinNowSelectors) {
+ try {
+ const btn = await page.waitForSelector(selector, { timeout: 5000, state: 'visible' });
+ if (btn) {
+ await btn.click();
+ _log('info', `Clicked "Join now": ${selector}`);
+ joinNowClicked = true;
+ break;
+ }
+ } catch { /* try next */ }
+ }
+
+ if (!joinNowClicked) {
+ _log('warn', '"Join now" button not found — logging all buttons');
+ try {
+ const buttons = await page.evaluate(() => {
+ const btns = document.querySelectorAll('button');
+ return Array.from(btns).slice(0, 25).map(b => {
+ const text = (b.textContent || '').trim().substring(0, 80);
+ const tid = b.getAttribute('data-tid') || '';
+ return `[BUTTON tid="${tid}"] ${text}`;
+ });
+ });
+ buttons.forEach(b => _log('info', ` ${b}`));
+ } catch { /* ignore */ }
+ }
+
+ // Wait for the actual meeting view (hangup button = we're in the meeting)
+ if (joinNowClicked) {
+ _log('info', 'Waiting for meeting to load...');
+ await page.waitForTimeout(5000);
+ try {
+ await page.waitForSelector(
+ 'button[id="hangup-button"], button[data-tid="hangup-button"], #hangup-button',
+ { timeout: 30000, state: 'visible' },
+ );
+ _log('info', 'IN THE MEETING — hangup button visible!');
+ } catch {
+ _log('warn', 'Hangup button not found after 30s');
+ }
+ await page.waitForTimeout(3000);
+ }
+ await _screenshotStep('4 - Im Meeting');
+
+ // Log final page buttons for debugging
try {
const buttons = await page.evaluate(() => {
const btns = document.querySelectorAll('button');
@@ -590,10 +426,8 @@ async function _runVariant(
return `[BUTTON tid="${tid}"] ${text}`;
});
});
- buttons.forEach(b => _log('info', ` Final page button: ${b}`));
- } catch {
- // Ignore
- }
+ buttons.forEach(b => _log('info', ` Final: ${b}`));
+ } catch { /* ignore */ }
// =====================================================================
// FINAL: Log result