Skip to content
Open
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions e2e/global-setup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,7 @@ async function globalSetup(config: FullConfig) {
...serverConfig.PluginSettings.Plugins[pluginID],
defaultenabled: true,
enableringing: true,
enablevideo: true,
},
};
await adminContext.put('/api/v4/config', {
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
248 changes: 247 additions & 1 deletion e2e/tests/media.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,10 @@ import {expect, test} from '@playwright/test';

import {apiSetEnableAV1} from '../config';
import PlaywrightDevPage from '../page';
import {getUserStoragesForTest, startCall} from '../utils';
import {getUsernamesForTest, getUserStoragesForTest, startCall, startDMWith} from '../utils';

const userStorages = getUserStoragesForTest();
const usernames = getUsernamesForTest();

test.beforeEach(async ({page}) => {
const devPage = new PlaywrightDevPage(page);
Expand Down Expand Up @@ -355,3 +356,248 @@ test.describe('sending voice', () => {
await Promise.all([devPage.leaveCall(), userPage.leaveCall()]);
});
});

test.describe('video calls', () => {
test.use({storageState: userStorages[0]});

test.describe('widget', () => {
test('self only', {
tag: '@core',
}, async ({page}) => {
const userAPage = new PlaywrightDevPage(page);
await userAPage.gotoDM(usernames[1]);
await userAPage.startCall();

// Start video
await userAPage.page.locator('#video-start-stop').click();

// Verify self view shows
await expect(userAPage.page.getByTestId('calls-widget-video-player-self')).toBeVisible();

// Verify video track is correctly set
const videoTrackID = await (await userAPage.page.waitForFunction(() => {
return window.callsClient.localVideoStream?.getVideoTracks()[0]?.id;
})).evaluate(() => {
return window.callsClient.localVideoStream?.getVideoTracks()[0]?.id;
});
expect(videoTrackID).toBeTruthy();

// Stop video
await page.locator('#video-start-stop').click();

// Verify self view is hidden
await expect(userAPage.page.getByTestId('calls-widget-video-player-self')).toBeHidden();

await userAPage.leaveCall();
});

test('1-1', {
tag: '@core',
}, async ({page}) => {
const userAPage = new PlaywrightDevPage(page);

const [_, userBPage] = await Promise.all([
userAPage.gotoDM(usernames[1]),
startDMWith(userStorages[1], usernames[0]),
]);

await Promise.all([userBPage.startCall(), userAPage.joinCall()]);

// User A starts video
await userAPage.page.locator('#video-start-stop').click();

// Verify userA's video shows
await expect(userAPage.page.getByTestId('calls-widget-video-player-self')).toBeVisible();

// Verify placeholder with userB's avatar shows
await expect(userAPage.page.getByTestId('calls-widget-video-placeholder-other')).toBeVisible();

// Verify userA's video is visible on userB's side
await expect(userBPage.page.getByTestId('calls-widget-video-player-other')).toBeVisible();

// Verify remote video tracks are correctly set
let videoTrackID = await (await userBPage.page.waitForFunction(() => {
return window.callsClient.getRemoteVideoStream()?.getVideoTracks()[0]?.id;
})).evaluate(() => {
return window.callsClient.getRemoteVideoStream()?.getVideoTracks()[0]?.id;
});
expect(videoTrackID).toBeTruthy();

// User A stops video
await userAPage.page.locator('#video-start-stop').click();

// Verify video interface is not rendered on both sides
await expect(userAPage.page.getByTestId('calls-widget-video-player-self')).toBeHidden();
await expect(userAPage.page.getByTestId('calls-widget-video-player-other')).toBeHidden();
await expect(userAPage.page.getByTestId('calls-widget-video-placeholder-self')).toBeHidden();
await expect(userAPage.page.getByTestId('calls-widget-video-placeholder-other')).toBeHidden();

await expect(userBPage.page.getByTestId('calls-widget-video-player-self')).toBeHidden();
await expect(userBPage.page.getByTestId('calls-widget-video-player-other')).toBeHidden();
await expect(userBPage.page.getByTestId('calls-widget-video-placeholder-self')).toBeHidden();
await expect(userBPage.page.getByTestId('calls-widget-video-placeholder-other')).toBeHidden();

// User B starts video
await userBPage.page.locator('#video-start-stop').click();

// Verify placeholder with userB's avatar is hidden
await expect(userAPage.page.getByTestId('calls-widget-video-placeholder-self')).toBeVisible();
await expect(userAPage.page.getByTestId('calls-widget-video-placeholder-other')).toBeHidden();

// Verify userB's video shows
await expect(userAPage.page.getByTestId('calls-widget-video-player-other')).toBeVisible();
await expect(userBPage.page.getByTestId('calls-widget-video-player-self')).toBeVisible();

// Verify remote video tracks are correctly set
videoTrackID = await (await userAPage.page.waitForFunction(() => {
return window.callsClient.getRemoteVideoStream()?.getVideoTracks()[0]?.id;
})).evaluate(() => {
return window.callsClient.getRemoteVideoStream()?.getVideoTracks()[0]?.id;
});
expect(videoTrackID).toBeTruthy();

await Promise.all([userAPage.leaveCall(), userBPage.leaveCall()]);
});
});

test.describe('popout', () => {
test('self only', {
tag: '@core',
}, async ({page}) => {
const userAPage = new PlaywrightDevPage(page);
await userAPage.gotoDM(usernames[1]);
await userAPage.startCall();

const popOut = await userAPage.openPopout();

// Start video
await popOut.page.locator('#calls-popout-video-button').click();

// Verify self view shows
await expect(popOut.page.getByTestId('calls-popout-video-player-self')).toBeVisible();

// Verify video track is correctly set
const videoTrackID = await (await userAPage.page.waitForFunction(() => {
return window.callsClient.localVideoStream?.getVideoTracks()[0]?.id;
})).evaluate(() => {
return window.callsClient.localVideoStream?.getVideoTracks()[0]?.id;
});
expect(videoTrackID).toBeTruthy();

// Stop video
await popOut.page.locator('#calls-popout-video-button').click();

// Verify self view is hidden
await expect(popOut.page.getByTestId('calls-popout-video-player-self')).toBeHidden();

await userAPage.leaveCall();
});

test('1-1', {
tag: '@core',
}, async ({page}) => {
const userAPage = new PlaywrightDevPage(page);

const [_, userBPage] = await Promise.all([
userAPage.gotoDM(usernames[1]),
startDMWith(userStorages[1], usernames[0]),
]);

await Promise.all([userBPage.startCall(), userAPage.joinCall()]);

const [popOutA, popOutB] = await Promise.all([userAPage.openPopout(), userBPage.openPopout()]);

// User A starts video
await popOutA.page.locator('#calls-popout-video-button').click();

// Verify userA's video shows
await expect(popOutA.page.getByTestId('calls-popout-video-player-self')).toBeVisible();

// Verify userA's video is visible on userB's side
await expect(popOutB.page.getByTestId('calls-popout-video-player-other')).toBeVisible();

// Verify remote video tracks are correctly set
let videoTrackID = await (await userBPage.page.waitForFunction(() => {
return window.callsClient.getRemoteVideoStream()?.getVideoTracks()[0]?.id;
})).evaluate(() => {
return window.callsClient.getRemoteVideoStream()?.getVideoTracks()[0]?.id;
});
expect(videoTrackID).toBeTruthy();

// User A stops video
await popOutA.page.locator('#calls-popout-video-button').click();

// Verify video is no longer visible
await expect(popOutA.page.getByTestId('calls-popout-video-player-self')).toBeHidden();
await expect(popOutB.page.getByTestId('calls-popout-video-player-other')).toBeHidden();

// User B starts video
await popOutB.page.locator('#calls-popout-video-button').click();

// Verify userB's video shows
await expect(popOutB.page.getByTestId('calls-popout-video-player-self')).toBeVisible();
await expect(popOutA.page.getByTestId('calls-popout-video-player-other')).toBeVisible();

// Verify remote video tracks are correctly set
videoTrackID = await (await userAPage.page.waitForFunction(() => {
return window.callsClient.getRemoteVideoStream()?.getVideoTracks()[0]?.id;
})).evaluate(() => {
return window.callsClient.getRemoteVideoStream()?.getVideoTracks()[0]?.id;
});
expect(videoTrackID).toBeTruthy();

await Promise.all([userAPage.leaveCall(), userBPage.leaveCall()]);
});

test('video + screen sharing', {
tag: '@core',
}, async ({page}) => {
const userAPage = new PlaywrightDevPage(page);

const [_, userBPage] = await Promise.all([
userAPage.gotoDM(usernames[1]),
startDMWith(userStorages[1], usernames[0]),
]);

await Promise.all([userBPage.startCall(), userAPage.joinCall()]);

const [popOutA, popOutB] = await Promise.all([userAPage.openPopout(), userBPage.openPopout()]);

// User A and B start video
await popOutA.page.locator('#calls-popout-video-button').click();
await popOutB.page.locator('#calls-popout-video-button').click();

// Verify video shows on both sides
await expect(popOutA.page.getByTestId('calls-popout-video-player-self')).toBeVisible();
await expect(popOutA.page.getByTestId('calls-popout-video-player-other')).toBeVisible();
await expect(popOutB.page.getByTestId('calls-popout-video-player-self')).toBeVisible();
await expect(popOutB.page.getByTestId('calls-popout-video-player-other')).toBeVisible();

// User A starts screen sharing
await popOutA.page.locator('#calls-popout-screenshare-button').click();

// Verify screen player is visible
await expect(popOutA.page.locator('#screen-player')).toBeVisible();
await expect(popOutB.page.locator('#screen-player')).toBeVisible();

// Wait a second for the screen sharing to start.
await userAPage.wait(1000);

// Verify the player is actually showing something on both sides
let box = await popOutA.page.locator('#screen-player').boundingBox();
expect(box?.width).toBeGreaterThan(700);
expect(box?.height).toBeGreaterThan(300);
box = await popOutB.page.locator('#screen-player').boundingBox();
expect(box?.width).toBeGreaterThan(700);
expect(box?.height).toBeGreaterThan(300);

// Verify video still shows on both sides
await expect(popOutA.page.getByTestId('calls-popout-video-player-self')).toBeVisible();
await expect(popOutA.page.getByTestId('calls-popout-video-player-other')).toBeVisible();
await expect(popOutB.page.getByTestId('calls-popout-video-player-self')).toBeVisible();
await expect(popOutB.page.getByTestId('calls-popout-video-player-other')).toBeVisible();

await Promise.all([userAPage.leaveCall(), userBPage.leaveCall()]);
});
});
});
96 changes: 85 additions & 11 deletions e2e/tests/start_call.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -242,20 +242,20 @@ test.describe('setting audio input device', () => {
await devPage.startCall();

await page.locator('#calls-widget-toggle-menu-button').click();
await expect(page.locator('#calls-widget-audio-input-button')).toBeVisible();
await page.locator('#calls-widget-audio-input-button').click();
await expect(page.locator('#calls-widget-audio-inputs-menu')).toBeVisible();
await expect(page.locator('#calls-widget-audioinput-button')).toBeVisible();
await page.locator('#calls-widget-audioinput-button').click();
await expect(page.locator('#calls-widget-audioinputs-menu')).toBeVisible();

const currentAudioInputDeviceID = await page.evaluate(() => {
return window.callsClient.currentInputAudioDevice?.deviceId;
return window.callsClient.currentAudioInputDevice?.deviceId;
});
if (currentAudioInputDeviceID) {
test.fail();
return;
}

await page.locator('#calls-widget-audio-inputs-menu button:has-text("Fake Audio Input 1")').click();
await expect(page.locator('#calls-widget-audio-inputs-menu')).toBeHidden();
await page.locator('#calls-widget-audioinputs-menu button:has-text("Fake Audio Input 1")').click();
await expect(page.locator('#calls-widget-audioinputs-menu')).toBeHidden();

const currentAudioInputDevice = await page.evaluate(() => {
return window.callsClient.currentAudioInputDevice;
Expand Down Expand Up @@ -312,9 +312,9 @@ test.describe('setting audio output device', () => {
await devPage.startCall();

await page.locator('#calls-widget-toggle-menu-button').click();
await expect(page.locator('#calls-widget-audio-output-button')).toBeVisible();
await page.locator('#calls-widget-audio-output-button').click();
await expect(page.locator('#calls-widget-audio-outputs-menu')).toBeVisible();
await expect(page.locator('#calls-widget-audiooutput-button')).toBeVisible();
await page.locator('#calls-widget-audiooutput-button').click();
await expect(page.locator('#calls-widget-audiooutputs-menu')).toBeVisible();

const currentAudioOutputDeviceID = await page.evaluate(() => {
return window.callsClient.currentAudioOutputDevice?.deviceId;
Expand All @@ -324,8 +324,8 @@ test.describe('setting audio output device', () => {
return;
}

await page.locator('#calls-widget-audio-outputs-menu button:has-text("Fake Audio Output 1")').click();
await expect(page.locator('#calls-widget-audio-outputs-menu')).toBeHidden();
await page.locator('#calls-widget-audiooutputs-menu button:has-text("Fake Audio Output 1")').click();
await expect(page.locator('#calls-widget-audiooutputs-menu')).toBeHidden();

const currentAudioOutputDevice = await page.evaluate(() => {
return window.callsClient.currentAudioOutputDevice;
Expand Down Expand Up @@ -598,3 +598,77 @@ test.describe('widget menu', () => {
await devPage.leaveCall();
});
});

test.describe('setting video input device', () => {
test.use({storageState: userStorages[0]});

test('no default', async ({page}) => {
const devPage = new PlaywrightDevPage(page);
await devPage.startCall();

const currentVideoInputDevice = await page.evaluate(() => {
return window.callsClient.currentVideoInputDevice?.deviceId;
});
if (currentVideoInputDevice) {
test.fail();
return;
}

await devPage.leaveCall();
});

test('setting default', async ({page}) => {
const devPage = new PlaywrightDevPage(page);

// Video is only available in DMs
await devPage.gotoDM(usernames[1]);

await devPage.startCall();

await page.locator('#calls-widget-toggle-menu-button').click();
await expect(page.locator('#calls-widget-videoinput-button')).toBeVisible();
await page.locator('#calls-widget-videoinput-button').click();
await expect(page.locator('#calls-widget-videoinputs-menu')).toBeVisible();

const currentVideoInputDeviceID = await page.evaluate(() => {
return window.callsClient.currentVideoInputDevice?.deviceId;
});
if (currentVideoInputDeviceID) {
test.fail();
return;
}

await page.locator('#calls-widget-videoinputs-menu button:has-text("fake_device_0")').click();
await expect(page.locator('#calls-widget-videoinputs-menu')).toBeHidden();

const currentVideoInputDevice = await page.evaluate(() => {
return window.callsClient.currentVideoInputDevice;
});
if (currentVideoInputDevice.label !== 'fake_device_0') {
test.fail();
return;
}

await devPage.leaveCall();

await devPage.startCall();

const currentVideoInputDevice2 = await page.evaluate(() => {
return window.callsClient.currentVideoInputDevice?.deviceId;
});
if (currentVideoInputDevice2 !== currentVideoInputDevice.deviceId) {
test.fail();
return;
}

await devPage.leaveCall();

await page.reload();
const device = await page.evaluate(() => {
return JSON.parse(window.localStorage.getItem('calls_default_video_input')!);
});
if (!device || !device.deviceId || !device.label) {
test.fail();
}
});
});
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading