refactor: 5 browser variants all running Join a meeting flow, remove Sign in path

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
ValueOn AG 2026-02-17 12:51:16 +01:00
parent f7e0c194d5
commit d93f10d211

View file

@ -49,14 +49,29 @@ export interface AuthTestResults {
const _VARIANTS: AuthTestVariant[] = [ const _VARIANTS: AuthTestVariant[] = [
{ {
id: 'signIn', id: 'chromiumClean',
name: 'Pfad: Sign in', name: '1) Chromium Headful Clean',
description: 'Nach Login auf Teams-Landingpage "Sign in" klicken — was kommt?', description: 'Playwright Chromium headful, enhanced stealth + realistic devices',
}, },
{ {
id: 'joinMeeting', id: 'chromiumNoAutomation',
name: 'Pfad: Join a meeting', name: '2) Chromium No-Automation',
description: 'Nach Login auf Teams-Landingpage "Join a meeting" klicken — was kommt?', 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', '--disable-component-update',
]; ];
// Minimal args — just --no-sandbox, no stealth
const _BROWSER_ARGS_MINIMAL = [
'--no-sandbox',
'--use-fake-ui-for-media-stream',
];
// ============================================================================ // ============================================================================
// MAIN EXPORT // MAIN EXPORT
// ============================================================================ // ============================================================================
/** /**
* Run auth tests: 2 variants "Sign in" and "Join a meeting" on the Teams landing page. * Run auth tests: 5 browser configs, all running the "Join a meeting" flow.
* Both do full Microsoft login first, then click different buttons to see what page loads. * Each variant: MS login Teams landing page "Join a meeting" enter meeting ID + passcode Join screenshot.
*/ */
export async function runAuthTests( export async function runAuthTests(
meetingUrl: string, meetingUrl: string,
@ -155,8 +176,8 @@ async function _runVariant(
}; };
try { try {
// Always use Chromium Headful Clean for both variants // Launch browser based on variant
const launchResult = await _launchChromiumHeadful(_BROWSER_ARGS_CLEAN); const launchResult = await _launchBrowserForVariant(variant);
browser = launchResult.browser; browser = launchResult.browser;
context = launchResult.context; context = launchResult.context;
const page = launchResult.page; 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') { _log('info', 'Step 4: Clicking "Join a meeting" on Teams landing page...');
// --- 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...');
const joinSelectors = [ const joinSelectors = [
'button:has-text("Join a meeting")', 'button:has-text("Join a meeting")',
'button:has-text("An Besprechung teilnehmen")', 'button:has-text("An Besprechung teilnehmen")',
@ -499,7 +478,6 @@ async function _runVariant(
await page.waitForTimeout(10000); await page.waitForTimeout(10000);
} }
await _screenshotStep('5 - Nach Join meeting'); await _screenshotStep('5 - Nach Join meeting');
}
// ===================================================================== // =====================================================================
// FINAL: Log result // FINAL: Log result
@ -580,9 +558,31 @@ interface LaunchResult {
page: Page; page: Page;
} }
async function _launchBrowserForVariant(_variant: AuthTestVariant): Promise<LaunchResult> { async function _launchBrowserForVariant(variant: AuthTestVariant): Promise<LaunchResult> {
_requireDisplay(); switch (variant.id) {
return _launchChromiumHeadful(_BROWSER_ARGS_CLEAN); 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<LaunchResult> {
return { browser, context, page }; return { browser, context, page };
} }
/**
* Launch Chromium headful with minimal args no stealth, just --no-sandbox.
*/
async function _launchChromiumMinimal(): Promise<LaunchResult> {
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<LaunchResult> {
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 // STEALTH SCRIPTS
// ============================================================================ // ============================================================================