fix: use exact data-tid=toggle-video selector for camera toggle on pre-join screen

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
ValueOn AG 2026-02-17 20:39:56 +01:00
parent 06ff78d2f8
commit 6647de8ae7

View file

@ -315,67 +315,62 @@ export class BotOrchestrator {
/** /**
* Ensure the camera is turned on in the pre-join screen. * Ensure the camera is turned on in the pre-join screen.
* When camera is on, Teams shows the profile/background image. * When camera is on, Teams shows the profile/background image.
*
* Teams pre-join uses a fui-Switch input:
* <input data-tid="toggle-video" role="switch" type="checkbox" checked>
* - checked present = camera ON (data-cid="toggle-video-true", title="Turn camera off")
* - checked absent = camera OFF (data-cid="toggle-video-false", title="Turn camera on")
*/ */
private async _ensureCameraOn(): Promise<void> { private async _ensureCameraOn(): Promise<void> {
try { try {
// Try multiple selectors for the camera toggle // Primary: the actual switch input (fui-Switch)
const cameraSelectors = [ let cameraToggle = await this._page!.$('input[data-tid="toggle-video"]');
'button[data-tid="toggle-video"]',
'button[aria-label*="camera" i]',
'button[aria-label*="Camera" i]',
'button[aria-label*="Video" i]',
'#video-toggle-button',
'[data-tid="prejoin-camera-toggle"]',
];
let cameraBtn = null; if (!cameraToggle) {
let matchedSelector = ''; this._logger.info('Primary camera selector not found, trying fallbacks...');
for (const sel of cameraSelectors) { const fallbacks = [
cameraBtn = await this._page!.$(sel); '[data-tid="toggle-video"]',
if (cameraBtn) { 'input[role="switch"][title*="camera" i]',
matchedSelector = sel; 'input[role="switch"][title*="Camera" i]',
'input[role="switch"][title*="Video" i]',
];
for (const sel of fallbacks) {
cameraToggle = await this._page!.$(sel);
if (cameraToggle) {
this._logger.info(`Camera toggle found via fallback: ${sel}`);
break; break;
} }
} }
}
if (!cameraBtn) { if (!cameraToggle) {
this._logger.warn('Camera toggle button not found with any selector'); this._logger.warn('Camera toggle not found on pre-join screen');
return; return;
} }
// Log button details for debugging // Read current state
const btnInfo = await cameraBtn.evaluate((el) => { const state = await cameraToggle.evaluate((el: HTMLInputElement) => ({
return { checked: el.checked,
ariaLabel: el.getAttribute('aria-label') || '', dataCid: el.getAttribute('data-cid') || '',
ariaPressed: el.getAttribute('aria-pressed'),
ariaChecked: el.getAttribute('aria-checked'),
dataTid: el.getAttribute('data-tid') || '',
className: el.className?.substring(0, 80) || '',
title: el.getAttribute('title') || '', title: el.getAttribute('title') || '',
innerText: el.innerText?.trim()?.substring(0, 30) || '', }));
};
});
this._logger.info(`Camera button found: ${matchedSelector} | aria-label="${btnInfo.ariaLabel}" | aria-pressed=${btnInfo.ariaPressed} | title="${btnInfo.title}"`);
// Determine if camera is off — click to turn it ON this._logger.info(`Camera state: checked=${state.checked}, data-cid="${state.dataCid}", title="${state.title}"`);
// In Teams pre-join: aria-pressed="false" means camera is OFF
const shouldClick = btnInfo.ariaPressed === 'false' || btnInfo.ariaChecked === 'false';
if (shouldClick) { if (!state.checked) {
await cameraBtn.click(); // Camera is OFF — click to turn ON
this._logger.info('Camera toggled ON (was off)'); await cameraToggle.click();
this._logger.info('Camera toggled ON');
await this._page!.waitForTimeout(2000); await this._page!.waitForTimeout(2000);
// Verify the toggle worked // Verify
const afterState = await cameraBtn.evaluate((el) => el.getAttribute('aria-pressed')); const afterState = await cameraToggle.evaluate((el: HTMLInputElement) => ({
this._logger.info(`Camera state after toggle: aria-pressed=${afterState}`); checked: el.checked,
} else if (btnInfo.ariaPressed === null && btnInfo.ariaChecked === null) { dataCid: el.getAttribute('data-cid') || '',
// No aria state — click anyway to turn camera on (safe default) }));
await cameraBtn.click(); this._logger.info(`Camera after toggle: checked=${afterState.checked}, data-cid="${afterState.dataCid}"`);
this._logger.info('Camera clicked (no aria state detected, assuming toggle)');
await this._page!.waitForTimeout(2000);
} else { } else {
this._logger.info('Camera already ON (aria-pressed=true)'); this._logger.info('Camera already ON');
} }
} catch (err) { } catch (err) {
this._logger.warn(`Could not toggle camera: ${err}`); this._logger.warn(`Could not toggle camera: ${err}`);