ov-components: Enhance screensharing tests to address pinning bugs and add utility methods for stream management

pull/856/head
Carlos Santos 2025-11-14 13:30:47 +01:00
parent 19a5c21162
commit 5a99839ed7
2 changed files with 165 additions and 81 deletions

View File

@ -205,112 +205,151 @@ describe('E2E: Screensharing features', () => {
await browser.sleep(500); await browser.sleep(500);
expect(await utils.getNumberOfElements('video')).toEqual(1); expect(await utils.getNumberOfElements('video')).toEqual(1);
}); });
// it('should show and hide CAMERA stream when muting video with screensharing', async () => {
// await browser.get(`${url}&prejoin=false`);
// await utils.checkLayoutPresent(); // ==================== PIN/UNPIN TESTS ====================
// These tests demonstrate bugs in the pin system:
// 1. Multiple screens can be auto-pinned simultaneously
// 2. Manual unpins can be overridden by auto-pin logic when participants join
// // Clicking to screensharing button it('should NOT have multiple screens pinned when both participants share screen', async () => {
// const screenshareButton = await utils.waitForElement('#screenshare-btn'); const roomName = 'pinBugCase1';
// expect(await screenshareButton.isDisplayed()).toBeTrue(); const fixedUrl = `${url}&roomName=${roomName}&prejoin=false`;
// await screenshareButton.click();
// await utils.waitForElement('.OV_big'); // Participant A joins and shares screen
// expect(await utils.getNumberOfElements('video')).toEqual(2); await browser.get(fixedUrl);
await utils.checkLayoutPresent();
await utils.waitForElement('#screenshare-btn');
await utils.clickOn('#screenshare-btn');
await browser.sleep(500);
// const muteVideoButton = await utils.waitForElement('#camera-btn'); // Verify A's screen is pinned
// await muteVideoButton.click(); await utils.waitForElement('.OV_big');
expect(await utils.getNumberOfPinnedStreams()).toEqual(1);
const pinnedCountA1 = await utils.getNumberOfPinnedStreams();
console.log(`[Tab A] After A shares: ${pinnedCountA1} pinned stream(s)`);
// expect(await utils.getNumberOfElements('video')).toEqual(1); // Participant B joins
// }); const tabs = await utils.openTab(fixedUrl);
await browser.switchTo().window(tabs[1]);
await utils.checkLayoutPresent();
await browser.sleep(1000);
// it('should screenshare has audio active when camera is muted', async () => { // B should see A's screen pinned
// let isAudioEnabled; expect(await utils.getNumberOfElements('video')).toEqual(3); // 2 cameras + 1 screen
// const audioEnableScript = 'return document.getElementsByTagName("video")[0].srcObject.getAudioTracks()[0].enabled;'; expect(await utils.getNumberOfPinnedStreams()).toEqual(1);
const pinnedCountB1 = await utils.getNumberOfPinnedStreams();
console.log(`[Tab B] After B joins: ${pinnedCountB1} pinned stream(s)`);
// await browser.get(`${url}&prejoin=false`); // B shares screen
await utils.waitForElement('#screenshare-btn');
await utils.clickOn('#screenshare-btn');
await browser.sleep(500);
// await utils.checkLayoutPresent(); // B should see only their own screen pinned (auto-pin + unpin previous)
expect(await utils.getNumberOfElements('video')).toEqual(4); // 2 cameras + 2 screens
await utils.waitForElement('.OV_big');
const pinnedCountB2 = await utils.getNumberOfPinnedStreams();
console.log(`[Tab B] After B shares: ${pinnedCountB2} pinned stream(s)`);
expect(pinnedCountB2).toEqual(1); // Should be 1, but implementation might show different
// // Clicking to screensharing button // Switch to Tab A and check
// const screenshareButton = await utils.waitForElement('#screenshare-btn'); await browser.switchTo().window(tabs[0]);
// expect(await utils.isPresent('#screenshare-btn')).toBeTrue(); await browser.sleep(1000);
// await screenshareButton.click(); expect(await utils.getNumberOfElements('video')).toEqual(4); // 2 cameras + 2 screens
// await utils.waitForElement('.OV_big'); // BUG: In A's view, BOTH screens are pinned
// expect(await utils.getNumberOfElements('video')).toEqual(2); const pinnedCountA2 = await utils.getNumberOfPinnedStreams();
// expect(await utils.getNumberOfElements('#status-mic')).toEqual(1); console.log(`[Tab A] After B shares: ${pinnedCountA2} pinned stream(s)`);
// // Muting camera video // EXPECTED: Only B's screen should be pinned (the most recent one)
// const muteVideoButton = await utils.waitForElement('#camera-btn'); // ACTUAL: Both A's and B's screens are pinned
// await muteVideoButton.click(); expect(pinnedCountA2).toEqual(1, 'BUG DETECTED: Multiple screens are pinned. Expected only the most recent screen to be pinned.');
});
// expect(await utils.getNumberOfElements('video')).toEqual(1);
it('should NOT re-pin manually unpinned screen when new participant joins', async () => {
// await browser.sleep(500); const roomName = 'pinBugCase2';
// expect(await utils.isPresent('#status-mic')).toBeFalse(); const fixedUrl = `${url}&roomName=${roomName}&prejoin=false`;
// // Checking if audio is muted after join the room // Participant A joins and shares screen
// isAudioEnabled = await browser.executeScript(audioEnableScript); await browser.get(fixedUrl);
// expect(isAudioEnabled).toBeTrue(); await utils.checkLayoutPresent();
await utils.waitForElement('#screenshare-btn');
// // Unmuting camera await utils.clickOn('#screenshare-btn');
// await muteVideoButton.click(); await browser.sleep(500);
// await browser.sleep(1000);
// Verify A's screen is auto-pinned
// await utils.waitForElement('.camera-type'); await utils.waitForElement('.OV_big');
// expect(await utils.getNumberOfElements('video')).toEqual(2); expect(await utils.getNumberOfPinnedStreams()).toEqual(1);
// expect(await utils.getNumberOfElements('#status-mic')).toEqual(1);
// }); // Participant B joins and shares screen
const tabs = await utils.openTab(fixedUrl);
// it('should camera come back with audio muted when screensharing', async () => { await browser.switchTo().window(tabs[1]);
// let element, isAudioEnabled; await utils.checkLayoutPresent();
await browser.sleep(1000);
// const getAudioScript = (className: string) => { await utils.waitForElement('#screenshare-btn');
// return `return document.getElementsByClassName('${className}')[0].srcObject.getAudioTracks()[0].enabled;`; await utils.clickOn('#screenshare-btn');
// }; await browser.sleep(500);
// await browser.get(`${url}&prejoin=false`); // B should see their own screen pinned
expect(await utils.getNumberOfElements('video')).toEqual(4); // 2 cameras + 2 screens
// await utils.checkLayoutPresent(); await utils.waitForElement('.OV_big');
let pinnedCountB = await utils.getNumberOfPinnedStreams();
// // Clicking to screensharing button console.log(`[Tab B] After B shares: ${pinnedCountB} pinned stream(s)`);
// const screenshareButton = await utils.waitForElement('#screenshare-btn');
// await screenshareButton.click(); // B manually unpins their own screen
const screenStreams = await utils.getScreenShareStreams();
// await utils.waitForElement('.screen-type'); if (screenStreams.length > 0) {
// expect(await utils.getNumberOfElements('video')).toEqual(2); // Find B's own screen (it should be the pinned one)
// expect(await utils.getNumberOfElements('#status-mic')).toEqual(1); await utils.toggleStreamPin('.OV_big');
await browser.sleep(500);
// // Mute camera }
// const muteVideoButton = await utils.waitForElement('#camera-btn');
// await muteVideoButton.click(); // Verify B's screen is now unpinned
pinnedCountB = await utils.getNumberOfPinnedStreams();
// expect(await utils.getNumberOfElements('video')).toEqual(1); console.log(`[Tab B] After manually unpinning B's screen: ${pinnedCountB} pinned stream(s)`);
// expect(await utils.isPresent('#status-mic')).toBeFalse(); expect(pinnedCountB).toEqual(0, 'B should have no pinned streams after manual unpin');
// // Checking if audio is muted after join the room // B manually pins A's screen
// isAudioEnabled = await browser.executeScript(getAudioScript('screen-type')); const screenElements = await utils.getScreenShareStreams();
// expect(isAudioEnabled).toBeTrue(); if (screenElements.length >= 2) {
// Pin the first screen that is not already pinned (should be A's screen)
// // Mute audio await utils.toggleStreamPin('.OV_stream.remote .screen-type');
// const muteAudioButton = await utils.waitForElement('#mic-btn'); await utils.toggleStreamPin('#pin-btn');
// await muteAudioButton.click(); await browser.sleep(500);
}
// await utils.waitForElement('#status-mic');
// expect(await utils.getNumberOfElements('#status-mic')).toEqual(1); // Verify A's screen is now pinned in B's view
pinnedCountB = await utils.getNumberOfPinnedStreams();
// isAudioEnabled = await browser.executeScript(getAudioScript('screen-type')); console.log(`[Tab B] After manually pinning A's screen: ${pinnedCountB} pinned stream(s)`);
// expect(isAudioEnabled).toBeFalse(); expect(pinnedCountB).toEqual(1, "Only A's screen should be pinned");
// // Unmute camera // Participant C joins the room
// await muteVideoButton.click(); const tab3 = await utils.openTab(fixedUrl);
await browser.switchTo().window(tab3[2]);
// await utils.waitForElement('.camera-type'); await utils.checkLayoutPresent();
// expect(await utils.getNumberOfElements('video')).toEqual(2); await browser.sleep(1500);
// expect(await utils.getNumberOfElements('#status-mic')).toEqual(2);
// Switch back to B's tab
// isAudioEnabled = await browser.executeScript(getAudioScript('camera-type')); await browser.switchTo().window(tabs[1]);
// expect(isAudioEnabled).toBeFalse(); await browser.sleep(1000);
// });
// B's screen should still be unpinned, but might get re-pinned automatically
pinnedCountB = await utils.getNumberOfPinnedStreams();
console.log(`[Tab B] After C joins: ${pinnedCountB} pinned stream(s)`);
// EXPECTED: No screens should be pinned (B manually unpinned everything)
// ACTUAL: B's screen gets re-pinned automatically
expect(pinnedCountB).toEqual(1, 'BUG DETECTED: Only one screen should be pinned after C joins.');
// Switch back to A's tab to verify
await browser.switchTo().window(tabs[0]);
await browser.sleep(500);
const pinnedCountA2 = await utils.getNumberOfPinnedStreams();
console.log(`[Tab A] After C joins: ${pinnedCountA2} pinned stream(s)`);
// EXPECTED: Only A's screen should be pinned
// ACTUAL: A's screen remains pinned
expect(pinnedCountA2).toEqual(1, "BUG DETECTED: A's screen should remain pinned after C joins.");
});
}); });

View File

@ -279,4 +279,49 @@ export class OpenViduComponentsPO {
// fs.writeFileSync('diff.png', PNG.sync.write(diff)); // fs.writeFileSync('diff.png', PNG.sync.write(diff));
// expect(numDiffPixels).to.be.greaterThan(500, 'The virtual background was not applied correctly'); // expect(numDiffPixels).to.be.greaterThan(500, 'The virtual background was not applied correctly');
} }
/**
* Pins or unpins a stream by clicking on it
* @param streamSelector CSS selector for the stream element (e.g., '.screen-type', '.camera-type')
*/
async toggleStreamPin(streamSelector: string): Promise<void> {
const stream = await this.waitForElement(streamSelector);
await stream.click();
await this.browser.sleep(300);
}
/**
* Gets the number of pinned streams (elements with class .OV_big)
*/
async getNumberOfPinnedStreams(): Promise<number> {
return await this.getNumberOfElements('.OV_big');
}
/**
* Checks if a specific stream is pinned
* @param streamSelector CSS selector for the stream element
*/
async isStreamPinned(streamSelector: string): Promise<boolean> {
try {
const stream = await this.waitForElement(streamSelector);
const classes = await stream.getAttribute('class');
return classes.includes('OV_big');
} catch (error) {
return false;
}
}
/**
* Gets all screen share streams
*/
async getScreenShareStreams(): Promise<WebElement[]> {
return await this.browser.findElements(By.css('.screen-type'));
}
/**
* Gets all camera streams
*/
async getCameraStreams(): Promise<WebElement[]> {
return await this.browser.findElements(By.css('.camera-type'));
}
} }