diff --git a/src/bot/authTestProcedure.ts b/src/bot/authTestProcedure.ts index e10c0f3..ac95458 100644 --- a/src/bot/authTestProcedure.ts +++ b/src/bot/authTestProcedure.ts @@ -49,14 +49,29 @@ export interface AuthTestResults { const _VARIANTS: AuthTestVariant[] = [ { - id: 'signIn', - name: 'Pfad: Sign in', - description: 'Nach Login auf Teams-Landingpage "Sign in" klicken — was kommt?', + id: 'chromiumClean', + name: '1) Chromium Headful Clean', + description: 'Playwright Chromium headful, enhanced stealth + realistic devices', }, { - id: 'joinMeeting', - name: 'Pfad: Join a meeting', - description: 'Nach Login auf Teams-Landingpage "Join a meeting" klicken — was kommt?', + id: 'chromiumNoAutomation', + name: '2) Chromium No-Automation', + description: 'Chromium headful + --disable-extensions, --no-first-run', + }, + { + id: 'rebrowserHeadful', + name: '3) rebrowser-playwright', + description: 'rebrowser-playwright headful, CDP-Leak-Fixes + realistic devices', + }, + { + id: 'chromiumMinimal', + name: '4) Chromium Minimal', + description: 'Chromium headful, nur --no-sandbox (minimale Stealth)', + }, + { + id: 'chromiumHeadless', + name: '5) Chromium Headless', + description: 'Chromium headless als Baseline-Vergleich', }, ]; @@ -86,13 +101,19 @@ const _BROWSER_ARGS_NO_AUTOMATION = [ '--disable-component-update', ]; +// Minimal args — just --no-sandbox, no stealth +const _BROWSER_ARGS_MINIMAL = [ + '--no-sandbox', + '--use-fake-ui-for-media-stream', +]; + // ============================================================================ // MAIN EXPORT // ============================================================================ /** - * Run auth tests: 2 variants — "Sign in" and "Join a meeting" on the Teams landing page. - * Both do full Microsoft login first, then click different buttons to see what page loads. + * Run auth tests: 5 browser configs, all running the "Join a meeting" flow. + * Each variant: MS login → Teams landing page → "Join a meeting" → enter meeting ID + passcode → Join → screenshot. */ export async function runAuthTests( meetingUrl: string, @@ -155,8 +176,8 @@ async function _runVariant( }; try { - // Always use Chromium Headful Clean for both variants - const launchResult = await _launchChromiumHeadful(_BROWSER_ARGS_CLEAN); + // Launch browser based on variant + const launchResult = await _launchBrowserForVariant(variant); browser = launchResult.browser; context = launchResult.context; const page = launchResult.page; @@ -292,51 +313,9 @@ async function _runVariant( } // ===================================================================== - // STEP 4: Click variant-specific button + // STEP 4: Click "Join a meeting" // ===================================================================== - if (variant.id === 'signIn') { - // --- VARIANT A: Click "Sign in" --- - _log('info', 'Step 3: Clicking "Sign in" on Teams landing page...'); - const signInSelectors = [ - 'button:has-text("Sign in")', - 'button:has-text("Anmelden")', - 'a:has-text("Sign in")', - 'a:has-text("Anmelden")', - ]; - - let clicked = false; - for (const selector of signInSelectors) { - 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', '"Sign in" button not found on landing page'); - } - - // Wait for the resulting page to FULLY load - _log('info', 'Waiting for resulting page to fully load...'); - await page.waitForTimeout(5000); - try { - await page.waitForLoadState('networkidle', { timeout: 20000 }); - } catch { - _log('warn', 'networkidle timeout, continuing'); - } - await page.waitForTimeout(5000); - await _screenshotStep('3 - Nach "Sign in"'); - - } else if (variant.id === 'joinMeeting') { - // --- VARIANT B: Click "Join a meeting" --- - _log('info', 'Step 3: Clicking "Join a meeting" on Teams landing page...'); + _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")', @@ -499,7 +478,6 @@ async function _runVariant( await page.waitForTimeout(10000); } await _screenshotStep('5 - Nach Join meeting'); - } // ===================================================================== // FINAL: Log result @@ -580,9 +558,31 @@ interface LaunchResult { page: Page; } -async function _launchBrowserForVariant(_variant: AuthTestVariant): Promise { - _requireDisplay(); - return _launchChromiumHeadful(_BROWSER_ARGS_CLEAN); +async function _launchBrowserForVariant(variant: AuthTestVariant): Promise { + switch (variant.id) { + case 'chromiumClean': + _requireDisplay(); + return _launchChromiumHeadful(_BROWSER_ARGS_CLEAN); + + case 'chromiumNoAutomation': + _requireDisplay(); + return _launchChromiumHeadful(_BROWSER_ARGS_NO_AUTOMATION); + + case 'rebrowserHeadful': + _requireDisplay(); + return _launchRebrowserHeadful(); + + case 'chromiumMinimal': + _requireDisplay(); + return _launchChromiumMinimal(); + + case 'chromiumHeadless': + return _launchChromiumHeadless(); + + default: + _requireDisplay(); + return _launchChromiumHeadful(_BROWSER_ARGS_CLEAN); + } } /** @@ -658,6 +658,49 @@ async function _launchRebrowserHeadful(): Promise { return { browser, context, page }; } +/** + * Launch Chromium headful with minimal args — no stealth, just --no-sandbox. + */ +async function _launchChromiumMinimal(): Promise { + const browser = await chromium.launch({ + headless: false, + args: _BROWSER_ARGS_MINIMAL, + }); + + const context = await browser.newContext({ + permissions: ['microphone', 'camera'], + viewport: { width: 1920, height: 1080 }, + userAgent: _USER_AGENT, + }); + + const page = await context.newPage(); + await page.addInitScript(_getDeviceSpoofScript); + + return { browser, context, page }; +} + +/** + * Launch Chromium headless — baseline comparison. + */ +async function _launchChromiumHeadless(): Promise { + const browser = await chromium.launch({ + headless: true, + args: _BROWSER_ARGS_CLEAN, + }); + + const context = await browser.newContext({ + permissions: ['microphone', 'camera'], + viewport: { width: 1920, height: 1080 }, + userAgent: _USER_AGENT, + }); + + const page = await context.newPage(); + await page.addInitScript(_getEnhancedStealthScript); + await page.addInitScript(_getDeviceSpoofScript); + + return { browser, context, page }; +} + // ============================================================================ // STEALTH SCRIPTS // ============================================================================