Some checks failed
Close stale issues and PRs / stale (push) Has been cancelled
482 lines
16 KiB
TypeScript
482 lines
16 KiB
TypeScript
import type { ChainablePromiseElement } from 'webdriverio';
|
|
|
|
import type { Participant } from '../../helpers/Participant';
|
|
import {
|
|
checkSubject,
|
|
ensureThreeParticipants,
|
|
ensureTwoParticipants,
|
|
hangupAllParticipants
|
|
} from '../../helpers/participants';
|
|
|
|
const MAIN_ROOM_NAME = 'Main room';
|
|
const BREAKOUT_ROOMS_LIST_ID = 'breakout-rooms-list';
|
|
const LIST_ITEM_CONTAINER = 'list-item-container';
|
|
|
|
describe('BreakoutRooms', () => {
|
|
it('check support', async () => {
|
|
await ensureTwoParticipants();
|
|
|
|
if (!await ctx.p1.isBreakoutRoomsSupported()) {
|
|
ctx.skipSuiteTests = true;
|
|
}
|
|
});
|
|
|
|
it('add breakout room', async () => {
|
|
const { p1, p2 } = ctx;
|
|
const p1BreakoutRooms = p1.getBreakoutRooms();
|
|
|
|
// there should be no breakout rooms initially, list is sent with a small delay
|
|
await p1.driver.pause(2000);
|
|
expect(await p1BreakoutRooms.getRoomsCount()).toBe(0);
|
|
|
|
// add one breakout room
|
|
await p1BreakoutRooms.addBreakoutRoom();
|
|
|
|
await p1.driver.waitUntil(
|
|
async () => await p1BreakoutRooms.getRoomsCount() === 1, {
|
|
timeout: 3000,
|
|
timeoutMsg: 'No breakout room added for p1'
|
|
});
|
|
|
|
|
|
// second participant should also see one breakout room
|
|
await p2.driver.waitUntil(
|
|
async () => await p2.getBreakoutRooms().getRoomsCount() === 1, {
|
|
timeout: 3000,
|
|
timeoutMsg: 'No breakout room seen by p2'
|
|
});
|
|
});
|
|
|
|
it('join breakout room', async () => {
|
|
const { p1, p2 } = ctx;
|
|
const p1BreakoutRooms = p1.getBreakoutRooms();
|
|
|
|
// there should be one breakout room
|
|
await p1.driver.waitUntil(
|
|
async () => await p1BreakoutRooms.getRoomsCount() === 1, {
|
|
timeout: 3000,
|
|
timeoutMsg: 'No breakout room seen by p1'
|
|
});
|
|
|
|
const roomsList = await p1BreakoutRooms.getRooms();
|
|
|
|
expect(roomsList.length).toBe(1);
|
|
|
|
// join the room
|
|
await roomsList[0].joinRoom();
|
|
|
|
// the participant should see the main room as the only breakout room
|
|
await p1.driver.waitUntil(
|
|
async () => {
|
|
if (await p1BreakoutRooms.getRoomsCount() !== 1) {
|
|
return false;
|
|
}
|
|
|
|
const list = await p1BreakoutRooms.getRooms();
|
|
|
|
if (list?.length !== 1) {
|
|
return false;
|
|
}
|
|
|
|
return list[0].name === MAIN_ROOM_NAME;
|
|
}, {
|
|
timeout: 5000,
|
|
timeoutMsg: 'P1 did not join breakout room'
|
|
});
|
|
|
|
// the second participant should see one participant in the breakout room
|
|
await p2.driver.waitUntil(
|
|
async () => {
|
|
const list = await p2.getBreakoutRooms().getRooms();
|
|
|
|
if (list?.length !== 1) {
|
|
return false;
|
|
}
|
|
|
|
return list[0].participantCount === 1;
|
|
}, {
|
|
timeout: 3000,
|
|
timeoutMsg: 'P2 is not seeing p1 in the breakout room'
|
|
});
|
|
});
|
|
|
|
it('leave breakout room', async () => {
|
|
const { p1, p2 } = ctx;
|
|
const p1BreakoutRooms = p1.getBreakoutRooms();
|
|
|
|
// leave room
|
|
await p1BreakoutRooms.leaveBreakoutRoom();
|
|
|
|
// there should be one breakout room and that should not be the main room
|
|
await p1.driver.waitUntil(
|
|
async () => {
|
|
if (await p1BreakoutRooms.getRoomsCount() !== 1) {
|
|
return false;
|
|
}
|
|
|
|
const list = await p1BreakoutRooms.getRooms();
|
|
|
|
if (list?.length !== 1) {
|
|
return false;
|
|
}
|
|
|
|
return list[0].name !== MAIN_ROOM_NAME;
|
|
}, {
|
|
timeout: 5000,
|
|
timeoutMsg: 'P1 did not leave breakout room'
|
|
});
|
|
|
|
// the second participant should see no participants in the breakout room
|
|
await p2.driver.waitUntil(
|
|
async () => {
|
|
const list = await p2.getBreakoutRooms().getRooms();
|
|
|
|
if (list?.length !== 1) {
|
|
return false;
|
|
}
|
|
|
|
return list[0].participantCount === 0;
|
|
}, {
|
|
timeout: 3000,
|
|
timeoutMsg: 'P2 is seeing p1 in the breakout room'
|
|
});
|
|
});
|
|
|
|
it('remove breakout room', async () => {
|
|
const { p1, p2 } = ctx;
|
|
const p1BreakoutRooms = p1.getBreakoutRooms();
|
|
|
|
// remove the room
|
|
await (await p1BreakoutRooms.getRooms())[0].removeRoom();
|
|
|
|
// there should be no breakout rooms
|
|
await p1.driver.waitUntil(
|
|
async () => await p1BreakoutRooms.getRoomsCount() === 0, {
|
|
timeout: 3000,
|
|
timeoutMsg: 'Breakout room was not removed for p1'
|
|
});
|
|
|
|
// the second participant should also see no breakout rooms
|
|
await p2.driver.waitUntil(
|
|
async () => await p2.getBreakoutRooms().getRoomsCount() === 0, {
|
|
timeout: 3000,
|
|
timeoutMsg: 'Breakout room was not removed for p2'
|
|
});
|
|
});
|
|
|
|
it('auto assign', async () => {
|
|
await ensureThreeParticipants();
|
|
const { p1, p2 } = ctx;
|
|
const p1BreakoutRooms = p1.getBreakoutRooms();
|
|
|
|
// create two rooms
|
|
await p1BreakoutRooms.addBreakoutRoom();
|
|
await p1BreakoutRooms.addBreakoutRoom();
|
|
|
|
// there should be two breakout rooms
|
|
await p1.driver.waitUntil(
|
|
async () => await p1BreakoutRooms.getRoomsCount() === 2, {
|
|
timeout: 3000,
|
|
timeoutMsg: 'Breakout room was not created by p1'
|
|
});
|
|
|
|
// auto assign participants to rooms
|
|
await p1BreakoutRooms.autoAssignToBreakoutRooms();
|
|
|
|
// each room should have one participant
|
|
await p1.driver.waitUntil(
|
|
async () => {
|
|
if (await p1BreakoutRooms.getRoomsCount() !== 2) {
|
|
return false;
|
|
}
|
|
|
|
const list = await p1BreakoutRooms.getRooms();
|
|
|
|
if (list?.length !== 2) {
|
|
return false;
|
|
}
|
|
|
|
return list[0].participantCount === 1 && list[1].participantCount === 1;
|
|
}, {
|
|
timeout: 5000,
|
|
timeoutMsg: 'P1 did not auto assigned participants to breakout rooms'
|
|
});
|
|
|
|
// the second participant should see one participant in the main room
|
|
const p2BreakoutRooms = p2.getBreakoutRooms();
|
|
|
|
await p2.driver.waitUntil(
|
|
async () => {
|
|
if (await p2BreakoutRooms.getRoomsCount() !== 2) {
|
|
return false;
|
|
}
|
|
|
|
const list = await p2BreakoutRooms.getRooms();
|
|
|
|
if (list?.length !== 2) {
|
|
return false;
|
|
}
|
|
|
|
return list[0].participantCount === 1 && list[1].participantCount === 1
|
|
&& (list[0].name === MAIN_ROOM_NAME || list[1].name === MAIN_ROOM_NAME);
|
|
}, {
|
|
timeout: 3000,
|
|
timeoutMsg: 'P2 is not seeing p1 in the main room'
|
|
});
|
|
});
|
|
|
|
it('close breakout room', async () => {
|
|
const { p1, p2, p3 } = ctx;
|
|
const p1BreakoutRooms = p1.getBreakoutRooms();
|
|
|
|
// there should be two non-empty breakout rooms
|
|
await p1.driver.waitUntil(
|
|
async () => {
|
|
if (await p1BreakoutRooms.getRoomsCount() !== 2) {
|
|
return false;
|
|
}
|
|
|
|
const list = await p1BreakoutRooms.getRooms();
|
|
|
|
if (list?.length !== 2) {
|
|
return false;
|
|
}
|
|
|
|
return list[0].participantCount === 1 && list[1].participantCount === 1;
|
|
}, {
|
|
timeout: 3000,
|
|
timeoutMsg: 'P1 is not seeing two breakout rooms'
|
|
});
|
|
|
|
// close the first room
|
|
await (await p1BreakoutRooms.getRooms())[0].closeRoom();
|
|
|
|
// there should be two rooms and first one should be empty
|
|
await p1.driver.waitUntil(
|
|
async () => {
|
|
if (await p1BreakoutRooms.getRoomsCount() !== 2) {
|
|
return false;
|
|
}
|
|
|
|
const list = await p1BreakoutRooms.getRooms();
|
|
|
|
if (list?.length !== 2) {
|
|
return false;
|
|
}
|
|
|
|
return list[0].participantCount === 0 || list[1].participantCount === 0;
|
|
}, {
|
|
timeout: 5000,
|
|
timeoutMsg: 'P1 is not seeing an empty breakout room'
|
|
});
|
|
|
|
// there should be two participants in the main room, either p2 or p3 got moved to the main room
|
|
const checkParticipants = (p: Participant) =>
|
|
p.driver.waitUntil(
|
|
async () => {
|
|
const isInBreakoutRoom = await p.isInBreakoutRoom();
|
|
const breakoutRooms = p.getBreakoutRooms();
|
|
|
|
if (isInBreakoutRoom) {
|
|
if (await breakoutRooms.getRoomsCount() !== 2) {
|
|
return false;
|
|
}
|
|
|
|
const list = await breakoutRooms.getRooms();
|
|
|
|
if (list?.length !== 2) {
|
|
return false;
|
|
}
|
|
|
|
return list.every(r => { // eslint-disable-line arrow-body-style
|
|
return r.name === MAIN_ROOM_NAME ? r.participantCount === 2 : r.participantCount === 0;
|
|
});
|
|
}
|
|
|
|
if (await breakoutRooms.getRoomsCount() !== 2) {
|
|
return false;
|
|
}
|
|
|
|
const list = await breakoutRooms.getRooms();
|
|
|
|
if (list?.length !== 2) {
|
|
return false;
|
|
}
|
|
|
|
return list[0].participantCount + list[1].participantCount === 1;
|
|
}, {
|
|
timeout: 3000,
|
|
timeoutMsg: `${p.name} is not seeing an empty breakout room and one with one participant`
|
|
});
|
|
|
|
await checkParticipants(p2);
|
|
await checkParticipants(p3);
|
|
});
|
|
|
|
it('send participants to breakout room', async () => {
|
|
await hangupAllParticipants();
|
|
|
|
// because the participants rejoin so fast, the meeting is not properly ended,
|
|
// so the previous breakout rooms would still be there.
|
|
// To avoid this issue we use a different meeting
|
|
// Respect room name suffix as it is important in multi-shard testing
|
|
ctx.roomName += `new-${ctx.roomName}`;
|
|
|
|
await ensureTwoParticipants();
|
|
const { p1, p2 } = ctx;
|
|
const p1BreakoutRooms = p1.getBreakoutRooms();
|
|
|
|
// there should be no breakout rooms
|
|
expect(await p1BreakoutRooms.getRoomsCount()).toBe(0);
|
|
|
|
// add one breakout room
|
|
await p1BreakoutRooms.addBreakoutRoom();
|
|
|
|
// there should be one empty room
|
|
await p1.driver.waitUntil(
|
|
async () => await p1BreakoutRooms.getRoomsCount() === 1
|
|
&& (await p1BreakoutRooms.getRooms())[0].participantCount === 0, {
|
|
timeout: 3000,
|
|
timeoutMsg: 'No breakout room added for p1'
|
|
});
|
|
|
|
// send the second participant to the first breakout room
|
|
await p1BreakoutRooms.sendParticipantToBreakoutRoom(p2, (await p1BreakoutRooms.getRooms())[0].name);
|
|
|
|
// there should be one room with one participant
|
|
await p1.driver.waitUntil(
|
|
async () => {
|
|
const list = await p1BreakoutRooms.getRooms();
|
|
|
|
if (list?.length !== 1) {
|
|
return false;
|
|
}
|
|
|
|
return list[0].participantCount === 1;
|
|
}, {
|
|
timeout: 5000,
|
|
timeoutMsg: 'P1 is not seeing p2 in the breakout room'
|
|
});
|
|
});
|
|
|
|
it('collapse breakout room', async () => {
|
|
const { p1 } = ctx;
|
|
const p1BreakoutRooms = p1.getBreakoutRooms();
|
|
|
|
// there should be one breakout room with one participant
|
|
await p1.driver.waitUntil(
|
|
async () => {
|
|
const list = await p1BreakoutRooms.getRooms();
|
|
|
|
if (list?.length !== 1) {
|
|
return false;
|
|
}
|
|
|
|
return list[0].participantCount === 1;
|
|
}, {
|
|
timeout: 3000,
|
|
timeoutMsg: 'P1 is not seeing p2 in the breakout room'
|
|
});
|
|
|
|
// get id of the breakout room participant
|
|
const breakoutList = p1.driver.$(`#${BREAKOUT_ROOMS_LIST_ID}`);
|
|
const breakoutRoomItem = await breakoutList.$$(`.${LIST_ITEM_CONTAINER}`).find(
|
|
async el => {
|
|
const id = await el.getAttribute('id');
|
|
|
|
return id !== '' && id !== null;
|
|
}) as ChainablePromiseElement;
|
|
|
|
const pId = await breakoutRoomItem.getAttribute('id');
|
|
const breakoutParticipant = p1.driver.$(`//div[@id="${pId}"]`);
|
|
|
|
expect(await breakoutParticipant.isDisplayed()).toBe(true);
|
|
|
|
// collapse the first
|
|
await (await p1BreakoutRooms.getRooms())[0].collapse();
|
|
|
|
// the participant should not be visible
|
|
expect(await breakoutParticipant.isDisplayed()).toBe(false);
|
|
|
|
// the collapsed room should still have one participant
|
|
expect((await p1BreakoutRooms.getRooms())[0].participantCount).toBe(1);
|
|
});
|
|
|
|
it('rename breakout room', async () => {
|
|
const myNewRoomName = `breakout-${crypto.randomUUID()}`;
|
|
const { p1, p2 } = ctx;
|
|
const p1BreakoutRooms = p1.getBreakoutRooms();
|
|
|
|
// let's rename breakout room and see it in local and remote
|
|
await (await p1BreakoutRooms.getRooms())[0].renameRoom(myNewRoomName);
|
|
|
|
await p1.driver.waitUntil(
|
|
async () => {
|
|
const list = await p1BreakoutRooms.getRooms();
|
|
|
|
if (list?.length !== 1) {
|
|
return false;
|
|
}
|
|
|
|
return list[0].name === myNewRoomName;
|
|
}, {
|
|
timeout: 3000,
|
|
timeoutMsg: 'The breakout room was not renamed for p1'
|
|
});
|
|
|
|
await checkSubject(p2, myNewRoomName);
|
|
|
|
const p2BreakoutRooms = p2.getBreakoutRooms();
|
|
|
|
// leave room
|
|
await p2BreakoutRooms.leaveBreakoutRoom();
|
|
|
|
// there should be one empty room
|
|
await p1.driver.waitUntil(
|
|
async () => {
|
|
const list = await p1BreakoutRooms.getRooms();
|
|
|
|
if (list?.length !== 1) {
|
|
return false;
|
|
}
|
|
|
|
return list[0].participantCount === 0;
|
|
}, {
|
|
timeout: 3000,
|
|
timeoutMsg: 'The breakout room not found or not empty for p1'
|
|
});
|
|
|
|
await p2.driver.waitUntil(
|
|
async () => {
|
|
const list = await p2BreakoutRooms.getRooms();
|
|
|
|
return list?.length === 1;
|
|
}, {
|
|
timeout: 3000,
|
|
timeoutMsg: 'The breakout room not seen by p2'
|
|
});
|
|
|
|
expect((await p2BreakoutRooms.getRooms())[0].name).toBe(myNewRoomName);
|
|
|
|
// send the second participant to the first breakout room
|
|
await p1BreakoutRooms.sendParticipantToBreakoutRoom(p2, myNewRoomName);
|
|
|
|
// there should be one room with one participant
|
|
await p1.driver.waitUntil(
|
|
async () => {
|
|
const list = await p1BreakoutRooms.getRooms();
|
|
|
|
if (list?.length !== 1) {
|
|
return false;
|
|
}
|
|
|
|
return list[0].participantCount === 1;
|
|
}, {
|
|
timeout: 5000,
|
|
timeoutMsg: 'The breakout room was not rename for p1'
|
|
});
|
|
|
|
await checkSubject(p2, myNewRoomName);
|
|
});
|
|
});
|