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

master
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);
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
// const screenshareButton = await utils.waitForElement('#screenshare-btn');
// expect(await screenshareButton.isDisplayed()).toBeTrue();
// await screenshareButton.click();
it('should NOT have multiple screens pinned when both participants share screen', async () => {
const roomName = 'pinBugCase1';
const fixedUrl = `${url}&roomName=${roomName}&prejoin=false`;
// await utils.waitForElement('.OV_big');
// expect(await utils.getNumberOfElements('video')).toEqual(2);
// Participant A joins and shares screen
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');
// await muteVideoButton.click();
// Verify A's screen is pinned
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 () => {
// let isAudioEnabled;
// const audioEnableScript = 'return document.getElementsByTagName("video")[0].srcObject.getAudioTracks()[0].enabled;';
// B should see A's screen pinned
expect(await utils.getNumberOfElements('video')).toEqual(3); // 2 cameras + 1 screen
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
// const screenshareButton = await utils.waitForElement('#screenshare-btn');
// expect(await utils.isPresent('#screenshare-btn')).toBeTrue();
// await screenshareButton.click();
// Switch to Tab A and check
await browser.switchTo().window(tabs[0]);
await browser.sleep(1000);
expect(await utils.getNumberOfElements('video')).toEqual(4); // 2 cameras + 2 screens
// await utils.waitForElement('.OV_big');
// expect(await utils.getNumberOfElements('video')).toEqual(2);
// expect(await utils.getNumberOfElements('#status-mic')).toEqual(1);
// BUG: In A's view, BOTH screens are pinned
const pinnedCountA2 = await utils.getNumberOfPinnedStreams();
console.log(`[Tab A] After B shares: ${pinnedCountA2} pinned stream(s)`);
// // Muting camera video
// const muteVideoButton = await utils.waitForElement('#camera-btn');
// await muteVideoButton.click();
// EXPECTED: Only B's screen should be pinned (the most recent one)
// ACTUAL: Both A's and B's screens are pinned
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 () => {
const roomName = 'pinBugCase2';
const fixedUrl = `${url}&roomName=${roomName}&prejoin=false`;
// await browser.sleep(500);
// expect(await utils.isPresent('#status-mic')).toBeFalse();
// Participant A joins and shares screen
await browser.get(fixedUrl);
await utils.checkLayoutPresent();
await utils.waitForElement('#screenshare-btn');
await utils.clickOn('#screenshare-btn');
await browser.sleep(500);
// // Checking if audio is muted after join the room
// isAudioEnabled = await browser.executeScript(audioEnableScript);
// expect(isAudioEnabled).toBeTrue();
// Verify A's screen is auto-pinned
await utils.waitForElement('.OV_big');
expect(await utils.getNumberOfPinnedStreams()).toEqual(1);
// // Unmuting camera
// await muteVideoButton.click();
// await browser.sleep(1000);
// Participant B joins and shares screen
const tabs = await utils.openTab(fixedUrl);
await browser.switchTo().window(tabs[1]);
await utils.checkLayoutPresent();
await browser.sleep(1000);
await utils.waitForElement('#screenshare-btn');
await utils.clickOn('#screenshare-btn');
await browser.sleep(500);
// await utils.waitForElement('.camera-type');
// expect(await utils.getNumberOfElements('video')).toEqual(2);
// expect(await utils.getNumberOfElements('#status-mic')).toEqual(1);
// });
// B should see their own screen pinned
expect(await utils.getNumberOfElements('video')).toEqual(4); // 2 cameras + 2 screens
await utils.waitForElement('.OV_big');
let pinnedCountB = await utils.getNumberOfPinnedStreams();
console.log(`[Tab B] After B shares: ${pinnedCountB} pinned stream(s)`);
// it('should camera come back with audio muted when screensharing', async () => {
// let element, isAudioEnabled;
// B manually unpins their own screen
const screenStreams = await utils.getScreenShareStreams();
if (screenStreams.length > 0) {
// Find B's own screen (it should be the pinned one)
await utils.toggleStreamPin('.OV_big');
await browser.sleep(500);
}
// const getAudioScript = (className: string) => {
// return `return document.getElementsByClassName('${className}')[0].srcObject.getAudioTracks()[0].enabled;`;
// };
// Verify B's screen is now unpinned
pinnedCountB = await utils.getNumberOfPinnedStreams();
console.log(`[Tab B] After manually unpinning B's screen: ${pinnedCountB} pinned stream(s)`);
expect(pinnedCountB).toEqual(0, 'B should have no pinned streams after manual unpin');
// await browser.get(`${url}&prejoin=false`);
// B manually pins A's screen
const screenElements = await utils.getScreenShareStreams();
if (screenElements.length >= 2) {
// Pin the first screen that is not already pinned (should be A's screen)
await utils.toggleStreamPin('.OV_stream.remote .screen-type');
await utils.toggleStreamPin('#pin-btn');
await browser.sleep(500);
}
// await utils.checkLayoutPresent();
// Verify A's screen is now pinned in B's view
pinnedCountB = await utils.getNumberOfPinnedStreams();
console.log(`[Tab B] After manually pinning A's screen: ${pinnedCountB} pinned stream(s)`);
expect(pinnedCountB).toEqual(1, "Only A's screen should be pinned");
// // Clicking to screensharing button
// const screenshareButton = await utils.waitForElement('#screenshare-btn');
// await screenshareButton.click();
// Participant C joins the room
const tab3 = await utils.openTab(fixedUrl);
await browser.switchTo().window(tab3[2]);
await utils.checkLayoutPresent();
await browser.sleep(1500);
// await utils.waitForElement('.screen-type');
// expect(await utils.getNumberOfElements('video')).toEqual(2);
// expect(await utils.getNumberOfElements('#status-mic')).toEqual(1);
// Switch back to B's tab
await browser.switchTo().window(tabs[1]);
await browser.sleep(1000);
// // Mute camera
// const muteVideoButton = await utils.waitForElement('#camera-btn');
// await muteVideoButton.click();
// 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)`);
// expect(await utils.getNumberOfElements('video')).toEqual(1);
// expect(await utils.isPresent('#status-mic')).toBeFalse();
// 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.');
// // Checking if audio is muted after join the room
// isAudioEnabled = await browser.executeScript(getAudioScript('screen-type'));
// expect(isAudioEnabled).toBeTrue();
// Switch back to A's tab to verify
await browser.switchTo().window(tabs[0]);
await browser.sleep(500);
// // Mute audio
// const muteAudioButton = await utils.waitForElement('#mic-btn');
// await muteAudioButton.click();
const pinnedCountA2 = await utils.getNumberOfPinnedStreams();
console.log(`[Tab A] After C joins: ${pinnedCountA2} pinned stream(s)`);
// await utils.waitForElement('#status-mic');
// expect(await utils.getNumberOfElements('#status-mic')).toEqual(1);
// isAudioEnabled = await browser.executeScript(getAudioScript('screen-type'));
// expect(isAudioEnabled).toBeFalse();
// // Unmute camera
// await muteVideoButton.click();
// await utils.waitForElement('.camera-type');
// expect(await utils.getNumberOfElements('video')).toEqual(2);
// expect(await utils.getNumberOfElements('#status-mic')).toEqual(2);
// isAudioEnabled = await browser.executeScript(getAudioScript('camera-type'));
// expect(isAudioEnabled).toBeFalse();
// });
// 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));
// 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'));
}
}