You've already forked matrix-js-sdk
mirror of
https://github.com/matrix-org/matrix-js-sdk.git
synced 2025-08-07 23:02:56 +03:00
1:1 screenshare tests (#2617)
* 1:1 screenshare tests Fixes https://github.com/vector-im/element-call/issues/548 * Always hang up calls after tests to prevent hanging tests Also fix a null dereference as we may not have an invitee or opponent member when sending voip events if not using to-device messages. * use mockImplementationOnce Co-authored-by: Robin <robin@robin.town> * use mockImplementationOnce Co-authored-by: Robin <robin@robin.town> * Add type on mock * Add corresponding call.off * Merge enable & disable screenshare tests Co-authored-by: Robin <robin@robin.town>
This commit is contained in:
@@ -56,6 +56,9 @@ export const DUMMY_SDP = (
|
|||||||
"a=ssrc:3619738545 cname:2RWtmqhXLdoF4sOi\r\n"
|
"a=ssrc:3619738545 cname:2RWtmqhXLdoF4sOi\r\n"
|
||||||
);
|
);
|
||||||
|
|
||||||
|
export const USERMEDIA_STREAM_ID = "mock_stream_from_media_handler";
|
||||||
|
export const SCREENSHARE_STREAM_ID = "mock_screen_stream_from_media_handler";
|
||||||
|
|
||||||
class MockMediaStreamAudioSourceNode {
|
class MockMediaStreamAudioSourceNode {
|
||||||
connect() {}
|
connect() {}
|
||||||
}
|
}
|
||||||
@@ -128,6 +131,10 @@ export class MockRTCPeerConnection {
|
|||||||
return new MockRTCRtpSender(track);
|
return new MockRTCRtpSender(track);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
removeTrack() {
|
||||||
|
this.needsNegotiation = true;
|
||||||
|
}
|
||||||
|
|
||||||
doNegotiation() {
|
doNegotiation() {
|
||||||
if (this.needsNegotiation && this.negotiationNeededListener) {
|
if (this.needsNegotiation && this.negotiationNeededListener) {
|
||||||
this.needsNegotiation = false;
|
this.needsNegotiation = false;
|
||||||
@@ -222,7 +229,7 @@ export class MockMediaHandler {
|
|||||||
if (audio) tracks.push(new MockMediaStreamTrack("audio_track", "audio"));
|
if (audio) tracks.push(new MockMediaStreamTrack("audio_track", "audio"));
|
||||||
if (video) tracks.push(new MockMediaStreamTrack("video_track", "video"));
|
if (video) tracks.push(new MockMediaStreamTrack("video_track", "video"));
|
||||||
|
|
||||||
const stream = new MockMediaStream("mock_stream_from_media_handler", tracks);
|
const stream = new MockMediaStream(USERMEDIA_STREAM_ID, tracks);
|
||||||
this.userMediaStreams.push(stream);
|
this.userMediaStreams.push(stream);
|
||||||
return stream;
|
return stream;
|
||||||
}
|
}
|
||||||
@@ -233,7 +240,7 @@ export class MockMediaHandler {
|
|||||||
const tracks = [new MockMediaStreamTrack("video_track", "video")];
|
const tracks = [new MockMediaStreamTrack("video_track", "video")];
|
||||||
if (opts?.audio) tracks.push(new MockMediaStreamTrack("audio_track", "audio"));
|
if (opts?.audio) tracks.push(new MockMediaStreamTrack("audio_track", "audio"));
|
||||||
|
|
||||||
const stream = new MockMediaStream("mock_screen_stream_from_media_handler", tracks);
|
const stream = new MockMediaStream(SCREENSHARE_STREAM_ID, tracks);
|
||||||
this.screensharingStreams.push(stream);
|
this.screensharingStreams.push(stream);
|
||||||
return stream;
|
return stream;
|
||||||
}
|
}
|
||||||
|
@@ -30,6 +30,8 @@ import {
|
|||||||
MockMediaStream,
|
MockMediaStream,
|
||||||
MockMediaStreamTrack,
|
MockMediaStreamTrack,
|
||||||
installWebRTCMocks,
|
installWebRTCMocks,
|
||||||
|
MockRTCPeerConnection,
|
||||||
|
SCREENSHARE_STREAM_ID,
|
||||||
} from "../../test-utils/webrtc";
|
} from "../../test-utils/webrtc";
|
||||||
import { CallFeed } from "../../../src/webrtc/callFeed";
|
import { CallFeed } from "../../../src/webrtc/callFeed";
|
||||||
import { EventType, MatrixEvent } from "../../../src";
|
import { EventType, MatrixEvent } from "../../../src";
|
||||||
@@ -117,6 +119,9 @@ describe('Call', function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
afterEach(function() {
|
afterEach(function() {
|
||||||
|
// Hangup to stop timers
|
||||||
|
call.hangup(CallErrorCode.UserHangup, true);
|
||||||
|
|
||||||
client.stop();
|
client.stop();
|
||||||
global.navigator = prevNavigator;
|
global.navigator = prevNavigator;
|
||||||
global.window = prevWindow;
|
global.window = prevWindow;
|
||||||
@@ -178,9 +183,6 @@ describe('Call', function() {
|
|||||||
getSender: () => "@test:foo",
|
getSender: () => "@test:foo",
|
||||||
});
|
});
|
||||||
expect(call.peerConn.addIceCandidate.mock.calls.length).toBe(1);
|
expect(call.peerConn.addIceCandidate.mock.calls.length).toBe(1);
|
||||||
|
|
||||||
// Hangup to stop timers
|
|
||||||
call.hangup(CallErrorCode.UserHangup, true);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should add candidates received before answer if party ID is correct', async function() {
|
it('should add candidates received before answer if party ID is correct', async function() {
|
||||||
@@ -283,9 +285,6 @@ describe('Call', function() {
|
|||||||
const ident = call.getRemoteAssertedIdentity();
|
const ident = call.getRemoteAssertedIdentity();
|
||||||
expect(ident.id).toEqual("@steve:example.com");
|
expect(ident.id).toEqual("@steve:example.com");
|
||||||
expect(ident.displayName).toEqual("Steve Gibbons");
|
expect(ident.displayName).toEqual("Steve Gibbons");
|
||||||
|
|
||||||
// Hangup to stop timers
|
|
||||||
call.hangup(CallErrorCode.UserHangup, true);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should map SDPStreamMetadata to feeds", async () => {
|
it("should map SDPStreamMetadata to feeds", async () => {
|
||||||
@@ -734,16 +733,18 @@ describe('Call', function() {
|
|||||||
|
|
||||||
describe("ignoring streams with ids for which we already have a feed", () => {
|
describe("ignoring streams with ids for which we already have a feed", () => {
|
||||||
const STREAM_ID = "stream_id";
|
const STREAM_ID = "stream_id";
|
||||||
const FEEDS_CHANGED_CALLBACK = jest.fn();
|
let FEEDS_CHANGED_CALLBACK: jest.Mock<void, []>;
|
||||||
|
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
|
FEEDS_CHANGED_CALLBACK = jest.fn();
|
||||||
|
|
||||||
await startVoiceCall(client, call);
|
await startVoiceCall(client, call);
|
||||||
call.on(CallEvent.FeedsChanged, FEEDS_CHANGED_CALLBACK);
|
call.on(CallEvent.FeedsChanged, FEEDS_CHANGED_CALLBACK);
|
||||||
jest.spyOn(call, "pushLocalFeed");
|
jest.spyOn(call, "pushLocalFeed");
|
||||||
});
|
});
|
||||||
|
|
||||||
afterEach(() => {
|
afterEach(() => {
|
||||||
FEEDS_CHANGED_CALLBACK.mockReset();
|
call.off(CallEvent.FeedsChanged, FEEDS_CHANGED_CALLBACK);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should ignore stream passed to pushRemoteFeed()", async () => {
|
it("should ignore stream passed to pushRemoteFeed()", async () => {
|
||||||
@@ -941,4 +942,70 @@ describe('Call', function() {
|
|||||||
|
|
||||||
expect(call.state).toEqual(CallState.Ended);
|
expect(call.state).toEqual(CallState.Ended);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe("Screen sharing", () => {
|
||||||
|
beforeEach(async () => {
|
||||||
|
await startVoiceCall(client, call);
|
||||||
|
|
||||||
|
await call.onAnswerReceived({
|
||||||
|
getContent: () => {
|
||||||
|
return {
|
||||||
|
"version": 1,
|
||||||
|
"call_id": call.callId,
|
||||||
|
"party_id": 'party_id',
|
||||||
|
"answer": {
|
||||||
|
sdp: DUMMY_SDP,
|
||||||
|
},
|
||||||
|
"org.matrix.msc3077.sdp_stream_metadata": {
|
||||||
|
"foo": {
|
||||||
|
"purpose": "m.usermedia",
|
||||||
|
"audio_muted": false,
|
||||||
|
"video_muted": false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
},
|
||||||
|
getSender: () => "@test:foo",
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
// Hangup to stop timers
|
||||||
|
call.hangup(CallErrorCode.UserHangup, true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("enables and disables screensharing", async () => {
|
||||||
|
await call.setScreensharingEnabled(true);
|
||||||
|
|
||||||
|
expect(call.feeds.filter(f => f.purpose == SDPStreamMetadataPurpose.Screenshare).length).toEqual(1);
|
||||||
|
|
||||||
|
client.client.sendEvent.mockReset();
|
||||||
|
const sendNegotiatePromise = new Promise<void>(resolve => {
|
||||||
|
client.client.sendEvent.mockImplementationOnce(() => {
|
||||||
|
resolve();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
MockRTCPeerConnection.triggerAllNegotiations();
|
||||||
|
await sendNegotiatePromise;
|
||||||
|
|
||||||
|
expect(client.client.sendEvent).toHaveBeenCalledWith(
|
||||||
|
FAKE_ROOM_ID,
|
||||||
|
EventType.CallNegotiate,
|
||||||
|
expect.objectContaining({
|
||||||
|
"version": "1",
|
||||||
|
"call_id": call.callId,
|
||||||
|
"org.matrix.msc3077.sdp_stream_metadata": expect.objectContaining({
|
||||||
|
[SCREENSHARE_STREAM_ID]: expect.objectContaining({
|
||||||
|
purpose: SDPStreamMetadataPurpose.Screenshare,
|
||||||
|
}),
|
||||||
|
}),
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
|
await call.setScreensharingEnabled(false);
|
||||||
|
|
||||||
|
expect(call.feeds.filter(f => f.purpose == SDPStreamMetadataPurpose.Screenshare).length).toEqual(0);
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
@@ -2240,7 +2240,7 @@ export class MatrixCall extends TypedEventEmitter<CallEvent, CallEventHandlerMap
|
|||||||
eventType,
|
eventType,
|
||||||
roomId: this.roomId,
|
roomId: this.roomId,
|
||||||
content: realContent,
|
content: realContent,
|
||||||
userId: this.invitee || this.getOpponentMember().userId,
|
userId: this.invitee || this.getOpponentMember()?.userId,
|
||||||
});
|
});
|
||||||
|
|
||||||
await this.client.sendEvent(this.roomId, eventType, realContent);
|
await this.client.sendEvent(this.roomId, eventType, realContent);
|
||||||
|
Reference in New Issue
Block a user