Some checks failed
Close stale issues and PRs / stale (push) Has been cancelled
478 lines
16 KiB
TypeScript
478 lines
16 KiB
TypeScript
import { isEqual } from 'lodash-es';
|
|
|
|
import { P1, P2, Participant } from '../../helpers/Participant';
|
|
import { setTestProperties } from '../../helpers/TestProperties';
|
|
import { config as testsConfig } from '../../helpers/TestsConfig';
|
|
import { ensureTwoParticipants, parseJid } from '../../helpers/participants';
|
|
|
|
setTestProperties(__filename, {
|
|
useIFrameApi: true,
|
|
useWebhookProxy: true,
|
|
usesBrowsers: [ 'p1', 'p2' ]
|
|
});
|
|
|
|
/**
|
|
* Tests PARTICIPANT_LEFT webhook.
|
|
*/
|
|
async function checkParticipantLeftHook(p: Participant, reason: string, checkId = false, conferenceJid: string) {
|
|
const { webhooksProxy } = ctx;
|
|
|
|
if (webhooksProxy) {
|
|
// PARTICIPANT_LEFT webhook
|
|
// @ts-ignore
|
|
const event: {
|
|
customerId: string;
|
|
data: {
|
|
conference: string;
|
|
disconnectReason: string;
|
|
group: string;
|
|
id: string;
|
|
isBreakout: boolean;
|
|
name: string;
|
|
participantId: string;
|
|
};
|
|
eventType: string;
|
|
} = await webhooksProxy.waitForEvent('PARTICIPANT_LEFT');
|
|
|
|
expect('PARTICIPANT_LEFT').toBe(event.eventType);
|
|
expect(event.data.conference).toBe(conferenceJid);
|
|
expect(event.data.disconnectReason).toBe(reason);
|
|
expect(event.data.isBreakout).toBe(false);
|
|
expect(event.data.participantId).toBe(await p.getEndpointId());
|
|
expect(event.data.name).toBe(p.name);
|
|
|
|
if (checkId) {
|
|
const jwtPayload = p.getToken()?.payload;
|
|
|
|
expect(event.data.id).toBe(jwtPayload?.context?.user?.id);
|
|
expect(event.data.group).toBe(jwtPayload?.context?.group);
|
|
expect(event.customerId).toBe(testsConfig.iframe.customerId);
|
|
}
|
|
}
|
|
}
|
|
|
|
describe('Participants presence', () => {
|
|
let conferenceJid: string = '';
|
|
|
|
it('joining the meeting', async () => {
|
|
// ensure 2 participants one moderator and one guest, we will load both with iframeAPI
|
|
await ensureTwoParticipants();
|
|
|
|
const { p1, p2, webhooksProxy } = ctx;
|
|
|
|
if (await p1.execute(() => config.disableIframeAPI)) {
|
|
// skip the test if iframeAPI is disabled
|
|
ctx.skipSuiteTests = true;
|
|
|
|
return;
|
|
}
|
|
|
|
// let's populate endpoint ids
|
|
await Promise.all([
|
|
p1.getEndpointId(),
|
|
p2.getEndpointId()
|
|
]);
|
|
|
|
await p1.switchToAPI();
|
|
await p2.switchToAPI();
|
|
|
|
expect(await p1.getIframeAPI().getEventResult('isModerator')).toBe(true);
|
|
expect(await p2.getIframeAPI().getEventResult('isModerator')).toBe(false);
|
|
|
|
expect(await p1.getIframeAPI().getEventResult('videoConferenceJoined')).toBeDefined();
|
|
expect(await p2.getIframeAPI().getEventResult('videoConferenceJoined')).toBeDefined();
|
|
|
|
if (webhooksProxy) {
|
|
// USAGE webhook
|
|
// @ts-ignore
|
|
const event: {
|
|
data: [
|
|
{ participantId: string; }
|
|
];
|
|
eventType: string;
|
|
} = await webhooksProxy.waitForEvent('USAGE');
|
|
|
|
expect('USAGE').toBe(event.eventType);
|
|
|
|
const p1EpId = await p1.getEndpointId();
|
|
const p2EpId = await p2.getEndpointId();
|
|
|
|
expect(event.data.filter(d => d.participantId === p1EpId
|
|
|| d.participantId === p2EpId).length).toBe(2);
|
|
}
|
|
});
|
|
|
|
it('participants info',
|
|
async () => {
|
|
const { p1, roomName, webhooksProxy } = ctx;
|
|
const roomsInfo = (await p1.getIframeAPI().getRoomsInfo()).rooms[0];
|
|
|
|
expect(roomsInfo).toBeDefined();
|
|
expect(roomsInfo.isMainRoom).toBe(true);
|
|
|
|
expect(roomsInfo.id).toBeDefined();
|
|
const { node: roomNode } = parseJid(roomsInfo.id);
|
|
|
|
expect(roomNode).toBe(roomName);
|
|
|
|
const { node, resource } = parseJid(roomsInfo.jid);
|
|
|
|
conferenceJid = roomsInfo.jid.substring(0, roomsInfo.jid.indexOf('/'));
|
|
|
|
const p1EpId = await p1.getEndpointId();
|
|
|
|
expect(node).toBe(roomName);
|
|
expect(resource).toBe(p1EpId);
|
|
|
|
expect(roomsInfo.participants.length).toBe(2);
|
|
expect(await p1.getIframeAPI().getNumberOfParticipants()).toBe(2);
|
|
|
|
if (webhooksProxy) {
|
|
// ROOM_CREATED webhook
|
|
// @ts-ignore
|
|
const event: {
|
|
data: {
|
|
conference: string;
|
|
isBreakout: boolean;
|
|
};
|
|
eventType: string;
|
|
} = await webhooksProxy.waitForEvent('ROOM_CREATED');
|
|
|
|
expect('ROOM_CREATED').toBe(event.eventType);
|
|
expect(event.data.conference).toBe(conferenceJid);
|
|
expect(event.data.isBreakout).toBe(false);
|
|
}
|
|
}
|
|
);
|
|
|
|
it('participants pane', async () => {
|
|
const { p1 } = ctx;
|
|
|
|
await p1.switchToAPI();
|
|
|
|
expect(await p1.getIframeAPI().isParticipantsPaneOpen()).toBe(false);
|
|
|
|
await p1.getIframeAPI().addEventListener('participantsPaneToggled');
|
|
await p1.getIframeAPI().executeCommand('toggleParticipantsPane', true);
|
|
|
|
expect(await p1.getIframeAPI().isParticipantsPaneOpen()).toBe(true);
|
|
expect((await p1.getIframeAPI().getEventResult('participantsPaneToggled'))?.open).toBe(true);
|
|
|
|
await p1.getIframeAPI().executeCommand('toggleParticipantsPane', false);
|
|
expect(await p1.getIframeAPI().isParticipantsPaneOpen()).toBe(false);
|
|
expect((await p1.getIframeAPI().getEventResult('participantsPaneToggled'))?.open).toBe(false);
|
|
});
|
|
|
|
it('grant moderator', async () => {
|
|
const { p1, p2, webhooksProxy } = ctx;
|
|
const p2EpId = await p2.getEndpointId();
|
|
|
|
await p1.getIframeAPI().clearEventResults('participantRoleChanged');
|
|
await p2.getIframeAPI().clearEventResults('participantRoleChanged');
|
|
|
|
await p1.getIframeAPI().executeCommand('grantModerator', p2EpId);
|
|
|
|
await p2.driver.waitUntil(() => p2.getIframeAPI().getEventResult('isModerator'), {
|
|
timeout: 3000,
|
|
timeoutMsg: 'Moderator role not granted'
|
|
});
|
|
|
|
type RoleChangedEvent = {
|
|
id: string;
|
|
role: string;
|
|
};
|
|
|
|
const event1: RoleChangedEvent = await p1.driver.waitUntil(
|
|
() => p1.getIframeAPI().getEventResult('participantRoleChanged'), {
|
|
timeout: 3000,
|
|
timeoutMsg: 'Role was not update on p1 side'
|
|
});
|
|
|
|
expect(event1?.id).toBe(p2EpId);
|
|
expect(event1?.role).toBe('moderator');
|
|
|
|
const event2: RoleChangedEvent = await p2.driver.waitUntil(
|
|
() => p2.getIframeAPI().getEventResult('participantRoleChanged'), {
|
|
timeout: 3000,
|
|
timeoutMsg: 'Role was not update on p2 side'
|
|
});
|
|
|
|
expect(event2?.id).toBe(p2EpId);
|
|
expect(event2?.role).toBe('moderator');
|
|
|
|
if (webhooksProxy) {
|
|
// ROLE_CHANGED webhook
|
|
// @ts-ignore
|
|
const event: {
|
|
data: {
|
|
grantedBy: {
|
|
participantId: string;
|
|
};
|
|
grantedTo: {
|
|
participantId: string;
|
|
};
|
|
role: string;
|
|
};
|
|
eventType: string;
|
|
} = await webhooksProxy.waitForEvent('ROLE_CHANGED');
|
|
|
|
expect('ROLE_CHANGED').toBe(event.eventType);
|
|
expect(event.data.role).toBe('moderator');
|
|
expect(event.data.grantedBy.participantId).toBe(await p1.getEndpointId());
|
|
expect(event.data.grantedTo.participantId).toBe(await p2.getEndpointId());
|
|
}
|
|
});
|
|
|
|
it('kick participant', async () => {
|
|
// we want to join second participant with token, so we can check info in webhook
|
|
await ctx.p2.getIframeAPI().addEventListener('videoConferenceLeft');
|
|
await ctx.p2.switchToAPI();
|
|
await ctx.p2.getIframeAPI().executeCommand('hangup');
|
|
await ctx.p2.driver.waitUntil(() =>
|
|
ctx.p2.getIframeAPI().getEventResult('videoConferenceLeft'), {
|
|
timeout: 4000,
|
|
timeoutMsg: 'videoConferenceLeft not received'
|
|
});
|
|
|
|
await ensureTwoParticipants({
|
|
preferGenerateToken: true
|
|
});
|
|
|
|
const { p1, p2, roomName, webhooksProxy } = ctx;
|
|
|
|
webhooksProxy?.clearCache();
|
|
|
|
const p1EpId = await p1.getEndpointId();
|
|
const p2EpId = await p2.getEndpointId();
|
|
|
|
const p1DisplayName = await p1.getLocalDisplayName();
|
|
const p2DisplayName = await p2.getLocalDisplayName();
|
|
|
|
await p1.switchToAPI();
|
|
await p2.switchToAPI();
|
|
|
|
const roomsInfo = (await p1.getIframeAPI().getRoomsInfo()).rooms[0];
|
|
|
|
conferenceJid = roomsInfo.jid.substring(0, roomsInfo.jid.indexOf('/'));
|
|
|
|
await p1.getIframeAPI().addEventListener('participantKickedOut');
|
|
await p2.getIframeAPI().addEventListener('participantKickedOut');
|
|
|
|
await p2.getIframeAPI().clearEventResults('videoConferenceLeft');
|
|
await p2.getIframeAPI().addEventListener('videoConferenceLeft');
|
|
|
|
await p1.getIframeAPI().executeCommand('kickParticipant', p2EpId);
|
|
|
|
const eventP1 = await p1.driver.waitUntil(() => p1.getIframeAPI().getEventResult('participantKickedOut'), {
|
|
timeout: 2000,
|
|
timeoutMsg: 'participantKickedOut event not received on p1 side'
|
|
});
|
|
const eventP2 = await p2.driver.waitUntil(() => p2.getIframeAPI().getEventResult('participantKickedOut'), {
|
|
timeout: 2000,
|
|
timeoutMsg: 'participantKickedOut event not received on p2 side'
|
|
});
|
|
|
|
await checkParticipantLeftHook(p2, 'kicked', true, conferenceJid);
|
|
|
|
expect(eventP1).toBeDefined();
|
|
expect(eventP2).toBeDefined();
|
|
|
|
expect(isEqual(eventP1, {
|
|
kicked: {
|
|
id: p2EpId,
|
|
local: false,
|
|
name: p2DisplayName
|
|
},
|
|
kicker: {
|
|
id: p1EpId,
|
|
local: true,
|
|
name: p1DisplayName
|
|
}
|
|
})).toBe(true);
|
|
|
|
expect(isEqual(eventP2, {
|
|
kicked: {
|
|
id: 'local',
|
|
local: true,
|
|
name: p2DisplayName
|
|
},
|
|
kicker: {
|
|
id: p1EpId,
|
|
name: p1DisplayName
|
|
}
|
|
})).toBe(true);
|
|
|
|
const eventConferenceLeftP2 = await p2.driver.waitUntil(() =>
|
|
p2.getIframeAPI().getEventResult('videoConferenceLeft'), {
|
|
timeout: 4000,
|
|
timeoutMsg: 'videoConferenceLeft not received'
|
|
});
|
|
|
|
expect(eventConferenceLeftP2).toBeDefined();
|
|
expect(eventConferenceLeftP2.roomName).toBe(roomName);
|
|
});
|
|
|
|
it('join after kick', async () => {
|
|
const { p1, webhooksProxy } = ctx;
|
|
|
|
await p1.getIframeAPI().addEventListener('participantJoined');
|
|
await p1.getIframeAPI().addEventListener('participantMenuButtonClick');
|
|
|
|
webhooksProxy?.clearCache();
|
|
|
|
// join again
|
|
await ensureTwoParticipants();
|
|
const { p2 } = ctx;
|
|
|
|
if (webhooksProxy) {
|
|
// PARTICIPANT_JOINED webhook
|
|
// @ts-ignore
|
|
const event: {
|
|
data: {
|
|
conference: string;
|
|
isBreakout: boolean;
|
|
moderator: boolean;
|
|
name: string;
|
|
participantId: string;
|
|
};
|
|
eventType: string;
|
|
} = await webhooksProxy.waitForEvent('PARTICIPANT_JOINED');
|
|
|
|
expect('PARTICIPANT_JOINED').toBe(event.eventType);
|
|
expect(event.data.conference).toBe(conferenceJid);
|
|
expect(event.data.isBreakout).toBe(false);
|
|
expect(event.data.moderator).toBe(false);
|
|
expect(event.data.name).toBe(await p2.getLocalDisplayName());
|
|
expect(event.data.participantId).toBe(await p2.getEndpointId());
|
|
expect(event.data.name).toBe(p2.name);
|
|
}
|
|
|
|
await p1.switchToAPI();
|
|
|
|
const event = await p1.driver.waitUntil(() => p1.getIframeAPI().getEventResult('participantJoined'), {
|
|
timeout: 2000,
|
|
timeoutMsg: 'participantJoined not received'
|
|
});
|
|
|
|
const p2DisplayName = await p2.getLocalDisplayName();
|
|
|
|
expect(event).toBeDefined();
|
|
expect(event.id).toBe(await p2.getEndpointId());
|
|
expect(event.displayName).toBe(p2DisplayName);
|
|
expect(event.formattedDisplayName).toBe(p2DisplayName);
|
|
|
|
});
|
|
|
|
it('overwrite names', async () => {
|
|
const { p1, p2 } = ctx;
|
|
|
|
const p1EpId = await p1.getEndpointId();
|
|
const p2EpId = await p2.getEndpointId();
|
|
|
|
const newP1Name = P1;
|
|
const newP2Name = P2;
|
|
const newNames: ({ id: string; name: string; })[] = [ {
|
|
id: p2EpId,
|
|
name: newP2Name
|
|
}, {
|
|
id: p1EpId,
|
|
name: newP1Name
|
|
} ];
|
|
|
|
await p1.getIframeAPI().executeCommand('overwriteNames', newNames);
|
|
|
|
await p1.switchInPage();
|
|
|
|
expect(await p1.getLocalDisplayName()).toBe(newP1Name);
|
|
|
|
expect(await p1.getFilmstrip().getRemoteDisplayName(p2EpId)).toBe(newP2Name);
|
|
|
|
});
|
|
|
|
it('hangup', async () => {
|
|
const { p1, p2, roomName } = ctx;
|
|
|
|
await p1.switchToAPI();
|
|
await p2.switchToAPI();
|
|
|
|
await p2.getIframeAPI().clearEventResults('videoConferenceLeft');
|
|
await p2.getIframeAPI().addEventListener('videoConferenceLeft');
|
|
await p2.getIframeAPI().addEventListener('readyToClose');
|
|
|
|
await p2.getIframeAPI().executeCommand('hangup');
|
|
|
|
const eventConferenceLeftP2 = await p2.driver.waitUntil(() =>
|
|
p2.getIframeAPI().getEventResult('videoConferenceLeft'), {
|
|
timeout: 4000,
|
|
timeoutMsg: 'videoConferenceLeft not received'
|
|
});
|
|
|
|
expect(eventConferenceLeftP2).toBeDefined();
|
|
expect(eventConferenceLeftP2.roomName).toBe(roomName);
|
|
|
|
await checkParticipantLeftHook(p2, 'left', false, conferenceJid);
|
|
|
|
const eventReadyToCloseP2 = await p2.driver.waitUntil(() => p2.getIframeAPI().getEventResult('readyToClose'), {
|
|
timeout: 2000,
|
|
timeoutMsg: 'readyToClose not received'
|
|
});
|
|
|
|
expect(eventReadyToCloseP2).toBeDefined();
|
|
});
|
|
|
|
it('dispose conference', async () => {
|
|
const { p1, roomName, webhooksProxy } = ctx;
|
|
|
|
await p1.switchToAPI();
|
|
|
|
await p1.getIframeAPI().clearEventResults('videoConferenceLeft');
|
|
await p1.getIframeAPI().addEventListener('videoConferenceLeft');
|
|
await p1.getIframeAPI().addEventListener('readyToClose');
|
|
|
|
await p1.getIframeAPI().executeCommand('hangup');
|
|
|
|
const eventConferenceLeft = await p1.driver.waitUntil(() =>
|
|
p1.getIframeAPI().getEventResult('videoConferenceLeft'), {
|
|
timeout: 4000,
|
|
timeoutMsg: 'videoConferenceLeft not received'
|
|
});
|
|
|
|
expect(eventConferenceLeft).toBeDefined();
|
|
expect(eventConferenceLeft.roomName).toBe(roomName);
|
|
|
|
await checkParticipantLeftHook(p1, 'left', true, conferenceJid);
|
|
if (webhooksProxy) {
|
|
// ROOM_DESTROYED webhook
|
|
// @ts-ignore
|
|
const event: {
|
|
data: {
|
|
conference: string;
|
|
isBreakout: boolean;
|
|
};
|
|
eventType: string;
|
|
} = await webhooksProxy.waitForEvent('ROOM_DESTROYED');
|
|
|
|
expect('ROOM_DESTROYED').toBe(event.eventType);
|
|
expect(event.data.conference).toBe(conferenceJid);
|
|
expect(event.data.isBreakout).toBe(false);
|
|
}
|
|
|
|
const eventReadyToClose = await p1.driver.waitUntil(() => p1.getIframeAPI().getEventResult('readyToClose'), {
|
|
timeout: 2000,
|
|
timeoutMsg: 'readyToClose not received'
|
|
});
|
|
|
|
expect(eventReadyToClose).toBeDefined();
|
|
|
|
// dispose
|
|
await p1.getIframeAPI().dispose();
|
|
|
|
// check there is no iframe on the page
|
|
await p1.driver.$('iframe').waitForExist({
|
|
reverse: true,
|
|
timeout: 2000,
|
|
timeoutMsg: 'iframe is still on the page'
|
|
});
|
|
});
|
|
});
|