refactor: drastically shortened auth test flow - direct login to chat to pre-join to meeting

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
ValueOn AG 2026-02-17 17:25:40 +01:00
parent 68cf43c5fa
commit 35dd781d90

View file

@ -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'); _log('info', 'Step 1: Navigate to teams.microsoft.com');
await page.goto('https://teams.microsoft.com', { await page.goto('https://teams.microsoft.com', {
@ -242,7 +242,6 @@ async function _runVariant(
timeout: 30000, timeout: 30000,
}); });
// Wait for login redirect OR the Teams landing page to appear
_log('info', 'Waiting for login.microsoftonline.com redirect...'); _log('info', 'Waiting for login.microsoftonline.com redirect...');
try { try {
await page.waitForURL('**/login.microsoftonline.com/**', { timeout: 30000 }); 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)}`); _log('warn', `No login redirect, current URL: ${page.url().substring(0, 150)}`);
} }
// Wait for the login page to FULLY RENDER (email input visible) // Wait for login page to render
_log('info', 'Waiting for login page to fully render...');
try { try {
await page.waitForSelector( await page.waitForSelector('input[name="loginfmt"], input[type="email"]', { timeout: 15000, state: 'visible' });
'input[name="loginfmt"], input[type="email"], button:has-text("Sign in"), button:has-text("Join a meeting")',
{ timeout: 15000, state: 'visible' },
);
await page.waitForTimeout(1000); await page.waitForTimeout(1000);
} catch { } catch {
_log('warn', 'Login page elements not found, taking screenshot anyway'); _log('warn', 'Login page elements not found');
await page.waitForTimeout(2000); await page.waitForTimeout(2000);
} }
await _screenshotStep('1 - Login-Seite'); await _screenshotStep('1 - Login-Seite');
// ===================================================================== // =====================================================================
// STEP 2: Microsoft Login // STEP 2: Microsoft Authentication
// ===================================================================== // =====================================================================
if (botAccountEmail && botAccountPassword) { if (botAccountEmail && botAccountPassword) {
authAttempted = true; authAttempted = true;
// Check if we're on login.microsoftonline.com or on the Teams landing page
const currentUrl = page.url(); const currentUrl = page.url();
const onMsLogin = currentUrl.includes('login.microsoftonline.com') || currentUrl.includes('login.live.com'); const onMsLogin = currentUrl.includes('login.microsoftonline.com') || currentUrl.includes('login.live.com');
if (onMsLogin) { if (onMsLogin) {
_log('info', `On MS login page, authenticating as ${botAccountEmail}`); _log('info', `Authenticating as ${botAccountEmail}`);
const authProcedure = new AuthProcedure(page, logger); const authProcedure = new AuthProcedure(page, logger);
authSuccess = await authProcedure.authenticateWithMicrosoft(botAccountEmail, botAccountPassword, true); authSuccess = await authProcedure.authenticateWithMicrosoft(botAccountEmail, botAccountPassword, true);
_log(authSuccess ? 'info' : 'warn', `Auth result: ${authSuccess ? 'success' : 'failed'}`); _log(authSuccess ? 'info' : 'warn', `Auth result: ${authSuccess ? 'success' : 'failed'}`);
} else { } 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; authSuccess = null;
} }
} else { } 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) { if (authSuccess) {
try { try {
await page.waitForURL('**/teams.microsoft.com/**', { timeout: 30000 }); 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 // Wait for the "Join" button in the chat header — this confirms we're on the chat page
// 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
try { try {
await page.waitForSelector( await page.waitForSelector(
'button[data-tid="chat-join-button"], button[data-tid="join-call-button"]', 'button[data-tid="chat-join-button"], button[data-tid="join-call-button"]',
{ timeout: 30000, state: 'visible' }, { 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 { } 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 { try {
const buttons = await page.evaluate(() => { const buttons = await page.evaluate(() => {
const btns = document.querySelectorAll('button'); 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 text = (b.textContent || '').trim().substring(0, 80);
const tid = b.getAttribute('data-tid') || ''; const tid = b.getAttribute('data-tid') || '';
return `[BUTTON tid="${tid}"] ${text}`; return `[BUTTON tid="${tid}"] ${text}`;
}); });
}); });
buttons.forEach(b => _log('info', ` ${b}`)); buttons.forEach(b => _log('info', ` ${b}`));
} catch { } catch { /* ignore */ }
// Ignore
}
} }
await _screenshotStep('2 - Teams Chat');
await _screenshotStep('6 - Teams Chat (vor Join-Klick)'); // =====================================================================
// STEP 4: Click "Join" in chat header → Pre-Join screen
// Click the "Join" button in the chat header // =====================================================================
_log('info', 'Step 4: Clicking "Join" in chat header...');
const chatJoinSelectors = [ 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"]',
'button:has-text("Join")',
'button:has-text("Beitreten")',
]; ];
let chatJoinClicked = false; let chatJoinClicked = false;
@ -547,40 +334,89 @@ async function _runVariant(
const btn = await page.waitForSelector(selector, { timeout: 5000, state: 'visible' }); const btn = await page.waitForSelector(selector, { timeout: 5000, state: 'visible' });
if (btn) { if (btn) {
await btn.click(); await btn.click();
_log('info', `Clicked chat "Join" button: ${selector}`); _log('info', `Clicked: ${selector}`);
chatJoinClicked = true; chatJoinClicked = true;
break; break;
} }
} catch { } catch { /* try next */ }
// Try next
}
} }
if (!chatJoinClicked) { if (!chatJoinClicked) {
_log('warn', '"Join" button in chat header not found'); _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) { if (chatJoinClicked) {
_log('info', 'Waiting for meeting view to load...'); _log('info', 'Waiting for pre-join screen...');
await page.waitForTimeout(5000);
// Wait for meeting UI elements (hangup button, video controls, etc.)
try { try {
await page.waitForSelector( 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' }, { timeout: 30000, state: 'visible' },
); );
_log('info', 'Meeting UI elements detected'); _log('info', 'Pre-join screen loaded');
} catch { } catch {
_log('warn', 'Meeting UI elements not found after 30s'); _log('warn', 'Pre-join "Join now" button not found after 30s');
} }
await page.waitForTimeout(2000);
await page.waitForTimeout(5000);
} }
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 { try {
const buttons = await page.evaluate(() => { const buttons = await page.evaluate(() => {
const btns = document.querySelectorAll('button'); const btns = document.querySelectorAll('button');
@ -590,10 +426,8 @@ async function _runVariant(
return `[BUTTON tid="${tid}"] ${text}`; return `[BUTTON tid="${tid}"] ${text}`;
}); });
}); });
buttons.forEach(b => _log('info', ` Final page button: ${b}`)); buttons.forEach(b => _log('info', ` Final: ${b}`));
} catch { } catch { /* ignore */ }
// Ignore
}
// ===================================================================== // =====================================================================
// FINAL: Log result // FINAL: Log result