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');
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,285 +295,16 @@ 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');
try {
const buttons = await page.evaluate(() => {
const btns = document.querySelectorAll('button');
return Array.from(btns).slice(0, 30).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
}
}
await _screenshotStep('6 - Teams Chat (vor Join-Klick)');
// Click the "Join" button in the 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;
for (const selector of chatJoinSelectors) {
try {
const btn = await page.waitForSelector(selector, { timeout: 5000, state: 'visible' });
if (btn) {
await btn.click();
_log('info', `Clicked chat "Join" button: ${selector}`);
chatJoinClicked = true;
break;
}
} catch {
// Try next
}
}
if (!chatJoinClicked) {
_log('warn', '"Join" button in chat header not found');
}
// Wait for the meeting to load after clicking Join
if (chatJoinClicked) {
_log('info', 'Waiting for meeting view to load...');
await page.waitForTimeout(5000);
// Wait for meeting UI elements (hangup button, video controls, etc.)
try {
await page.waitForSelector(
'button[id="hangup-button"], button[data-tid="hangup-button"], [data-tid="prejoin-join-button"], [data-tid="calling-prejoin"]',
{ timeout: 30000, state: 'visible' },
);
_log('info', 'Meeting UI elements detected');
} catch {
_log('warn', 'Meeting UI elements not found after 30s');
}
await page.waitForTimeout(5000);
}
await _screenshotStep('7 - Nach Join (Meeting-Ansicht)');
// Log all visible buttons on the final page for debugging
_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');
@ -590,10 +314,120 @@ async function _runVariant(
return `[BUTTON tid="${tid}"] ${text}`;
});
});
buttons.forEach(b => _log('info', ` Final page button: ${b}`));
} catch {
// Ignore
buttons.forEach(b => _log('info', ` ${b}`));
} catch { /* ignore */ }
}
await _screenshotStep('2 - Teams Chat');
// =====================================================================
// 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"]',
];
let chatJoinClicked = false;
for (const selector of chatJoinSelectors) {
try {
const btn = await page.waitForSelector(selector, { timeout: 5000, state: 'visible' });
if (btn) {
await btn.click();
_log('info', `Clicked: ${selector}`);
chatJoinClicked = true;
break;
}
} catch { /* try next */ }
}
if (!chatJoinClicked) {
_log('warn', '"Join" button in chat header not found');
}
// Wait for pre-join screen (camera preview, "Join now" button)
if (chatJoinClicked) {
_log('info', 'Waiting for pre-join screen...');
try {
await page.waitForSelector(
'button:has-text("Join now"), button:has-text("Jetzt teilnehmen"), button[data-tid="prejoin-join-button"]',
{ timeout: 30000, state: 'visible' },
);
_log('info', 'Pre-join screen loaded');
} catch {
_log('warn', 'Pre-join "Join now" button not found after 30s');
}
await page.waitForTimeout(2000);
}
await _screenshotStep('3 - Pre-Join Ansicht');
// =====================================================================
// 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');
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', ` Final: ${b}`));
} catch { /* ignore */ }
// =====================================================================
// FINAL: Log result