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:
parent
f7e0c194d5
commit
d93f10d211
1 changed files with 101 additions and 58 deletions
|
|
@ -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<LaunchResult> {
|
||||
_requireDisplay();
|
||||
return _launchChromiumHeadful(_BROWSER_ARGS_CLEAN);
|
||||
async function _launchBrowserForVariant(variant: AuthTestVariant): Promise<LaunchResult> {
|
||||
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<LaunchResult> {
|
|||
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
|
||||
// ============================================================================
|
||||
|
|
|
|||
Loading…
Reference in a new issue