@webex/plugin-meetings 1.149.2 → 1.151.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/constants.js +14 -4
- package/dist/constants.js.map +1 -1
- package/dist/locus-info/mediaSharesUtils.js +88 -11
- package/dist/locus-info/mediaSharesUtils.js.map +1 -1
- package/dist/meeting/index.js +368 -42
- package/dist/meeting/index.js.map +1 -1
- package/dist/meeting/request.js +10 -4
- package/dist/meeting/request.js.map +1 -1
- package/dist/meeting-info/utilv2.js +3 -1
- package/dist/meeting-info/utilv2.js.map +1 -1
- package/dist/members/index.js +72 -11
- package/dist/members/index.js.map +1 -1
- package/dist/metrics/config.js +6 -0
- package/dist/metrics/config.js.map +1 -1
- package/dist/metrics/index.js +65 -45
- package/dist/metrics/index.js.map +1 -1
- package/dist/peer-connection-manager/index.js +1 -1
- package/dist/peer-connection-manager/index.js.map +1 -1
- package/package.json +6 -5
- package/src/constants.js +11 -2
- package/src/locus-info/mediaSharesUtils.js +84 -12
- package/src/meeting/index.js +350 -29
- package/src/meeting/request.js +10 -4
- package/src/meeting-info/utilv2.js +3 -0
- package/src/members/index.js +80 -11
- package/src/metrics/config.js +6 -0
- package/src/metrics/index.js +28 -17
- package/src/peer-connection-manager/index.js +7 -2
- package/test/integration/spec/journey.js +180 -3
- package/test/integration/spec/space-meeting.js +29 -6
- package/test/unit/spec/meeting/index.js +547 -3
- package/test/unit/spec/metrics/index.js +42 -1
- package/test/utils/testUtils.js +18 -1
- package/test/utils/webex-test-users.js +2 -0
package/src/metrics/config.js
CHANGED
|
@@ -126,6 +126,12 @@ export const eventType = {
|
|
|
126
126
|
// Fired when the client changes its local UI/layout to a content sharing view,
|
|
127
127
|
// because it is expecting to display share media.
|
|
128
128
|
SHARE_LAYOUT_DISPLAYED: 'client.share.layout.displayed',
|
|
129
|
+
// Fired when the user of the client starts a whiteboard share (e.g. click 'Share Live' button).
|
|
130
|
+
WHITEBOARD_SHARE_INITIATED: 'client.whiteboard.share.initiated',
|
|
131
|
+
// Fired when the meeting floor is released for whiteboard share
|
|
132
|
+
WHITEBOARD_SHARE_STOPPED: 'client.whiteboard.share.stopped',
|
|
133
|
+
// When the client receives a successful response from locus indicating that it has the floor for whiteboard sharing.
|
|
134
|
+
WHITEBOARD_SHARE_FLOOR_GRANTED: 'client.whiteboard.share.floor-granted',
|
|
129
135
|
MUTED: 'client.muted',
|
|
130
136
|
UNMUTED: 'client.unmuted',
|
|
131
137
|
LEAVE: 'client.call.leave',
|
package/src/metrics/index.js
CHANGED
|
@@ -6,10 +6,10 @@ import util from 'util';
|
|
|
6
6
|
import {includes} from 'lodash';
|
|
7
7
|
import uuid from 'uuid';
|
|
8
8
|
import window from 'global/window';
|
|
9
|
+
import anonymize from 'ip-anonymize';
|
|
9
10
|
|
|
10
11
|
import LoggerProxy from '../common/logs/logger-proxy';
|
|
11
12
|
import {MEETING_ERRORS} from '../constants';
|
|
12
|
-
import StaticConfig from '../common/config';
|
|
13
13
|
import BrowserDetection from '../common/browser-detection';
|
|
14
14
|
|
|
15
15
|
import {
|
|
@@ -34,21 +34,19 @@ const {
|
|
|
34
34
|
} = BrowserDetection();
|
|
35
35
|
|
|
36
36
|
// Apply a CIDR /28 format to the IP address
|
|
37
|
-
const
|
|
38
|
-
if (!localIp) {
|
|
39
|
-
return undefined;
|
|
40
|
-
}
|
|
41
|
-
const parts = localIp.split('.');
|
|
42
|
-
|
|
43
|
-
// eslint-disable-next-line no-bitwise
|
|
44
|
-
parts[3] &= 240;
|
|
45
|
-
|
|
46
|
-
return parts.join('.');
|
|
47
|
-
};
|
|
37
|
+
const anonymizeIPAddress = (localIp) => anonymize(localIp);
|
|
48
38
|
|
|
49
39
|
const triggerTimers = ({event, meeting, data}) => {
|
|
50
40
|
switch (event) {
|
|
41
|
+
case eventType.CALL_INITIATED:
|
|
42
|
+
meeting.setStartCallInitiateJoinReq();
|
|
43
|
+
break;
|
|
44
|
+
case eventType.LOCUS_JOIN_REQUEST:
|
|
45
|
+
meeting.setEndCallInitiateJoinReq();
|
|
46
|
+
meeting.setStartJoinReqResp();
|
|
47
|
+
break;
|
|
51
48
|
case eventType.LOCUS_JOIN_RESPONSE:
|
|
49
|
+
meeting.setEndJoinReqResp();
|
|
52
50
|
meeting.setStartSetupDelay(mediaType.AUDIO);
|
|
53
51
|
meeting.setStartSetupDelay(mediaType.VIDEO);
|
|
54
52
|
meeting.setStartSendingMediaDelay(mediaType.AUDIO);
|
|
@@ -60,6 +58,12 @@ const triggerTimers = ({event, meeting, data}) => {
|
|
|
60
58
|
case eventType.SENDING_MEDIA_START:
|
|
61
59
|
meeting.setEndSendingMediaDelay(data.mediaType);
|
|
62
60
|
break;
|
|
61
|
+
case eventType.LOCAL_SDP_GENERATED:
|
|
62
|
+
meeting.setStartLocalSDPGenRemoteSDPRecvDelay();
|
|
63
|
+
break;
|
|
64
|
+
case eventType.REMOTE_SDP_RECEIVED:
|
|
65
|
+
meeting.setEndLocalSDPGenRemoteSDPRecvDelay();
|
|
66
|
+
break;
|
|
63
67
|
default:
|
|
64
68
|
break;
|
|
65
69
|
}
|
|
@@ -144,6 +148,7 @@ class Metrics {
|
|
|
144
148
|
|
|
145
149
|
if (!meeting && meetingId) {
|
|
146
150
|
meeting = this.meetingCollection.get(meetingId);
|
|
151
|
+
options.meeting = meeting;
|
|
147
152
|
}
|
|
148
153
|
|
|
149
154
|
if (meeting) {
|
|
@@ -185,7 +190,7 @@ class Metrics {
|
|
|
185
190
|
clientInfo: {
|
|
186
191
|
clientType: options.clientType,
|
|
187
192
|
clientVersion: `${CLIENT_NAME}/${this.webex.version}`,
|
|
188
|
-
localNetworkPrefix:
|
|
193
|
+
localNetworkPrefix: anonymizeIPAddress(this.webex.meetings.geoHintInfo?.clientAddress),
|
|
189
194
|
osVersion: getOSVersion() || 'unknown',
|
|
190
195
|
subClientType: options.subClientType,
|
|
191
196
|
os: this.getOsName(),
|
|
@@ -228,6 +233,9 @@ class Metrics {
|
|
|
228
233
|
if (options.recoveredBy) {
|
|
229
234
|
payload.event.recoveredBy = options.recoveredBy;
|
|
230
235
|
}
|
|
236
|
+
if (options.joinTimes) {
|
|
237
|
+
payload.event.joinTimes = options.joinTimes;
|
|
238
|
+
}
|
|
231
239
|
}
|
|
232
240
|
|
|
233
241
|
return payload;
|
|
@@ -259,7 +267,7 @@ class Metrics {
|
|
|
259
267
|
* @memberof Metrics
|
|
260
268
|
*/
|
|
261
269
|
initMediaPayload(eventType, identifiers, options = {}) {
|
|
262
|
-
const {audioSetupDelay, videoSetupDelay} = options;
|
|
270
|
+
const {audioSetupDelay, videoSetupDelay, joinTimes} = options;
|
|
263
271
|
|
|
264
272
|
const payload = {
|
|
265
273
|
eventId: uuid.v4(),
|
|
@@ -273,7 +281,7 @@ class Metrics {
|
|
|
273
281
|
clientInfo: {
|
|
274
282
|
clientType: options.clientType, // TODO: Only clientType: 'TEAMS_CLIENT' is whitelisted
|
|
275
283
|
clientVersion: `${CLIENT_NAME}/${this.webex.version}`,
|
|
276
|
-
localNetworkPrefix:
|
|
284
|
+
localNetworkPrefix: anonymizeIPAddress(this.webex.meetings.geoHintInfo?.clientAddress),
|
|
277
285
|
os: this.getOsName(),
|
|
278
286
|
osVersion: getOSVersion() || UNKNOWN,
|
|
279
287
|
subClientType: options.subClientType,
|
|
@@ -290,7 +298,10 @@ class Metrics {
|
|
|
290
298
|
canProceed: true,
|
|
291
299
|
identifiers,
|
|
292
300
|
intervals: [options.intervalData],
|
|
293
|
-
|
|
301
|
+
joinTimes,
|
|
302
|
+
eventData: {
|
|
303
|
+
webClientDomain: window.location.hostname
|
|
304
|
+
},
|
|
294
305
|
sourceMetadata: {
|
|
295
306
|
applicationSoftwareType: CLIENT_NAME,
|
|
296
307
|
applicationSoftwareVersion: this.webex.version,
|
|
@@ -455,7 +466,7 @@ class Metrics {
|
|
|
455
466
|
userAgentToString() {
|
|
456
467
|
let userAgentOption;
|
|
457
468
|
let browserInfo;
|
|
458
|
-
const clientInfo = util.format('client=%s', `${
|
|
469
|
+
const clientInfo = util.format('client=%s', `${this.webex.meetings?.metrics?.clientName}`);
|
|
459
470
|
|
|
460
471
|
if (['chrome', 'firefox', 'msie', 'msedge', 'safari'].indexOf(getBrowserName().toLowerCase()) !== -1) {
|
|
461
472
|
browserInfo = util.format('browser=%s', `${getBrowserName().toLowerCase()}/${getBrowserVersion().split('.')[0]}`);
|
|
@@ -288,7 +288,12 @@ pc.addStream = (peerConnection, stream) => {
|
|
|
288
288
|
* @param {String} meetingId
|
|
289
289
|
* @returns {undefined}
|
|
290
290
|
*/
|
|
291
|
-
pc.setRemoteSessionDetails = (
|
|
291
|
+
pc.setRemoteSessionDetails = (
|
|
292
|
+
peerConnection,
|
|
293
|
+
typeStr,
|
|
294
|
+
remoteSdp,
|
|
295
|
+
meetingId,
|
|
296
|
+
) => {
|
|
292
297
|
LoggerProxy.logger.log(`PeerConnectionManager:index#setRemoteSessionDetails --> Setting the remote description type: ${typeStr}State: ${peerConnection.signalingState}`);
|
|
293
298
|
const sdp = remoteSdp;
|
|
294
299
|
|
|
@@ -314,7 +319,7 @@ pc.setRemoteSessionDetails = (peerConnection, typeStr, remoteSdp, meetingId) =>
|
|
|
314
319
|
})
|
|
315
320
|
)
|
|
316
321
|
.then(() => {
|
|
317
|
-
if (
|
|
322
|
+
if (peerConnection.signalingState === SDP.STABLE) {
|
|
318
323
|
Metrics.postEvent({
|
|
319
324
|
event: eventType.REMOTE_SDP_RECEIVED,
|
|
320
325
|
meetingId
|
|
@@ -13,7 +13,7 @@ const webexTestUsers = require('../../utils/webex-test-users');
|
|
|
13
13
|
|
|
14
14
|
const {isBrowser} = BrowserDetection();
|
|
15
15
|
|
|
16
|
-
let userSet, alice, bob, chris, enumerateSpy;
|
|
16
|
+
let userSet, alice, bob, chris, enumerateSpy, channelUrlA, channelUrlB;
|
|
17
17
|
|
|
18
18
|
skipInNode(describe)('plugin-meetings', () => {
|
|
19
19
|
describe('journey', () => {
|
|
@@ -32,6 +32,8 @@ skipInNode(describe)('plugin-meetings', () => {
|
|
|
32
32
|
alice.webex.meetings.name = 'alice';
|
|
33
33
|
bob.webex.meetings.name = 'bob';
|
|
34
34
|
chris.webex.meetings.name = 'chris';
|
|
35
|
+
channelUrlA = 'https://board-a.wbx2.com/board/api/v1/channels/49cfb550-5517-11eb-a2af-1b9e4bc3da13';
|
|
36
|
+
channelUrlB = 'https://board-a.wbx2.com/board/api/v1/channels/977a7330-54f4-11eb-b1ef-91f5eefc7bf3';
|
|
35
37
|
})
|
|
36
38
|
.then(() => Promise.all([testUtils.syncAndEndMeeting(alice),
|
|
37
39
|
testUtils.syncAndEndMeeting(bob)]))
|
|
@@ -162,6 +164,41 @@ skipInNode(describe)('plugin-meetings', () => {
|
|
|
162
164
|
}));
|
|
163
165
|
});
|
|
164
166
|
|
|
167
|
+
// Enabled when config.enableUnifiedMeetings = true
|
|
168
|
+
xdescribe('Conversation URL', () => {
|
|
169
|
+
describe('Successful 1:1 meeting', () => {
|
|
170
|
+
it('Fetch meeting information with a conversation URL for a 1:1 space', async () => {
|
|
171
|
+
assert.equal(Object.keys(bob.webex.meetings.getAllMeetings()), 0);
|
|
172
|
+
assert.equal(Object.keys(chris.webex.meetings.getAllMeetings()), 0);
|
|
173
|
+
|
|
174
|
+
const conversation = await chris.webex.internal.conversation.create({participants: [bob]});
|
|
175
|
+
|
|
176
|
+
await chris.webex.internal.conversation.post(conversation, {displayName: 'hello world how are you '});
|
|
177
|
+
|
|
178
|
+
await Promise.all([
|
|
179
|
+
testUtils.delayedPromise(chris.webex.meetings.create(conversation.url, 'CONVERSATION_URL')),
|
|
180
|
+
testUtils.waitForEvents([{scope: chris.webex.meetings, event: 'meeting:added', user: chris}])
|
|
181
|
+
])
|
|
182
|
+
.then(function chrisJoinsMeeting() {
|
|
183
|
+
return Promise.all([
|
|
184
|
+
testUtils.delayedPromise(chris.meeting.join()),
|
|
185
|
+
testUtils.waitForEvents([{scope: bob.webex.meetings, event: 'meeting:added', user: bob},
|
|
186
|
+
{scope: chris.meeting, event: 'meeting:stateChange', user: chris}])
|
|
187
|
+
.then((response) => {
|
|
188
|
+
assert.equal(response[0].result.payload.currentState, 'ACTIVE');
|
|
189
|
+
})
|
|
190
|
+
]);
|
|
191
|
+
});
|
|
192
|
+
});
|
|
193
|
+
|
|
194
|
+
it('Fetch meeting information with invalid conversation URL and throws error', () => {
|
|
195
|
+
chris.webex.meetings.meetingInfo.fetchMeetingInfo('http://some-invalid.com', 'CONVERSATION_URL').then((response) => {
|
|
196
|
+
assert(response.result === '404');
|
|
197
|
+
});
|
|
198
|
+
});
|
|
199
|
+
});
|
|
200
|
+
});
|
|
201
|
+
|
|
165
202
|
describe('Successful 1:1 meeting (including Guest)', function () {
|
|
166
203
|
before(() => {
|
|
167
204
|
// Workaround since getDisplayMedia requires a user gesture to be activated, and this is a integration tests
|
|
@@ -482,7 +519,10 @@ skipInNode(describe)('plugin-meetings', () => {
|
|
|
482
519
|
.then((response) => {
|
|
483
520
|
assert.equal(response[0].result.memberId, alice.meeting.selfId);
|
|
484
521
|
}),
|
|
485
|
-
testUtils.waitForEvents([{scope: bob.meeting.members, event: 'members:update'}])
|
|
522
|
+
testUtils.waitForEvents([{scope: bob.meeting.members, event: 'members:update'}])
|
|
523
|
+
.then((response) => {
|
|
524
|
+
console.log('SCREEN SHARE RESPONSE ', JSON.stringify(response, testUtils.getCircularReplacer()));
|
|
525
|
+
}),
|
|
486
526
|
testUtils.waitForEvents([{scope: alice.meeting, event: 'media:ready'}])
|
|
487
527
|
.then((response) => {
|
|
488
528
|
console.log('MEDIA:READY event ', response[0].result);
|
|
@@ -512,7 +552,7 @@ skipInNode(describe)('plugin-meetings', () => {
|
|
|
512
552
|
}),
|
|
513
553
|
testUtils.waitForEvents([{scope: alice.meeting.members, event: 'members:update'}])
|
|
514
554
|
.then((response) => {
|
|
515
|
-
console.log('SCREEN SHARE RESPONSE ', JSON.stringify(response));
|
|
555
|
+
console.log('SCREEN SHARE RESPONSE ', JSON.stringify(response, testUtils.getCircularReplacer()));
|
|
516
556
|
}),
|
|
517
557
|
testUtils.waitForEvents([{scope: bob.meeting, event: 'media:ready'}])
|
|
518
558
|
.then((response) => {
|
|
@@ -550,6 +590,143 @@ skipInNode(describe)('plugin-meetings', () => {
|
|
|
550
590
|
assert.equal(alice.meeting.shareStatus, 'no_share');
|
|
551
591
|
}));
|
|
552
592
|
|
|
593
|
+
it('alice shares whiteboard A', () => Promise.all([
|
|
594
|
+
testUtils.delayedPromise(alice.meeting.startWhiteboardShare(channelUrlA)),
|
|
595
|
+
testUtils.waitForEvents([
|
|
596
|
+
{scope: alice.meeting, event: 'meeting:startedSharingWhiteboard'}
|
|
597
|
+
]),
|
|
598
|
+
testUtils.waitForEvents([{scope: bob.meeting, event: 'meeting:startedSharingWhiteboard'}])
|
|
599
|
+
.then((response) => {
|
|
600
|
+
const {memberId, resourceUrl} = response[0].result;
|
|
601
|
+
|
|
602
|
+
assert.equal(memberId, alice.meeting.selfId);
|
|
603
|
+
assert.equal(resourceUrl, channelUrlA);
|
|
604
|
+
}),
|
|
605
|
+
testUtils.waitForEvents([{scope: bob.meeting.members, event: 'members:update'}])
|
|
606
|
+
.then((response) => {
|
|
607
|
+
console.log('WHITEBOARD SHARE RESPONSE ', JSON.stringify(response, testUtils.getCircularReplacer()));
|
|
608
|
+
})
|
|
609
|
+
])
|
|
610
|
+
.then(() => {
|
|
611
|
+
assert.equal(alice.meeting.isSharing, false);
|
|
612
|
+
assert.equal(alice.meeting.shareStatus, 'whiteboard_share_active');
|
|
613
|
+
assert.equal(bob.meeting.shareStatus, 'whiteboard_share_active');
|
|
614
|
+
}));
|
|
615
|
+
|
|
616
|
+
it('bob steals share from alice with whiteboard B', () => Promise.all([
|
|
617
|
+
testUtils.delayedPromise(bob.meeting.startWhiteboardShare(channelUrlB)),
|
|
618
|
+
testUtils.waitForEvents([
|
|
619
|
+
{scope: bob.meeting, event: 'meeting:startedSharingWhiteboard'}
|
|
620
|
+
]),
|
|
621
|
+
testUtils.waitForEvents([{scope: alice.meeting, event: 'meeting:startedSharingWhiteboard'}])
|
|
622
|
+
.then((response) => {
|
|
623
|
+
const {memberId, resourceUrl} = response[0].result;
|
|
624
|
+
|
|
625
|
+
assert.equal(memberId, bob.meeting.selfId);
|
|
626
|
+
assert.equal(resourceUrl, channelUrlB);
|
|
627
|
+
}),
|
|
628
|
+
testUtils.waitForEvents([{scope: alice.meeting.members, event: 'members:update'}])
|
|
629
|
+
.then((response) => {
|
|
630
|
+
console.log('WHITEBOARD SHARE RESPONSE ', JSON.stringify(response, testUtils.getCircularReplacer()));
|
|
631
|
+
})
|
|
632
|
+
])
|
|
633
|
+
.then(() => {
|
|
634
|
+
assert.equal(bob.meeting.isSharing, false);
|
|
635
|
+
assert.equal(alice.meeting.shareStatus, 'whiteboard_share_active');
|
|
636
|
+
assert.equal(bob.meeting.shareStatus, 'whiteboard_share_active');
|
|
637
|
+
}));
|
|
638
|
+
|
|
639
|
+
it('bob stops sharing ', () => Promise.all([
|
|
640
|
+
// Wait for peerConnection to stabalize
|
|
641
|
+
testUtils.waitUntil(20000),
|
|
642
|
+
testUtils.delayedPromise(bob.meeting.stopWhiteboardShare(channelUrlB)),
|
|
643
|
+
testUtils.waitForEvents([{scope: bob.meeting, event: 'meeting:stoppedSharingWhiteboard'}]),
|
|
644
|
+
testUtils.waitForEvents([{scope: alice.meeting, event: 'meeting:stoppedSharingWhiteboard'}])
|
|
645
|
+
])
|
|
646
|
+
.then(() => {
|
|
647
|
+
assert.equal(bob.meeting.isSharing, false);
|
|
648
|
+
assert.equal(bob.meeting.shareStatus, 'no_share');
|
|
649
|
+
assert.equal(alice.meeting.shareStatus, 'no_share');
|
|
650
|
+
}));
|
|
651
|
+
|
|
652
|
+
it('alice shares whiteboard B', () => Promise.all([
|
|
653
|
+
testUtils.delayedPromise(alice.meeting.startWhiteboardShare(channelUrlB)),
|
|
654
|
+
testUtils.waitForEvents([
|
|
655
|
+
{scope: alice.meeting, event: 'meeting:startedSharingWhiteboard'}
|
|
656
|
+
]),
|
|
657
|
+
testUtils.waitForEvents([{scope: bob.meeting, event: 'meeting:startedSharingWhiteboard'}])
|
|
658
|
+
.then((response) => {
|
|
659
|
+
const {memberId, resourceUrl} = response[0].result;
|
|
660
|
+
|
|
661
|
+
assert.equal(memberId, alice.meeting.selfId);
|
|
662
|
+
assert.equal(resourceUrl, channelUrlB);
|
|
663
|
+
}),
|
|
664
|
+
testUtils.waitForEvents([{scope: bob.meeting.members, event: 'members:update'}])
|
|
665
|
+
.then((response) => {
|
|
666
|
+
console.log('WHITEBOARD SHARE RESPONSE ', JSON.stringify(response, testUtils.getCircularReplacer()));
|
|
667
|
+
})
|
|
668
|
+
])
|
|
669
|
+
.then(() => {
|
|
670
|
+
assert.equal(alice.meeting.isSharing, false);
|
|
671
|
+
assert.equal(alice.meeting.shareStatus, 'whiteboard_share_active');
|
|
672
|
+
assert.equal(bob.meeting.shareStatus, 'whiteboard_share_active');
|
|
673
|
+
}));
|
|
674
|
+
|
|
675
|
+
it('bob steals the share from alice with desktop share', () => Promise.all([
|
|
676
|
+
testUtils.delayedPromise(bob.meeting.shareScreen()),
|
|
677
|
+
testUtils.waitForEvents([{scope: alice.meeting, event: 'meeting:stoppedSharingWhiteboard'}]),
|
|
678
|
+
testUtils.waitForEvents([{scope: bob.meeting, event: 'meeting:startedSharingLocal'}]),
|
|
679
|
+
testUtils.waitForEvents([{scope: alice.meeting, event: 'meeting:startedSharingRemote'}])
|
|
680
|
+
.then((response) => {
|
|
681
|
+
assert.equal(response[0].result.memberId, bob.meeting.selfId);
|
|
682
|
+
}),
|
|
683
|
+
testUtils.waitForEvents([{scope: alice.meeting.members, event: 'members:update'}])
|
|
684
|
+
.then((response) => {
|
|
685
|
+
console.log('SCREEN SHARE RESPONSE ', JSON.stringify(response, testUtils.getCircularReplacer()));
|
|
686
|
+
}),
|
|
687
|
+
testUtils.waitForEvents([{scope: bob.meeting, event: 'media:ready'}])
|
|
688
|
+
.then((response) => {
|
|
689
|
+
console.log('MEDIA:READY event ', response[0].result);
|
|
690
|
+
assert.equal(response[0].result.type === 'localShare', true);
|
|
691
|
+
})
|
|
692
|
+
])
|
|
693
|
+
.then(() => {
|
|
694
|
+
const heightResolution = DEFAULT_RESOLUTIONS.meetings.screenResolution.idealHeight;
|
|
695
|
+
|
|
696
|
+
// TODO: Re-eanable Safari when screensharing issues have been resolved
|
|
697
|
+
if (!isBrowser('safari')) {
|
|
698
|
+
assert.equal(bob.meeting.mediaProperties.shareTrack.getConstraints().height, heightResolution);
|
|
699
|
+
}
|
|
700
|
+
assert.equal(bob.meeting.isSharing, true);
|
|
701
|
+
assert.equal(bob.meeting.shareStatus, 'local_share_active');
|
|
702
|
+
assert.equal(alice.meeting.shareStatus, 'remote_share_active');
|
|
703
|
+
|
|
704
|
+
return testUtils.waitUntil(10000);
|
|
705
|
+
}));
|
|
706
|
+
|
|
707
|
+
it('bob shares whiteboard B', () => Promise.all([
|
|
708
|
+
testUtils.delayedPromise(bob.meeting.startWhiteboardShare(channelUrlB)),
|
|
709
|
+
testUtils.waitForEvents([
|
|
710
|
+
{scope: bob.meeting, event: 'meeting:startedSharingWhiteboard'}
|
|
711
|
+
]),
|
|
712
|
+
testUtils.waitForEvents([{scope: alice.meeting, event: 'meeting:startedSharingWhiteboard'}])
|
|
713
|
+
.then((response) => {
|
|
714
|
+
const {memberId, resourceUrl} = response[0].result;
|
|
715
|
+
|
|
716
|
+
assert.equal(memberId, bob.meeting.selfId);
|
|
717
|
+
assert.equal(resourceUrl, channelUrlB);
|
|
718
|
+
}),
|
|
719
|
+
testUtils.waitForEvents([{scope: alice.meeting.members, event: 'members:update'}])
|
|
720
|
+
.then((response) => {
|
|
721
|
+
console.log('WHITEBOARD SHARE RESPONSE ', JSON.stringify(response, testUtils.getCircularReplacer()));
|
|
722
|
+
})
|
|
723
|
+
])
|
|
724
|
+
.then(() => {
|
|
725
|
+
assert.equal(bob.meeting.isSharing, false);
|
|
726
|
+
assert.equal(alice.meeting.shareStatus, 'whiteboard_share_active');
|
|
727
|
+
assert.equal(bob.meeting.shareStatus, 'whiteboard_share_active');
|
|
728
|
+
}));
|
|
729
|
+
|
|
553
730
|
it('alice adds chris as guest to 1:1 meeting', () => Promise.all([
|
|
554
731
|
testUtils.delayedPromise(alice.meeting.invite({emailAddress: chris.emailAddress})),
|
|
555
732
|
testUtils.waitForEvents([{scope: chris.webex.meetings, event: 'meeting:added', user: chris}]),
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
|
|
2
2
|
import {assert} from '@webex/test-helper-chai';
|
|
3
3
|
import {skipInNode, jenkinsOnly} from '@webex/test-helper-mocha';
|
|
4
|
+
import {patterns} from '@webex/common';
|
|
5
|
+
import MeetingInfoUtil from '@webex/plugin-meetings/src/meeting-info/utilv2';
|
|
4
6
|
|
|
5
7
|
import CMR from '../../utils/cmr';
|
|
6
8
|
import testUtils from '../../utils/testUtils';
|
|
@@ -63,18 +65,39 @@ skipInNode(describe)('plugin-meetings', () => {
|
|
|
63
65
|
testUtils.delayedPromise(alice.meeting.join()),
|
|
64
66
|
testUtils.waitForEvents([
|
|
65
67
|
{scope: bob.webex.meetings, event: 'meeting:added', user: bob},
|
|
66
|
-
{scope: chris.webex.meetings, event: 'meeting:added', user: chris}
|
|
67
|
-
|
|
68
|
+
{scope: chris.webex.meetings, event: 'meeting:added', user: chris}
|
|
69
|
+
])
|
|
70
|
+
]).then(() => {
|
|
71
|
+
const {meetingNumber} = bob.meeting.meetingInfo;
|
|
72
|
+
|
|
73
|
+
assert(meetingNumber === alice.meeting.meetingNumber, 'meetingNumber matches alice meeting number');
|
|
74
|
+
})));
|
|
75
|
+
|
|
76
|
+
xit('Should fetch user info using user hydra id with the new api', () => alice.webex.rooms.create({title: 'sample'})
|
|
77
|
+
.then((room) => MeetingInfoUtil.getDestinationType({
|
|
78
|
+
destination: room.creatorId,
|
|
79
|
+
webex: alice.webex
|
|
80
|
+
}))
|
|
81
|
+
.then((destinationType) => MeetingInfoUtil.getRequestBody(destinationType))
|
|
82
|
+
.then((res) => {
|
|
83
|
+
assert.exists(res.sipUrl, 'sipURL didnt exist');
|
|
84
|
+
assert.match(res.sipUrl, patterns.email); // assert sipURL is email
|
|
85
|
+
}));
|
|
68
86
|
|
|
69
87
|
// Enable this test when we are going to enable the unified space meeeting .
|
|
70
88
|
// We cannot change the config on load as the meetingInfo function loads dynamically
|
|
71
|
-
xit('Should fetch meeting
|
|
72
|
-
alice.webex.meetings.config.experimental.enableUnifiedMeetings = true;
|
|
89
|
+
xit('Should fetch meeting info using space url with the new api', async () => {
|
|
73
90
|
const res = await alice.webex.meetings.meetingInfo.fetchMeetingInfo(space.url, 'CONVERSATION_URL');
|
|
74
91
|
|
|
75
|
-
assert.exists(res.meetingNumber);
|
|
92
|
+
assert.exists(res.body.meetingNumber);
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
xit('Bob fetches meeting info with SIP URI before joining', async () => {
|
|
96
|
+
const {sipUri} = alice.meeting;
|
|
97
|
+
const res = await bob.webex.meetings.meetingInfo.fetchMeetingInfo(sipUri, 'SIP_URI');
|
|
98
|
+
const {meetingNumber} = res.body;
|
|
76
99
|
|
|
77
|
-
alice.
|
|
100
|
+
assert(meetingNumber === alice.meeting.meetingNumber, 'meetingNumber matches alice meeting number');
|
|
78
101
|
});
|
|
79
102
|
|
|
80
103
|
it('Bob and chris joins space meeting', () => testUtils.waitForStateChange(alice.meeting, 'JOINED')
|