Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[MM-55503] Add support for new DesktopAPI #602

Merged
merged 22 commits into from
Feb 9, 2024
Merged
Show file tree
Hide file tree
Changes from all 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
241 changes: 241 additions & 0 deletions e2e/tests/desktop.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,241 @@
import {expect, test} from '@playwright/test';
import {readFile} from 'fs/promises';

import PlaywrightDevPage from '../page';
import type {DesktopAPICalls} from '../types';
import {
getChannelNamesForTest,
getUserStoragesForTest,
} from '../utils';

const userStorages = getUserStoragesForTest();

const desktopAPICalls: DesktopAPICalls = {
getAppInfo: false,
onCallsError: false,
openScreenShareModal: false,
onScreenShared: false,
sendCallsError: false,
leaveCall: false,
};

test.beforeEach(async ({page}, info) => {
if (info.title.startsWith('desktopAPI')) {
await page.exposeFunction('getAppInfo', () => {
desktopAPICalls.getAppInfo = true;
return {version: '5.7.0'};
});

await page.exposeFunction('onCallsError', () => {
desktopAPICalls.onCallsError = true;
});

await page.exposeFunction('openScreenShareModal', () => {
desktopAPICalls.openScreenShareModal = true;
});

await page.exposeFunction('onScreenShared', () => {
desktopAPICalls.onScreenShared = true;
});

await page.exposeFunction('sendCallsError', () => {
desktopAPICalls.sendCallsError = true;
});

await page.exposeFunction('leaveCall', () => {
desktopAPICalls.leaveCall = true;
});

await page.addInitScript(() => {
window.desktopAPI = {
getAppInfo: window.getAppInfo,
openScreenShareModal: window.openScreenShareModal,
onCallsError: () => {
window.onCallsError();

return () => {}; // eslint-disable-line @typescript-eslint/no-empty-function
},
onScreenShared: () => {
window.onScreenShared();

return () => {}; // eslint-disable-line @typescript-eslint/no-empty-function
},
sendCallsError: window.sendCallsError,
leaveCall: window.leaveCall,
};
});
}

const devPage = new PlaywrightDevPage(page);
await devPage.goto();
});

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

test('screen sharing < 5.1.0', async ({page}) => {
await page.evaluate(() => {
window.desktop = {version: '5.0.0'};
});
const devPage = new PlaywrightDevPage(page);
await devPage.startCall();
await page.locator('#calls-widget-toggle-menu-button').click();
await page.locator('#calls-widget-menu-screenshare').click();
await expect(page.locator('#calls-screen-source-modal')).toBeHidden();
await devPage.leaveCall();
});

test('screen source modal >= 5.1.0', async ({page}) => {
const data = await readFile('./assets/screen.png', {encoding: 'base64'});
const sourceURI = `data:image/png;base64,${data}`;
await page.evaluate((thumbnailURL) => {
window.desktop = {version: '5.1.0'};
window.addEventListener('message', (event) => {
if (event.data.type !== 'get-desktop-sources') {
return;
}

window.postMessage({
type: 'desktop-sources-result',
message: [
{id: '1', name: 'source_1', thumbnailURL},
{id: '2', name: 'source_2', thumbnailURL},
{id: '3', name: 'source_3', thumbnailURL},
],
},
window.location.origin);
});
}, sourceURI);

const devPage = new PlaywrightDevPage(page);
await devPage.startCall();
await page.locator('#calls-widget-toggle-menu-button').click();
await page.locator('#calls-widget-menu-screenshare').click();
await expect(page.locator('#calls-screen-source-modal')).toBeVisible();
expect(await page.locator('#calls-screen-source-modal').screenshot()).toMatchSnapshot('calls-screen-source-modal.png');
await page.locator('#calls-screen-source-modal button:has-text("source_2")').click();
await page.locator('#calls-screen-source-modal button:has-text("Share")').click();
await expect(page.locator('#calls-screen-source-modal')).toBeHidden();
await devPage.leaveCall();
});

test('desktopAPI: screen sharing', async ({page}) => {
await page.addInitScript(() => {
window.desktopAPI.onScreenShared = (listener: (sourceID: string, withAudio: boolean) => void) => {
window.desktopAPI.openScreenShareModal = () => {
window.openScreenShareModal();
listener('', false);
};

window.onScreenShared();

return () => {}; // eslint-disable-line @typescript-eslint/no-empty-function
};

// Some browser API mocking needed given screen sharing is a little different
// on Electron.

// @ts-ignore
navigator.mediaDevices.getUserMediaOriginal = navigator.mediaDevices.getUserMedia;
navigator.mediaDevices.getUserMedia = (opts) => {
if (opts?.audio) {
// @ts-ignore
return navigator.mediaDevices.getUserMediaOriginal({
video: false,
audio: true,
});
}

return navigator.mediaDevices.getDisplayMedia({
video: true,
audio: false,
});
};
});

// start call in global widget
const devPage = new PlaywrightDevPage(page);
await devPage.openWidget(getChannelNamesForTest()[0]);

expect(desktopAPICalls.getAppInfo).toBe(true);
expect(desktopAPICalls.onScreenShared).toBe(true);

// click screen sharing button
await page.locator('#calls-widget-toggle-menu-button').click();
await page.locator('#calls-widget-menu-screenshare').click();

expect(desktopAPICalls.openScreenShareModal).toBe(true);

// verify we are screen sharing
await expect(devPage.page.locator('#screen-player')).toBeVisible();

await devPage.leaveCall();
});

test('desktopAPI: screen sharing permissions error', async ({page}) => {
await page.addInitScript(() => {
window.desktopAPI.onScreenShared = (listener: (sourceID: string, withAudio: boolean) => void) => {
window.desktopAPI.openScreenShareModal = () => {
window.openScreenShareModal();
listener('', false);
};

window.onScreenShared();

return () => {}; // eslint-disable-line @typescript-eslint/no-empty-function
};
});

// start call in global widget
const devPage = new PlaywrightDevPage(page);
await devPage.openWidget(getChannelNamesForTest()[0]);

expect(desktopAPICalls.getAppInfo).toBe(true);
expect(desktopAPICalls.onScreenShared).toBe(true);

// click screen sharing button
await page.locator('#calls-widget-toggle-menu-button').click();
await page.locator('#calls-widget-menu-screenshare').click();

expect(desktopAPICalls.openScreenShareModal).toBe(true);

// verify screen sharing is failing
await expect(page.locator('#screen-player')).toBeHidden();
await expect(page.getByTestId('calls-widget-banner-alert')).toBeVisible();

await devPage.leaveCall();
});

test('desktopAPI: calls client error', async ({page}) => {
// start call in global widget
const devPage = new PlaywrightDevPage(page);
await devPage.openWidget(getChannelNamesForTest()[0]);

// Verify no error was sent
expect(desktopAPICalls.sendCallsError).toBe(false);

// Fake client failure
await page.evaluate(() => {
window.callsClient.disconnect(new Error('rtc peer error'));
});

await expect(devPage.page.locator('#calls-widget')).toBeHidden();

// Verify error is getting sent
expect(desktopAPICalls.sendCallsError).toBe(true);
});

test('desktopAPI: leave call', async ({page}) => {
// start call in global widget
const devPage = new PlaywrightDevPage(page);
await devPage.openWidget(getChannelNamesForTest()[0]);
await devPage.leaveCall();

// Need to wait a moment since the the leave call happens in
// a setTimeout handler.
await devPage.wait(500);

// Verify error is getting sent
expect(desktopAPICalls.leaveCall).toBe(true);
});
});
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.
50 changes: 0 additions & 50 deletions e2e/tests/start_call.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -161,56 +161,6 @@ test.describe('start new call', () => {
});
});

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

test('screen sharing < 5.1.0', async ({page}) => {
await page.evaluate(() => {
window.desktop = {version: '5.0.0'};
});
const devPage = new PlaywrightDevPage(page);
await devPage.startCall();
await page.locator('#calls-widget-toggle-menu-button').click();
await page.locator('#calls-widget-menu-screenshare').click();
await expect(page.locator('#calls-screen-source-modal')).toBeHidden();
await devPage.leaveCall();
});

test('screen source modal >= 5.1.0', async ({page}) => {
const data = await readFile('./assets/screen.png', {encoding: 'base64'});
const sourceURI = `data:image/png;base64,${data}`;
await page.evaluate((thumbnailURL) => {
window.desktop = {version: '5.1.0'};
window.addEventListener('message', (event) => {
if (event.data.type !== 'get-desktop-sources') {
return;
}

window.postMessage({
type: 'desktop-sources-result',
message: [
{id: '1', name: 'source_1', thumbnailURL},
{id: '2', name: 'source_2', thumbnailURL},
{id: '3', name: 'source_3', thumbnailURL},
],
},
window.location.origin);
});
}, sourceURI);

const devPage = new PlaywrightDevPage(page);
await devPage.startCall();
await page.locator('#calls-widget-toggle-menu-button').click();
await page.locator('#calls-widget-menu-screenshare').click();
await expect(page.locator('#calls-screen-source-modal')).toBeVisible();
expect(await page.locator('#calls-screen-source-modal').screenshot()).toMatchSnapshot('calls-screen-source-modal.png');
await page.locator('#calls-screen-source-modal button:has-text("source_2")').click();
await page.locator('#calls-screen-source-modal button:has-text("Share")').click();
await expect(page.locator('#calls-screen-source-modal')).toBeHidden();
await devPage.leaveCall();
});
});

test.describe('auto join link', () => {
test.use({storageState: userStorages[0]});

Expand Down
Binary file not shown.
Binary file not shown.
Binary file not shown.
20 changes: 19 additions & 1 deletion e2e/types.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,22 @@
declare global {
interface Window {
callsClient: any,
desktop: any,
isHandRaised: boolean;
e2eDesktopNotificationsRejected?: DesktopNotificationArgs[],
e2eDesktopNotificationsSent?: string[],
e2eNotificationsSoundedAt?: number[],
e2eNotificationsSoundStoppedAt?: number[],
e2eRingLength?: number,

// Desktop Mocking
desktop: any,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You probably don't need this anymore, it's unfortunately still there because of the version field, which has been replaced by getAppInfo under the desktopAPI

desktopAPI: any,
getAppInfo: () => void,
openScreenShareModal: () => void,
onCallsError: () => void,
onScreenShared: () => void,
sendCallsError: () => void,
leaveCall: () => void,
}
}

Expand All @@ -25,3 +34,12 @@ export type DesktopNotificationArgs = {
url: string;
notify: boolean;
};

export type DesktopAPICalls = {
getAppInfo: boolean;
onCallsError: boolean;
openScreenShareModal: boolean;
onScreenShared: boolean;
sendCallsError: boolean;
leaveCall: boolean;
};
19 changes: 17 additions & 2 deletions standalone/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion standalone/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
"@babel/preset-typescript": "7.16.0",
"@formatjs/cli": "6.0.4",
"@mattermost/client": "file:../webapp/mattermost-webapp/webapp/platform/client",
"@mattermost/desktop-api": "5.7.0-3",
"@mattermost/types": "file:../webapp/mattermost-webapp/webapp/platform/types",
"@types/jest": "27.0.2",
"@types/lodash": "4.14.182",
Expand Down Expand Up @@ -70,7 +71,7 @@
"webpack-cli": "4.10.0"
},
"dependencies": {
"@calls/common": "github:mattermost/calls-common#25619914bcfe6347101b29204b2976518742e81e",
"@calls/common": "github:mattermost/calls-common#70e226f00822a23189c1577d02b711514cdaf2b6",
"@mattermost/compass-icons": "0.1.31",
"@msgpack/msgpack": "2.7.1",
"bootstrap": "3.4.1",
Expand Down
Loading
Loading