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:
parent
06ff78d2f8
commit
6647de8ae7
1 changed files with 41 additions and 46 deletions
|
|
@ -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}`);
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue