Skip to content

Commit

Permalink
feat(tests): Adds breakout tests.
Browse files Browse the repository at this point in the history
  • Loading branch information
damencho committed Dec 20, 2024
1 parent c3744bc commit b848c3e
Show file tree
Hide file tree
Showing 6 changed files with 769 additions and 18 deletions.
26 changes: 26 additions & 0 deletions tests/helpers/Participant.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { multiremotebrowser } from '@wdio/globals';

import { IConfig } from '../../react/features/base/config/configType';
import { urlObjectToString } from '../../react/features/base/util/uri';
import BreakoutRooms from '../pageobjects/BreakoutRooms';
import Filmstrip from '../pageobjects/Filmstrip';
import IframeAPI from '../pageobjects/IframeAPI';
import Notifications from '../pageobjects/Notifications';
Expand Down Expand Up @@ -251,6 +252,22 @@ export class Participant {
&& APP.store?.getState()['features/base/participants']?.local?.role === 'moderator');
}

/**
* Checks if the meeting supports breakout rooms.
*/
async isBreakoutRoomsSupported() {
return await this.driver.execute(() => typeof APP !== 'undefined'
&& APP.store?.getState()['features/base/conference'].conference?.getBreakoutRooms()?.isSupported());
}

/**
* Checks if the participant is in breakout room.
*/
async isInBreakoutRoom() {
return await this.driver.execute(() => typeof APP !== 'undefined'
&& APP.store?.getState()['features/base/conference'].conference?.getBreakoutRooms()?.isBreakoutRoom());
}

/**
* Waits to join the muc.
*
Expand Down Expand Up @@ -321,6 +338,15 @@ export class Participant {
});
}

/**
* Returns the BreakoutRooms for this participant.
*
* @returns {BreakoutRooms}
*/
getBreakoutRooms(): BreakoutRooms {
return new BreakoutRooms(this);
}

/**
* Returns the toolbar for this participant.
*
Expand Down
18 changes: 18 additions & 0 deletions tests/helpers/participants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ import { v4 as uuidv4 } from 'uuid';
import { Participant } from './Participant';
import { IContext, IJoinOptions } from './types';

const SUBJECT_XPATH = '//div[starts-with(@class, "subject-text")]';

/**
* Ensure that there is on participant.
*
Expand Down Expand Up @@ -237,3 +239,19 @@ export function parseJid(str: string): {
resource: domainParts.length > 0 ? domainParts[1] : undefined
};
}

/**
* Check the subject of the participant.
* @param participant
* @param subject
*/
export async function checkSubject(participant: Participant, subject: string) {
const localTile = participant.driver.$(SUBJECT_XPATH);

await localTile.waitForExist();
await localTile.moveTo();

const txt = await localTile.getText();

expect(txt.startsWith(subject)).toBe(true);
}
230 changes: 230 additions & 0 deletions tests/pageobjects/BreakoutRooms.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,230 @@
import { Participant } from '../helpers/Participant';

import BaseDialog from './BaseDialog';
import BasePageObject from './BasePageObject';

const BREAKOUT_ROOMS_CLASS = 'breakout-room-container';
const ADD_BREAKOUT_ROOM = 'Add breakout room';
const MORE_LABEL = 'More';
const LEAVE_ROOM_LABEL = 'Leave breakout room';
const AUTO_ASSIGN_LABEL = 'Auto assign to breakout rooms';

/**
* Represents a single breakout room and the operations for it.
*/
class BreakoutRoom extends BasePageObject {
title: string;
id: string;
count: number;

/**
* Constructs a breakout room.
*/
constructor(participant: Participant, title: string, id: string) {
super(participant);

this.title = title;
this.id = id;

const tMatch = title.match(/.*\((.*)\)/);

if (tMatch) {
this.count = parseInt(tMatch[1], 10);
}
}

/**
* Returns room name.
*/
get name() {
return this.title.split('(')[0].trim();
}

/**
* Returns the number of participants in the room.
*/
get participantCount() {
return this.count;
}

/**
* Collapses the breakout room.
*/
async collapse() {
const collapseElem = this.participant.driver.$(
`div[data-testid="${this.id}"]`);

await collapseElem.click();
}

/**
* Joins the breakout room.
*/
async joinRoom() {
const joinButton = this.participant.driver
.$(`button[data-testid="join-room-${this.id}"]`);

await joinButton.waitForClickable();
await joinButton.click();
}

/**
* Removes the breakout room.
*/
async removeRoom() {
await this.openContextMenu();

const removeButton = this.participant.driver.$(`#remove-room-${this.id}`);

await removeButton.waitForClickable();
await removeButton.click();
}

/**
* Renames the breakout room.
*/
async renameRoom(newName: string) {
await this.openContextMenu();

const renameButton = this.participant.driver.$(`#rename-room-${this.id}`);

await renameButton.click();

const newNameInput = this.participant.driver.$('input[name="breakoutRoomName"]');

await newNameInput.waitForStable();
await newNameInput.setValue(newName);

await new BaseDialog(this.participant).clickOkButton();
}

/**
* Closes the breakout room.
*/
async closeRoom() {
await this.openContextMenu();

const closeButton = this.participant.driver.$(`#close-room-${this.id}`);

await closeButton.waitForClickable();
await closeButton.click();
}

/**
* Opens the context menu.
* @private
*/
private async openContextMenu() {
const listItem = this.participant.driver.$(`div[data-testid="${this.id}"]`);

await listItem.click();

const button = listItem.$(`aria/${MORE_LABEL}`);

await button.waitForClickable();
await button.click();
}
}

/**
* All breakout rooms objects and operations.
*/
export default class BreakoutRooms extends BasePageObject {
/**
* Returns the number of breakout rooms.
*/
async getRoomsCount() {
const participantsPane = this.participant.getParticipantsPane();

if (!await participantsPane.isOpen()) {
await participantsPane.open();
}

return await this.participant.driver.$$(`.${BREAKOUT_ROOMS_CLASS}`).length;
}

/**
* Adds a breakout room.
*/
async addBreakoutRoom() {
const participantsPane = this.participant.getParticipantsPane();

if (!await participantsPane.isOpen()) {
await participantsPane.open();
}

const addBreakoutButton = this.participant.driver.$(`aria/${ADD_BREAKOUT_ROOM}`);

await addBreakoutButton.waitForDisplayed();
await addBreakoutButton.click();
}

/**
* Returns all breakout rooms.
*/
async getRooms(): Promise<BreakoutRoom[]> {
const rooms = this.participant.driver.$$(`.${BREAKOUT_ROOMS_CLASS}`);

return rooms.map(async room => new BreakoutRoom(
this.participant, await room.$('span').getText(), await room.getAttribute('data-testid')));
}

/**
* Leave by clicking the leave button in participant pane.
*/
async leaveBreakoutRoom() {
const participantsPane = this.participant.getParticipantsPane();

if (!await participantsPane.isOpen()) {
await participantsPane.open();
}

const leaveButton = this.participant.driver.$(`aria/${LEAVE_ROOM_LABEL}`);

await leaveButton.isClickable();
await leaveButton.click();
}

/**
* Auto assign participants to breakout rooms.
*/
async autoAssignToBreakoutRooms() {
const button = this.participant.driver.$(`aria/${AUTO_ASSIGN_LABEL}`);

await button.waitForClickable();
await button.click();
}

/**
* Tries to send a participant to a breakout room.
*/
async sendParticipantToBreakoutRoom(participant: Participant, roomName: string) {
const participantsPane = this.participant.getParticipantsPane();

await participantsPane.selectParticipant(participant);
await participantsPane.openParticipantContextMenu(participant);

const sendButton = this.participant.driver.$(`aria/${roomName}`);

await sendButton.waitForClickable();
await sendButton.click();
}

// /**
// * Open context menu for given participant.
// */
// async openParticipantContextMenu(participant: Participant) {
// const listItem = this.participant.driver.$(
// `div[@id="participant-item-${await participant.getEndpointId()}"]`);
//
// await listItem.waitForDisplayed();
// await listItem.moveTo();
//
// const button = listItem.$(`aria/${PARTICIPANT_MORE_LABEL}`);
//
// await button.waitForClickable();
// await button.click();
// }
}


44 changes: 30 additions & 14 deletions tests/pageobjects/ParticipantsPane.ts
Original file line number Diff line number Diff line change
Expand Up @@ -128,22 +128,10 @@ export default class ParticipantsPane extends BasePageObject {
await this.participant.getNotifications().dismissAnyJoinNotification();

const participantId = await participantToUnmute.getEndpointId();
const participantItem = this.participant.driver.$(`#participant-item-${participantId}`);

await participantItem.waitForExist();
await participantItem.waitForStable();
await participantItem.waitForDisplayed();
await participantItem.moveTo();

await this.selectParticipant(participantToUnmute);
if (fromContextMenu) {
const meetingParticipantMoreOptions = this.participant.driver
.$(`[data-testid="participant-more-options-${participantId}"]`);

await meetingParticipantMoreOptions.waitForExist();
await meetingParticipantMoreOptions.waitForDisplayed();
await meetingParticipantMoreOptions.waitForStable();
await meetingParticipantMoreOptions.moveTo();
await meetingParticipantMoreOptions.click();
await this.openParticipantContextMenu(participantToUnmute);
}

const unmuteButton = this.participant.driver
Expand All @@ -152,4 +140,32 @@ export default class ParticipantsPane extends BasePageObject {
await unmuteButton.waitForExist();
await unmuteButton.click();
}

/**
* Open context menu for given participant.
*/
async selectParticipant(participant: Participant) {
const participantId = await participant.getEndpointId();
const participantItem = this.participant.driver.$(`#participant-item-${participantId}`);

await participantItem.waitForExist();
await participantItem.waitForStable();
await participantItem.waitForDisplayed();
await participantItem.moveTo();
}

/**
* Open context menu for given participant.
*/
async openParticipantContextMenu(participant: Participant) {
const participantId = await participant.getEndpointId();
const meetingParticipantMoreOptions = this.participant.driver
.$(`[data-testid="participant-more-options-${participantId}"]`);

await meetingParticipantMoreOptions.waitForExist();
await meetingParticipantMoreOptions.waitForDisplayed();
await meetingParticipantMoreOptions.waitForStable();
await meetingParticipantMoreOptions.moveTo();
await meetingParticipantMoreOptions.click();
}
}
Loading

0 comments on commit b848c3e

Please sign in to comment.