210 lines
7.2 KiB
TypeScript
210 lines
7.2 KiB
TypeScript
import { Participant } from '../../helpers/Participant';
|
|
import { setTestProperties } from '../../helpers/TestProperties';
|
|
import { config as testsConfig } from '../../helpers/TestsConfig';
|
|
import WebhookProxy from '../../helpers/WebhookProxy';
|
|
import { expectations } from '../../helpers/expectations';
|
|
import { joinJaasMuc, generateJaasToken as t } from '../../helpers/jaas';
|
|
|
|
setTestProperties(__filename, {
|
|
requireWebhookProxy: true,
|
|
useJaas: true
|
|
});
|
|
|
|
/**
|
|
* Tests the recording and live-streaming functionality of JaaS (including relevant webhooks) exercising the iFrame API
|
|
* commands and functions.
|
|
* TODO: also assert "this meeting is being recorded" notifications are show/played?
|
|
*/
|
|
describe('Recording and live-streaming', () => {
|
|
const tenant = testsConfig.jaas.tenant;
|
|
const customerId = tenant?.replace('vpaas-magic-cookie-', '');
|
|
let recordingEnabled: boolean;
|
|
let liveStreamingEnabled: boolean;
|
|
let p: Participant;
|
|
let webhooksProxy: WebhookProxy;
|
|
|
|
it('setup', async () => {
|
|
webhooksProxy = ctx.webhooksProxy;
|
|
p = await joinJaasMuc({ iFrameApi: true, token: t({ moderator: true }) }, { roomName: ctx.roomName });
|
|
|
|
recordingEnabled = Boolean(await p.execute(() => config.recordingService?.enabled));
|
|
expect(recordingEnabled).toBe(expectations.jaas.recordingEnabled);
|
|
|
|
liveStreamingEnabled = Boolean(await p.execute(() => config.liveStreaming?.enabled));
|
|
expect(liveStreamingEnabled).toBe(expectations.jaas.liveStreamingEnabled);
|
|
|
|
if (liveStreamingEnabled && !process.env.YTUBE_TEST_STREAM_KEY) {
|
|
liveStreamingEnabled = false;
|
|
console.log('Skipping live-streaming tests because YTUBE_TEST_STREAM_KEY is not set.');
|
|
}
|
|
|
|
await p.switchToMainFrame();
|
|
});
|
|
|
|
/**
|
|
* Starts recording and asserts that the expected iFrame and JaaS events are received.
|
|
* @param command whether to use the "command" or the "function" iFrame API.
|
|
*/
|
|
async function startRecording(command: boolean) {
|
|
await p.getIframeAPI().addEventListener('recordingStatusChanged');
|
|
await p.getIframeAPI().addEventListener('recordingLinkAvailable');
|
|
|
|
if (command) {
|
|
await p.getIframeAPI().executeCommand('startRecording', {
|
|
mode: 'file'
|
|
});
|
|
} else {
|
|
await p.getIframeAPI().startRecording({
|
|
mode: 'file'
|
|
});
|
|
}
|
|
|
|
const jaasEvent: {
|
|
customerId: string;
|
|
eventType: string;
|
|
} = await webhooksProxy.waitForEvent('RECORDING_STARTED');
|
|
|
|
expect('RECORDING_STARTED').toBe(jaasEvent.eventType);
|
|
expect(jaasEvent.customerId).toBe(customerId);
|
|
|
|
webhooksProxy.clearCache();
|
|
|
|
const iFrameEvent = await p.driver.waitUntil(() =>
|
|
p.getIframeAPI().getEventResult('recordingStatusChanged'), {
|
|
timeout: 5000,
|
|
timeoutMsg: 'recordingStatusChanged event not received'
|
|
});
|
|
|
|
expect(iFrameEvent.mode).toBe('file');
|
|
expect(iFrameEvent.on).toBe(true);
|
|
|
|
const linkEvent = await p.driver.waitUntil(() =>
|
|
p.getIframeAPI().getEventResult('recordingLinkAvailable'), {
|
|
timeout: 5000,
|
|
timeoutMsg: 'recordingLinkAvailable event not received'
|
|
});
|
|
|
|
expect(linkEvent.link.startsWith('https://')).toBe(true);
|
|
expect(linkEvent.link.includes(tenant)).toBe(true);
|
|
expect(linkEvent.ttl > 0).toBe(true);
|
|
}
|
|
|
|
/**
|
|
* Stops recording and asserts that the expected iFrame and JaaS events are received.
|
|
* @param command whether to use the "command" or the "function" iFrame API.
|
|
*/
|
|
async function stopRecording(command: boolean) {
|
|
if (command) {
|
|
await p.getIframeAPI().executeCommand('stopRecording', 'file');
|
|
} else {
|
|
await p.getIframeAPI().stopRecording('file');
|
|
}
|
|
|
|
const jaasEndedEvent: {
|
|
customerId: string;
|
|
eventType: string;
|
|
} = await webhooksProxy.waitForEvent('RECORDING_ENDED');
|
|
|
|
expect('RECORDING_ENDED').toBe(jaasEndedEvent.eventType);
|
|
expect(jaasEndedEvent.customerId).toBe(customerId);
|
|
|
|
const jaasUploadedEvent: {
|
|
customerId: string;
|
|
data: {
|
|
initiatorId: string;
|
|
participants: Array<string>;
|
|
};
|
|
eventType: string;
|
|
} = await webhooksProxy.waitForEvent('RECORDING_UPLOADED');
|
|
|
|
const jwtPayload = p.getToken()?.payload;
|
|
|
|
expect(jaasUploadedEvent.data.initiatorId).toBe(jwtPayload?.context?.user?.id);
|
|
expect(jaasUploadedEvent.data.participants.some(
|
|
// @ts-ignore
|
|
e => e.id === jwtPayload?.context?.user?.id)).toBe(true);
|
|
|
|
webhooksProxy.clearCache();
|
|
|
|
const iFrameEvent = (await p.getIframeAPI().getEventResult('recordingStatusChanged'));
|
|
|
|
expect(iFrameEvent.mode).toBe('file');
|
|
expect(iFrameEvent.on).toBe(false);
|
|
|
|
await p.getIframeAPI().clearEventResults('recordingStatusChanged');
|
|
}
|
|
|
|
it('start/stop recording using the iFrame command', async () => {
|
|
if (!recordingEnabled) {
|
|
return;
|
|
}
|
|
|
|
await startRecording(true);
|
|
await stopRecording(true);
|
|
|
|
// to avoid rate limits
|
|
await p.driver.pause(30000);
|
|
});
|
|
|
|
it('start/stop recording using the iFrame function', async () => {
|
|
if (!recordingEnabled) {
|
|
return;
|
|
}
|
|
|
|
await startRecording(false);
|
|
await stopRecording(false);
|
|
|
|
// to avoid rate limits
|
|
await p.driver.pause(30000);
|
|
});
|
|
|
|
it('start/stop live-streaming using the iFrame command', async () => {
|
|
if (!liveStreamingEnabled) {
|
|
return;
|
|
}
|
|
|
|
await p.getIframeAPI().addEventListener('recordingStatusChanged');
|
|
|
|
await p.getIframeAPI().executeCommand('startRecording', {
|
|
youtubeBroadcastID: process.env.YTUBE_TEST_BROADCAST_ID,
|
|
mode: 'stream',
|
|
youtubeStreamKey: process.env.YTUBE_TEST_STREAM_KEY
|
|
});
|
|
|
|
const jaasEvent: {
|
|
customerId: string;
|
|
eventType: string;
|
|
} = await webhooksProxy.waitForEvent('LIVE_STREAM_STARTED');
|
|
|
|
expect('LIVE_STREAM_STARTED').toBe(jaasEvent.eventType);
|
|
expect(jaasEvent.customerId).toBe(customerId);
|
|
|
|
const iFrameEvent = (await p.getIframeAPI().getEventResult('recordingStatusChanged'));
|
|
|
|
expect(iFrameEvent.mode).toBe('stream');
|
|
expect(iFrameEvent.on).toBe(true);
|
|
|
|
if (process.env.YTUBE_TEST_BROADCAST_ID) {
|
|
const liveStreamUrl = await p.getIframeAPI().getLivestreamUrl();
|
|
|
|
expect(liveStreamUrl.livestreamUrl).toBeDefined();
|
|
}
|
|
|
|
await p.getIframeAPI().executeCommand('stopRecording', 'stream');
|
|
|
|
const jaasEndedEvent: {
|
|
customerId: string;
|
|
eventType: string;
|
|
} = await webhooksProxy.waitForEvent('LIVE_STREAM_ENDED');
|
|
|
|
expect(jaasEndedEvent.eventType).toBe('LIVE_STREAM_ENDED');
|
|
expect(jaasEndedEvent.customerId).toBe(customerId);
|
|
|
|
const iFrameEndedEvent = (await p.getIframeAPI().getEventResult('recordingStatusChanged'));
|
|
|
|
expect(iFrameEndedEvent.mode).toBe('stream');
|
|
expect(iFrameEndedEvent.on).toBe(false);
|
|
});
|
|
});
|
|
|