import { setTestProperties } from '../../helpers/TestProperties'; import { config as testsConfig } from '../../helpers/TestsConfig'; import { ensureOneParticipant } from '../../helpers/participants'; setTestProperties(__filename, { useIFrameApi: true, useWebhookProxy: true }); const { tenant, customerId } = testsConfig.iframe; describe('Recording', () => { let recordingDisabled: boolean; let liveStreamingDisabled: boolean; it('join participant', async () => { await ensureOneParticipant(); const { p1 } = ctx; // check for dial-in dial-out sip-jibri maybe if (await p1.execute(() => config.disableIframeAPI)) { // skip the test if iframeAPI is disabled ctx.skipSuiteTests = true; return; } recordingDisabled = Boolean(!await p1.execute(() => config.recordingService?.enabled)); liveStreamingDisabled = Boolean(!await p1.execute(() => config.liveStreaming?.enabled)) || !process.env.YTUBE_TEST_STREAM_KEY; }); it('start/stop function', async () => { if (recordingDisabled) { return; } await testRecordingStarted(true); await testRecordingStopped(true); // to avoid limits await ctx.p1.driver.pause(30000); }); it('start/stop command', async () => { if (recordingDisabled) { return; } await testRecordingStarted(false); await testRecordingStopped(false); // to avoid limits await ctx.p1.driver.pause(30000); }); it('start/stop Livestreaming command', async () => { if (liveStreamingDisabled) { return; } const { p1, webhooksProxy } = ctx; await p1.switchToAPI(); await p1.getIframeAPI().addEventListener('recordingStatusChanged'); await p1.getIframeAPI().executeCommand('startRecording', { youtubeBroadcastID: process.env.YTUBE_TEST_BROADCAST_ID, mode: 'stream', youtubeStreamKey: process.env.YTUBE_TEST_STREAM_KEY }); if (webhooksProxy) { const liveStreamEvent: { customerId: string; eventType: string; } = await webhooksProxy.waitForEvent('LIVE_STREAM_STARTED'); expect('LIVE_STREAM_STARTED').toBe(liveStreamEvent.eventType); expect(liveStreamEvent.customerId).toBe(customerId); } const statusEvent = (await p1.getIframeAPI().getEventResult('recordingStatusChanged')); expect(statusEvent.mode).toBe('stream'); expect(statusEvent.on).toBe(true); if (process.env.YTUBE_TEST_BROADCAST_ID) { const liveStreamUrl = await p1.getIframeAPI().getLivestreamUrl(); expect(liveStreamUrl.livestreamUrl).toBeDefined(); } await p1.getIframeAPI().executeCommand('stopRecording', 'stream'); if (webhooksProxy) { const liveStreamEvent: { customerId: string; eventType: string; } = await webhooksProxy.waitForEvent('LIVE_STREAM_ENDED'); expect('LIVE_STREAM_ENDED').toBe(liveStreamEvent.eventType); expect(liveStreamEvent.customerId).toBe(customerId); } const stoppedStatusEvent = (await p1.getIframeAPI().getEventResult('recordingStatusChanged')); expect(stoppedStatusEvent.mode).toBe('stream'); expect(stoppedStatusEvent.on).toBe(false); }); }); /** * Checks if the recording is started. * @param command */ async function testRecordingStarted(command: boolean) { const { p1, webhooksProxy } = ctx; await p1.switchToAPI(); await p1.getIframeAPI().addEventListener('recordingStatusChanged'); await p1.getIframeAPI().addEventListener('recordingLinkAvailable'); if (command) { await p1.getIframeAPI().executeCommand('startRecording', { mode: 'file' }); } else { await p1.getIframeAPI().startRecording({ mode: 'file' }); } if (webhooksProxy) { const recordingEvent: { customerId: string; eventType: string; } = await webhooksProxy.waitForEvent('RECORDING_STARTED'); expect('RECORDING_STARTED').toBe(recordingEvent.eventType); expect(recordingEvent.customerId).toBe(customerId); webhooksProxy?.clearCache(); } const statusEvent = (await p1.getIframeAPI().getEventResult('recordingStatusChanged')); expect(statusEvent.mode).toBe('file'); expect(statusEvent.on).toBe(true); const linkEvent = (await p1.getIframeAPI().getEventResult('recordingLinkAvailable')); expect(linkEvent.link.startsWith('https://')).toBe(true); expect(linkEvent.link.includes(tenant)).toBe(true); expect(linkEvent.ttl > 0).toBe(true); } /** * Checks if the recording is stopped. * @param command */ async function testRecordingStopped(command: boolean) { const { p1, webhooksProxy } = ctx; await p1.switchToAPI(); if (command) { await p1.getIframeAPI().executeCommand('stopRecording', 'file'); } else { await p1.getIframeAPI().stopRecording('file'); } if (webhooksProxy) { const liveStreamEvent: { customerId: string; eventType: string; } = await webhooksProxy.waitForEvent('RECORDING_ENDED'); expect('RECORDING_ENDED').toBe(liveStreamEvent.eventType); expect(liveStreamEvent.customerId).toBe(customerId); const recordingUploadedEvent: { customerId: string; data: { initiatorId: string; participants: Array; }; eventType: string; } = await webhooksProxy.waitForEvent('RECORDING_UPLOADED'); const jwtPayload = p1.getToken()?.payload; expect(recordingUploadedEvent.data.initiatorId).toBe(jwtPayload?.context?.user?.id); expect(recordingUploadedEvent.data.participants.some( // @ts-ignore e => e.id === jwtPayload?.context?.user?.id)).toBe(true); webhooksProxy?.clearCache(); } const statusEvent = (await p1.getIframeAPI().getEventResult('recordingStatusChanged')); expect(statusEvent.mode).toBe('file'); expect(statusEvent.on).toBe(false); await p1.getIframeAPI().clearEventResults('recordingStatusChanged'); }