@webex/internal-plugin-metrics 3.8.1 → 3.9.0
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/call-diagnostic/call-diagnostic-metrics-latencies.js +92 -14
- package/dist/call-diagnostic/call-diagnostic-metrics-latencies.js.map +1 -1
- package/dist/call-diagnostic/call-diagnostic-metrics.js +348 -48
- package/dist/call-diagnostic/call-diagnostic-metrics.js.map +1 -1
- package/dist/call-diagnostic/call-diagnostic-metrics.util.js +21 -0
- package/dist/call-diagnostic/call-diagnostic-metrics.util.js.map +1 -1
- package/dist/call-diagnostic/config.js +3 -1
- package/dist/call-diagnostic/config.js.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/metrics.js +1 -1
- package/dist/metrics.types.js.map +1 -1
- package/dist/new-metrics.js +43 -1
- package/dist/new-metrics.js.map +1 -1
- package/dist/types/call-diagnostic/call-diagnostic-metrics-latencies.d.ts +23 -1
- package/dist/types/call-diagnostic/call-diagnostic-metrics.d.ts +176 -10
- package/dist/types/call-diagnostic/config.d.ts +2 -0
- package/dist/types/index.d.ts +2 -2
- package/dist/types/metrics.types.d.ts +18 -7
- package/dist/types/new-metrics.d.ts +19 -2
- package/package.json +11 -12
- package/src/call-diagnostic/call-diagnostic-metrics-latencies.ts +104 -14
- package/src/call-diagnostic/call-diagnostic-metrics.ts +363 -25
- package/src/call-diagnostic/call-diagnostic-metrics.util.ts +20 -0
- package/src/call-diagnostic/config.ts +3 -0
- package/src/index.ts +2 -0
- package/src/metrics.types.ts +25 -6
- package/src/new-metrics.ts +52 -1
- package/test/unit/spec/call-diagnostic/call-diagnostic-metrics-batcher.ts +20 -1
- package/test/unit/spec/call-diagnostic/call-diagnostic-metrics-latencies.ts +255 -0
- package/test/unit/spec/call-diagnostic/call-diagnostic-metrics.ts +829 -39
- package/test/unit/spec/call-diagnostic/call-diagnostic-metrics.util.ts +6 -0
- package/test/unit/spec/new-metrics.ts +67 -2
- package/test/unit/spec/prelogin-metrics-batcher.ts +72 -3
- package/dist/call-diagnostic-events-batcher.js +0 -60
- package/dist/call-diagnostic-events-batcher.js.map +0 -1
|
@@ -239,6 +239,20 @@ export const prepareDiagnosticMetricItem = (webex: any, item: any) => {
|
|
|
239
239
|
|
|
240
240
|
// Set upgradeChannel to 'gold' if buildType is 'prod', otherwise to the buildType value
|
|
241
241
|
const upgradeChannel = buildType === 'prod' ? 'gold' : buildType;
|
|
242
|
+
if (webex.devicemanager) {
|
|
243
|
+
const pairedDevice = webex.devicemanager.getPairedDevice();
|
|
244
|
+
if (pairedDevice) {
|
|
245
|
+
const devicePayload = {
|
|
246
|
+
deviceId: pairedDevice.deviceInfo?.id,
|
|
247
|
+
devicePairingType: webex.devicemanager.getPairedMethod(),
|
|
248
|
+
deviceURL: pairedDevice.url,
|
|
249
|
+
isPersonalDevice: pairedDevice.mode === 'personal',
|
|
250
|
+
productName: pairedDevice.devices[0]?.productName,
|
|
251
|
+
};
|
|
252
|
+
item.eventPayload.event.pairingState = 'paired';
|
|
253
|
+
item.eventPayload.event.pairedDevice = devicePayload;
|
|
254
|
+
}
|
|
255
|
+
}
|
|
242
256
|
|
|
243
257
|
const origin: Partial<Event['origin']> = {
|
|
244
258
|
buildType,
|
|
@@ -257,6 +271,7 @@ export const prepareDiagnosticMetricItem = (webex: any, item: any) => {
|
|
|
257
271
|
switch (eventName) {
|
|
258
272
|
case 'client.webexapp.launched':
|
|
259
273
|
joinTimes.downloadTime = cdl.getDownloadTimeJMT();
|
|
274
|
+
joinTimes.pageJmt = cdl.getPageJMT();
|
|
260
275
|
break;
|
|
261
276
|
case 'client.login.end':
|
|
262
277
|
joinTimes.otherAppApiReqResp = cdl.getOtherAppApiReqResp();
|
|
@@ -267,6 +282,7 @@ export const prepareDiagnosticMetricItem = (webex: any, item: any) => {
|
|
|
267
282
|
joinTimes.clickToInterstitial = cdl.getClickToInterstitial();
|
|
268
283
|
joinTimes.refreshCaptchaServiceReqResp = cdl.getRefreshCaptchaReqResp();
|
|
269
284
|
joinTimes.downloadIntelligenceModelsReqResp = cdl.getDownloadIntelligenceModelsReqResp();
|
|
285
|
+
joinTimes.clickToInterstitialWithUserDelay = cdl.getClickToInterstitialWithUserDelay();
|
|
270
286
|
break;
|
|
271
287
|
|
|
272
288
|
case 'client.call.initiated':
|
|
@@ -287,6 +303,8 @@ export const prepareDiagnosticMetricItem = (webex: any, item: any) => {
|
|
|
287
303
|
joinTimes.totalJmt = cdl.getTotalJMT();
|
|
288
304
|
joinTimes.clientJmt = cdl.getClientJMT();
|
|
289
305
|
joinTimes.downloadTime = cdl.getDownloadTimeJMT();
|
|
306
|
+
joinTimes.clickToInterstitialWithUserDelay = cdl.getClickToInterstitialWithUserDelay();
|
|
307
|
+
joinTimes.totalJMTWithUserDelay = cdl.getTotalJMTWithUserDelay();
|
|
290
308
|
break;
|
|
291
309
|
|
|
292
310
|
case 'client.ice.end':
|
|
@@ -307,6 +325,8 @@ export const prepareDiagnosticMetricItem = (webex: any, item: any) => {
|
|
|
307
325
|
joinTimes.interstitialToMediaOKJMT = cdl.getInterstitialToMediaOKJMT();
|
|
308
326
|
joinTimes.callInitMediaEngineReady = cdl.getCallInitMediaEngineReady();
|
|
309
327
|
joinTimes.stayLobbyTime = cdl.getStayLobbyTime();
|
|
328
|
+
joinTimes.totalMediaJMTWithUserDelay = cdl.getTotalMediaJMTWithUserDelay();
|
|
329
|
+
joinTimes.totalJMTWithUserDelay = cdl.getTotalJMTWithUserDelay();
|
|
310
330
|
break;
|
|
311
331
|
|
|
312
332
|
case 'client.media.tx.start':
|
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
import {ClientEventError, ClientSubServiceType} from '../metrics.types';
|
|
6
6
|
|
|
7
7
|
export const CALL_DIAGNOSTIC_LOG_IDENTIFIER = 'call-diagnostic-events -> ';
|
|
8
|
+
export const CALL_FEATURE_LOG_IDENTIFIER = 'call-diagnostic-events-feature -> ';
|
|
8
9
|
|
|
9
10
|
export const AUTHENTICATION_FAILED_CODE = 1010;
|
|
10
11
|
export const NETWORK_ERROR = 1026;
|
|
@@ -738,3 +739,5 @@ export const CLIENT_ERROR_CODE_TO_ERROR_PAYLOAD: Record<number, Partial<ClientEv
|
|
|
738
739
|
};
|
|
739
740
|
|
|
740
741
|
export const CALL_DIAGNOSTIC_EVENT_FAILED_TO_SEND = 'js_sdk_call_diagnostic_event_failed_to_send';
|
|
742
|
+
|
|
743
|
+
export const CALL_FEATURE_EVENT_FAILED_TO_SEND = 'js_sdk_call_feature_event_failed_to_send';
|
package/src/index.ts
CHANGED
|
@@ -18,6 +18,7 @@ import {
|
|
|
18
18
|
SubmitBusinessEvent,
|
|
19
19
|
SubmitMQE,
|
|
20
20
|
PreComputedLatencies,
|
|
21
|
+
SubmitFeatureEvent,
|
|
21
22
|
} from './metrics.types';
|
|
22
23
|
import * as CALL_DIAGNOSTIC_CONFIG from './call-diagnostic/config';
|
|
23
24
|
import * as CallDiagnosticUtils from './call-diagnostic/call-diagnostic-metrics.util';
|
|
@@ -61,4 +62,5 @@ export type {
|
|
|
61
62
|
SubmitOperationalEvent,
|
|
62
63
|
SubmitBusinessEvent,
|
|
63
64
|
PreComputedLatencies,
|
|
65
|
+
SubmitFeatureEvent,
|
|
64
66
|
};
|
package/src/metrics.types.ts
CHANGED
|
@@ -2,9 +2,12 @@ import {
|
|
|
2
2
|
ClientEvent as RawClientEvent,
|
|
3
3
|
Event as RawEvent,
|
|
4
4
|
MediaQualityEvent as RawMediaQualityEvent,
|
|
5
|
+
FeatureEvent as RawFeatureEvent,
|
|
5
6
|
} from '@webex/event-dictionary-ts';
|
|
6
7
|
|
|
7
|
-
export type Event = Omit<RawEvent, 'event'> & {
|
|
8
|
+
export type Event = Omit<RawEvent, 'event'> & {
|
|
9
|
+
event: RawClientEvent | RawMediaQualityEvent | RawFeatureEvent;
|
|
10
|
+
};
|
|
8
11
|
|
|
9
12
|
export type ClientEventError = NonNullable<RawClientEvent['errors']>[0];
|
|
10
13
|
|
|
@@ -157,7 +160,9 @@ export type InternalEvent = {
|
|
|
157
160
|
| 'internal.client.meeting.interstitial-window.showed'
|
|
158
161
|
| 'internal.client.interstitial-window.click.joinbutton'
|
|
159
162
|
| 'internal.client.add-media.turn-discovery.start'
|
|
160
|
-
| 'internal.client.add-media.turn-discovery.end'
|
|
163
|
+
| 'internal.client.add-media.turn-discovery.end'
|
|
164
|
+
| 'internal.client.share.initiated'
|
|
165
|
+
| 'internal.client.share.stopped';
|
|
161
166
|
|
|
162
167
|
payload?: never;
|
|
163
168
|
options?: never;
|
|
@@ -212,10 +217,9 @@ export type BehavioralEvent = TaggedEvent;
|
|
|
212
217
|
export type OperationalEvent = TaggedEvent;
|
|
213
218
|
|
|
214
219
|
export interface FeatureEvent {
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
options?: never;
|
|
220
|
+
name: RawFeatureEvent['name'];
|
|
221
|
+
payload?: RawFeatureEvent;
|
|
222
|
+
options?: SubmitClientEventOptions;
|
|
219
223
|
}
|
|
220
224
|
|
|
221
225
|
export interface MediaQualityEvent {
|
|
@@ -251,6 +255,8 @@ export type ClientEventPayload = RecursivePartial<ClientEvent['payload']>;
|
|
|
251
255
|
export type ClientEventLeaveReason = ClientEvent['payload']['leaveReason'];
|
|
252
256
|
export type ClientEventPayloadError = ClientEvent['payload']['errors'];
|
|
253
257
|
|
|
258
|
+
export type ClientFeatureEventPayload = RecursivePartial<FeatureEvent['payload']>;
|
|
259
|
+
|
|
254
260
|
export type MediaQualityEventAudioSetupDelayPayload = NonNullable<
|
|
255
261
|
MediaQualityEvent['payload']
|
|
256
262
|
>['audioSetupDelay'];
|
|
@@ -311,6 +317,7 @@ export type PreComputedLatencies =
|
|
|
311
317
|
| 'internal.download.time'
|
|
312
318
|
| 'internal.get.cluster.time'
|
|
313
319
|
| 'internal.click.to.interstitial'
|
|
320
|
+
| 'internal.click.to.interstitial.with.user.delay'
|
|
314
321
|
| 'internal.refresh.captcha.time'
|
|
315
322
|
| 'internal.exchange.ci.token.time'
|
|
316
323
|
| 'internal.get.u2c.time'
|
|
@@ -339,3 +346,15 @@ export interface DelayedClientEvent {
|
|
|
339
346
|
payload?: RecursivePartial<ClientEvent['payload']>;
|
|
340
347
|
options?: SubmitClientEventOptions;
|
|
341
348
|
}
|
|
349
|
+
|
|
350
|
+
export type SubmitFeatureEvent = (args: {
|
|
351
|
+
name: FeatureEvent['name'];
|
|
352
|
+
payload?: RecursivePartial<FeatureEvent['payload']>;
|
|
353
|
+
options?: SubmitClientEventOptions;
|
|
354
|
+
}) => Promise<any>;
|
|
355
|
+
|
|
356
|
+
export interface DelayedClientFeatureEvent {
|
|
357
|
+
name: FeatureEvent['name'];
|
|
358
|
+
payload?: RecursivePartial<FeatureEvent['payload']>;
|
|
359
|
+
options?: SubmitClientEventOptions;
|
|
360
|
+
}
|
package/src/new-metrics.ts
CHANGED
|
@@ -23,6 +23,7 @@ import {
|
|
|
23
23
|
SubmitClientEventOptions,
|
|
24
24
|
Table,
|
|
25
25
|
DelayedClientEvent,
|
|
26
|
+
DelayedClientFeatureEvent,
|
|
26
27
|
} from './metrics.types';
|
|
27
28
|
import CallDiagnosticLatencies from './call-diagnostic/call-diagnostic-metrics-latencies';
|
|
28
29
|
import {setMetricTimings} from './call-diagnostic/call-diagnostic-metrics.util';
|
|
@@ -51,11 +52,18 @@ class Metrics extends WebexPlugin {
|
|
|
51
52
|
*/
|
|
52
53
|
delaySubmitClientEvents = false;
|
|
53
54
|
|
|
55
|
+
/**
|
|
56
|
+
* Whether or not to delay the submission of feature events.
|
|
57
|
+
*/
|
|
58
|
+
delaySubmitClientFeatureEvents = false;
|
|
59
|
+
|
|
54
60
|
/**
|
|
55
61
|
* Overrides for delayed client events. E.g. if you want to override the correlationId for all delayed client events, you can set this to { correlationId: 'newCorrelationId' }
|
|
56
62
|
*/
|
|
57
63
|
delayedClientEventsOverrides: Partial<DelayedClientEvent['options']> = {};
|
|
58
64
|
|
|
65
|
+
delayedClientFeatureEventsOverrides: Partial<DelayedClientFeatureEvent['options']> = {};
|
|
66
|
+
|
|
59
67
|
/**
|
|
60
68
|
* Constructor
|
|
61
69
|
* @param args
|
|
@@ -275,7 +283,25 @@ class Metrics extends WebexPlugin {
|
|
|
275
283
|
payload?: RecursivePartial<FeatureEvent['payload']>;
|
|
276
284
|
options: any;
|
|
277
285
|
}) {
|
|
278
|
-
|
|
286
|
+
if (!this.callDiagnosticLatencies || !this.callDiagnosticMetrics) {
|
|
287
|
+
// @ts-ignore
|
|
288
|
+
this.webex.logger.log(
|
|
289
|
+
`NewMetrics: @submitFeatureEvent. Attempted to submit before webex.ready. Event name: ${name}`
|
|
290
|
+
);
|
|
291
|
+
|
|
292
|
+
return Promise.resolve();
|
|
293
|
+
}
|
|
294
|
+
this.callDiagnosticLatencies.saveTimestamp({
|
|
295
|
+
key: name,
|
|
296
|
+
options: {meetingId: options?.meetingId},
|
|
297
|
+
});
|
|
298
|
+
|
|
299
|
+
return this.callDiagnosticMetrics.submitFeatureEvent({
|
|
300
|
+
name,
|
|
301
|
+
payload,
|
|
302
|
+
options,
|
|
303
|
+
delaySubmitEvent: this.delaySubmitClientFeatureEvents,
|
|
304
|
+
});
|
|
279
305
|
}
|
|
280
306
|
|
|
281
307
|
/**
|
|
@@ -432,6 +458,31 @@ class Metrics extends WebexPlugin {
|
|
|
432
458
|
|
|
433
459
|
return Promise.resolve();
|
|
434
460
|
}
|
|
461
|
+
|
|
462
|
+
/**
|
|
463
|
+
* Sets the value of setDelaySubmitClientFeatureEvents.
|
|
464
|
+
* If set to true, feature events will be delayed until submitDelayedClientFeatureEvents is called.
|
|
465
|
+
* If set to false, delayed feature events will be submitted.
|
|
466
|
+
*
|
|
467
|
+
* @param {object} options - {shouldDelay: A boolean value indicating whether to delay the submission of feature events,
|
|
468
|
+
* overrides: An object containing overrides for the feature events}
|
|
469
|
+
*/
|
|
470
|
+
public setDelaySubmitClientFeatureEvents({
|
|
471
|
+
shouldDelay,
|
|
472
|
+
overrides,
|
|
473
|
+
}: {
|
|
474
|
+
shouldDelay: boolean;
|
|
475
|
+
overrides?: Partial<DelayedClientFeatureEvent['options']>;
|
|
476
|
+
}) {
|
|
477
|
+
this.delaySubmitClientFeatureEvents = shouldDelay;
|
|
478
|
+
this.delayedClientFeatureEventsOverrides = overrides || {};
|
|
479
|
+
|
|
480
|
+
if (this.isReady && !shouldDelay) {
|
|
481
|
+
return this.callDiagnosticMetrics.submitDelayedClientFeatureEvents(overrides);
|
|
482
|
+
}
|
|
483
|
+
|
|
484
|
+
return Promise.resolve();
|
|
485
|
+
}
|
|
435
486
|
}
|
|
436
487
|
|
|
437
488
|
export default Metrics;
|
|
@@ -108,6 +108,8 @@ describe('plugin-metrics', () => {
|
|
|
108
108
|
.returns(10);
|
|
109
109
|
webex.internal.newMetrics.callDiagnosticLatencies.getDownloadIntelligenceModelsReqResp =
|
|
110
110
|
sinon.stub().returns(42);
|
|
111
|
+
webex.internal.newMetrics.callDiagnosticLatencies.getClickToInterstitialWithUserDelay =
|
|
112
|
+
sinon.stub().returns(12);
|
|
111
113
|
|
|
112
114
|
const promise = webex.internal.newMetrics.callDiagnosticMetrics.submitToCallDiagnostics(
|
|
113
115
|
//@ts-ignore
|
|
@@ -127,6 +129,7 @@ describe('plugin-metrics', () => {
|
|
|
127
129
|
meetingInfoReqResp: 10,
|
|
128
130
|
refreshCaptchaServiceReqResp: 10,
|
|
129
131
|
downloadIntelligenceModelsReqResp: 42,
|
|
132
|
+
clickToInterstitialWithUserDelay: 12,
|
|
130
133
|
},
|
|
131
134
|
});
|
|
132
135
|
assert.lengthOf(
|
|
@@ -183,9 +186,15 @@ describe('plugin-metrics', () => {
|
|
|
183
186
|
webex.internal.newMetrics.callDiagnosticLatencies.getCallInitJoinReq = sinon
|
|
184
187
|
.stub()
|
|
185
188
|
.returns(10);
|
|
186
|
-
|
|
189
|
+
webex.internal.newMetrics.callDiagnosticLatencies.getDownloadTimeJMT = sinon
|
|
187
190
|
.stub()
|
|
188
191
|
.returns(100);
|
|
192
|
+
webex.internal.newMetrics.callDiagnosticLatencies.getClickToInterstitialWithUserDelay = sinon
|
|
193
|
+
.stub()
|
|
194
|
+
.returns(43);
|
|
195
|
+
webex.internal.newMetrics.callDiagnosticLatencies.getTotalJMTWithUserDelay = sinon
|
|
196
|
+
.stub()
|
|
197
|
+
.returns(64);
|
|
189
198
|
const promise = webex.internal.newMetrics.callDiagnosticMetrics.submitToCallDiagnostics(
|
|
190
199
|
//@ts-ignore
|
|
191
200
|
{event: {name: 'client.locus.join.response'}}
|
|
@@ -209,6 +218,8 @@ describe('plugin-metrics', () => {
|
|
|
209
218
|
totalJmt: 20,
|
|
210
219
|
clientJmt: 5,
|
|
211
220
|
downloadTime: 100,
|
|
221
|
+
clickToInterstitialWithUserDelay: 43,
|
|
222
|
+
totalJMTWithUserDelay: 64,
|
|
212
223
|
},
|
|
213
224
|
});
|
|
214
225
|
assert.lengthOf(
|
|
@@ -338,6 +349,12 @@ describe('plugin-metrics', () => {
|
|
|
338
349
|
webex.internal.newMetrics.callDiagnosticLatencies.getStayLobbyTime = sinon
|
|
339
350
|
.stub()
|
|
340
351
|
.returns(1);
|
|
352
|
+
webex.internal.newMetrics.callDiagnosticLatencies.getTotalMediaJMTWithUserDelay = sinon
|
|
353
|
+
.stub()
|
|
354
|
+
.returns(43);
|
|
355
|
+
webex.internal.newMetrics.callDiagnosticLatencies.getTotalJMTWithUserDelay = sinon
|
|
356
|
+
.stub()
|
|
357
|
+
.returns(64);
|
|
341
358
|
const promise = webex.internal.newMetrics.callDiagnosticMetrics.submitToCallDiagnostics(
|
|
342
359
|
//@ts-ignore
|
|
343
360
|
{event: {name: 'client.media-engine.ready'}}
|
|
@@ -356,6 +373,8 @@ describe('plugin-metrics', () => {
|
|
|
356
373
|
interstitialToMediaOKJMT: 22,
|
|
357
374
|
callInitMediaEngineReady: 10,
|
|
358
375
|
stayLobbyTime: 1,
|
|
376
|
+
totalMediaJMTWithUserDelay: 43,
|
|
377
|
+
totalJMTWithUserDelay: 64,
|
|
359
378
|
},
|
|
360
379
|
});
|
|
361
380
|
assert.lengthOf(
|
|
@@ -130,6 +130,82 @@ describe('internal-plugin-metrics', () => {
|
|
|
130
130
|
assert.deepEqual(res2, undefined);
|
|
131
131
|
});
|
|
132
132
|
|
|
133
|
+
describe('getDiffBetweenTimestamps with clamping', () => {
|
|
134
|
+
it('should return diff without clamping when no clampValues provided', () => {
|
|
135
|
+
cdl.saveTimestamp({key: 'client.alert.displayed', value: 10});
|
|
136
|
+
cdl.saveTimestamp({key: 'client.alert.removed', value: 50});
|
|
137
|
+
const res = cdl.getDiffBetweenTimestamps('client.alert.displayed', 'client.alert.removed');
|
|
138
|
+
assert.deepEqual(res, 40);
|
|
139
|
+
});
|
|
140
|
+
|
|
141
|
+
it('should return diff without clamping when value is within range', () => {
|
|
142
|
+
cdl.saveTimestamp({key: 'client.alert.displayed', value: 10});
|
|
143
|
+
cdl.saveTimestamp({key: 'client.alert.removed', value: 50});
|
|
144
|
+
const res = cdl.getDiffBetweenTimestamps('client.alert.displayed', 'client.alert.removed', {
|
|
145
|
+
minimum: 0,
|
|
146
|
+
maximum: 100
|
|
147
|
+
});
|
|
148
|
+
assert.deepEqual(res, 40);
|
|
149
|
+
});
|
|
150
|
+
|
|
151
|
+
it('should clamp to minimum when diff is below minimum', () => {
|
|
152
|
+
cdl.saveTimestamp({key: 'client.alert.displayed', value: 50});
|
|
153
|
+
cdl.saveTimestamp({key: 'client.alert.removed', value: 45});
|
|
154
|
+
const res = cdl.getDiffBetweenTimestamps('client.alert.displayed', 'client.alert.removed', {
|
|
155
|
+
minimum: 10,
|
|
156
|
+
maximum: 100
|
|
157
|
+
});
|
|
158
|
+
assert.deepEqual(res, 10);
|
|
159
|
+
});
|
|
160
|
+
|
|
161
|
+
it('should clamp to maximum when diff is above maximum', () => {
|
|
162
|
+
cdl.saveTimestamp({key: 'client.alert.displayed', value: 10});
|
|
163
|
+
cdl.saveTimestamp({key: 'client.alert.removed', value: 210});
|
|
164
|
+
const res = cdl.getDiffBetweenTimestamps('client.alert.displayed', 'client.alert.removed', {
|
|
165
|
+
minimum: 0,
|
|
166
|
+
maximum: 100
|
|
167
|
+
});
|
|
168
|
+
assert.deepEqual(res, 100);
|
|
169
|
+
});
|
|
170
|
+
|
|
171
|
+
it('should use default minimum of 0 when only maximum is specified', () => {
|
|
172
|
+
cdl.saveTimestamp({key: 'client.alert.displayed', value: 50});
|
|
173
|
+
cdl.saveTimestamp({key: 'client.alert.removed', value: 45});
|
|
174
|
+
const res = cdl.getDiffBetweenTimestamps('client.alert.displayed', 'client.alert.removed', {
|
|
175
|
+
maximum: 100
|
|
176
|
+
});
|
|
177
|
+
assert.deepEqual(res, 0);
|
|
178
|
+
});
|
|
179
|
+
|
|
180
|
+
it('should not clamp maximum when maximum is undefined', () => {
|
|
181
|
+
cdl.saveTimestamp({key: 'client.alert.displayed', value: 10});
|
|
182
|
+
cdl.saveTimestamp({key: 'client.alert.removed', value: 2000});
|
|
183
|
+
const res = cdl.getDiffBetweenTimestamps('client.alert.displayed', 'client.alert.removed', {
|
|
184
|
+
minimum: 5
|
|
185
|
+
});
|
|
186
|
+
assert.deepEqual(res, 1990);
|
|
187
|
+
});
|
|
188
|
+
|
|
189
|
+
it('should handle negative differences correctly with clamping', () => {
|
|
190
|
+
cdl.saveTimestamp({key: 'client.alert.displayed', value: 100});
|
|
191
|
+
cdl.saveTimestamp({key: 'client.alert.removed', value: 50});
|
|
192
|
+
const res = cdl.getDiffBetweenTimestamps('client.alert.displayed', 'client.alert.removed', {
|
|
193
|
+
minimum: 10,
|
|
194
|
+
maximum: 1000
|
|
195
|
+
});
|
|
196
|
+
assert.deepEqual(res, 10);
|
|
197
|
+
});
|
|
198
|
+
|
|
199
|
+
it('should return undefined when timestamps are missing even with clamping', () => {
|
|
200
|
+
cdl.saveTimestamp({key: 'client.alert.displayed', value: 10});
|
|
201
|
+
const res = cdl.getDiffBetweenTimestamps('client.alert.displayed', 'client.alert.removed', {
|
|
202
|
+
minimum: 0,
|
|
203
|
+
maximum: 100
|
|
204
|
+
});
|
|
205
|
+
assert.deepEqual(res, undefined);
|
|
206
|
+
});
|
|
207
|
+
});
|
|
208
|
+
|
|
133
209
|
it('calculates getMeetingInfoReqResp correctly', () => {
|
|
134
210
|
cdl.saveTimestamp({key: 'internal.client.meetinginfo.request', value: 10});
|
|
135
211
|
cdl.saveTimestamp({key: 'internal.client.meetinginfo.response', value: 20});
|
|
@@ -446,6 +522,36 @@ describe('internal-plugin-metrics', () => {
|
|
|
446
522
|
assert.deepEqual(cdl.getClickToInterstitial(), 0);
|
|
447
523
|
});
|
|
448
524
|
|
|
525
|
+
it('calculates getClickToInterstitialWithUserDelay correctly', () => {
|
|
526
|
+
cdl.saveTimestamp({
|
|
527
|
+
key: 'internal.client.meeting.click.joinbutton',
|
|
528
|
+
value: 10,
|
|
529
|
+
});
|
|
530
|
+
cdl.saveTimestamp({
|
|
531
|
+
key: 'internal.client.meeting.interstitial-window.showed',
|
|
532
|
+
value: 20,
|
|
533
|
+
});
|
|
534
|
+
assert.deepEqual(cdl.getClickToInterstitialWithUserDelay(), 10);
|
|
535
|
+
});
|
|
536
|
+
|
|
537
|
+
it('calculates getClickToInterstitialWithUserDelay without join button timestamp', () => {
|
|
538
|
+
cdl.saveLatency('internal.click.to.interstitial.with.user.delay', 5);
|
|
539
|
+
cdl.saveTimestamp({
|
|
540
|
+
key: 'internal.client.meeting.interstitial-window.showed',
|
|
541
|
+
value: 20,
|
|
542
|
+
});
|
|
543
|
+
assert.deepEqual(cdl.getClickToInterstitialWithUserDelay(), 5);
|
|
544
|
+
});
|
|
545
|
+
|
|
546
|
+
it('calculates getClickToInterstitialWithUserDelay without join button timestamp when it is 0', () => {
|
|
547
|
+
cdl.saveLatency('internal.click.to.interstitial.with.user.delay', 0);
|
|
548
|
+
cdl.saveTimestamp({
|
|
549
|
+
key: 'internal.client.meeting.interstitial-window.showed',
|
|
550
|
+
value: 20,
|
|
551
|
+
});
|
|
552
|
+
assert.deepEqual(cdl.getClickToInterstitialWithUserDelay(), 0);
|
|
553
|
+
});
|
|
554
|
+
|
|
449
555
|
it('calculates getInterstitialToJoinOK correctly', () => {
|
|
450
556
|
cdl.saveTimestamp({
|
|
451
557
|
key: 'internal.client.interstitial-window.click.joinbutton',
|
|
@@ -554,6 +660,78 @@ describe('internal-plugin-metrics', () => {
|
|
|
554
660
|
assert.deepEqual(cdl.getTotalJMT(), undefined);
|
|
555
661
|
});
|
|
556
662
|
|
|
663
|
+
it('calculates getTotalJMTWithUserDelay correctly', () => {
|
|
664
|
+
cdl.saveTimestamp({
|
|
665
|
+
key: 'internal.client.interstitial-window.click.joinbutton',
|
|
666
|
+
value: 5,
|
|
667
|
+
});
|
|
668
|
+
cdl.saveTimestamp({
|
|
669
|
+
key: 'internal.client.meeting.click.joinbutton',
|
|
670
|
+
value: 10,
|
|
671
|
+
});
|
|
672
|
+
cdl.saveTimestamp({
|
|
673
|
+
key: 'internal.client.meeting.interstitial-window.showed',
|
|
674
|
+
value: 20,
|
|
675
|
+
});
|
|
676
|
+
cdl.saveTimestamp({
|
|
677
|
+
key: 'client.locus.join.response',
|
|
678
|
+
value: 40,
|
|
679
|
+
});
|
|
680
|
+
assert.deepEqual(cdl.getTotalJMTWithUserDelay(), 45);
|
|
681
|
+
});
|
|
682
|
+
|
|
683
|
+
it('calculates getTotalJMTWithUserDelay correctly when clickToInterstitialWithUserDelay is 0', () => {
|
|
684
|
+
cdl.saveLatency('internal.click.to.interstitial.with.user.delay', 0);
|
|
685
|
+
cdl.saveTimestamp({
|
|
686
|
+
key: 'internal.client.interstitial-window.click.joinbutton',
|
|
687
|
+
value: 20,
|
|
688
|
+
});
|
|
689
|
+
cdl.saveTimestamp({
|
|
690
|
+
key: 'client.locus.join.response',
|
|
691
|
+
value: 40,
|
|
692
|
+
});
|
|
693
|
+
assert.deepEqual(cdl.getTotalJMTWithUserDelay(), 20);
|
|
694
|
+
});
|
|
695
|
+
|
|
696
|
+
it('calculates getTotalJMTWithUserDelay correctly when interstitialToJoinOk is 0', () => {
|
|
697
|
+
cdl.saveTimestamp({
|
|
698
|
+
key: 'internal.client.interstitial-window.click.joinbutton',
|
|
699
|
+
value: 40,
|
|
700
|
+
});
|
|
701
|
+
cdl.saveLatency('internal.click.to.interstitial.with.user.delay', 12);
|
|
702
|
+
cdl.saveTimestamp({
|
|
703
|
+
key: 'client.locus.join.response',
|
|
704
|
+
value: 40,
|
|
705
|
+
});
|
|
706
|
+
assert.deepEqual(cdl.getTotalJMTWithUserDelay(), 12);
|
|
707
|
+
});
|
|
708
|
+
|
|
709
|
+
it('calculates getTotalJMTWithUserDelay correctly when both clickToInterstitialWithUserDelay and interstitialToJoinOk are 0', () => {
|
|
710
|
+
cdl.saveTimestamp({
|
|
711
|
+
key: 'internal.client.interstitial-window.click.joinbutton',
|
|
712
|
+
value: 40,
|
|
713
|
+
});
|
|
714
|
+
cdl.saveLatency('internal.click.to.interstitial.with.user.delay', 0);
|
|
715
|
+
cdl.saveTimestamp({
|
|
716
|
+
key: 'client.locus.join.response',
|
|
717
|
+
value: 40,
|
|
718
|
+
});
|
|
719
|
+
assert.deepEqual(cdl.getTotalJMTWithUserDelay(), 0);
|
|
720
|
+
});
|
|
721
|
+
|
|
722
|
+
it('calculates getTotalJMTWithUserDelay correctly when both clickToInterstitialWithUserDelay is not a number', () => {
|
|
723
|
+
cdl.saveTimestamp({
|
|
724
|
+
key: 'internal.client.interstitial-window.click.joinbutton',
|
|
725
|
+
value: 40,
|
|
726
|
+
});
|
|
727
|
+
cdl.saveLatency('internal.click.to.interstitial.with.user.delay', 'eleven' as unknown as number);
|
|
728
|
+
cdl.saveTimestamp({
|
|
729
|
+
key: 'client.locus.join.response',
|
|
730
|
+
value: 40,
|
|
731
|
+
});
|
|
732
|
+
assert.deepEqual(cdl.getTotalJMTWithUserDelay(), undefined);
|
|
733
|
+
});
|
|
734
|
+
|
|
557
735
|
it('calculates getTotalMediaJMT correctly', () => {
|
|
558
736
|
cdl.saveTimestamp({
|
|
559
737
|
key: 'internal.client.meeting.click.joinbutton',
|
|
@@ -627,6 +805,71 @@ describe('internal-plugin-metrics', () => {
|
|
|
627
805
|
assert.deepEqual(cdl.getTotalMediaJMT(), 31);
|
|
628
806
|
});
|
|
629
807
|
|
|
808
|
+
it('calculates getTotalMediaJMTWithUserDelay correctly', () => {
|
|
809
|
+
cdl.saveLatency('internal.click.to.interstitial.with.user.delay', 7);
|
|
810
|
+
cdl.saveTimestamp({
|
|
811
|
+
key: 'internal.client.interstitial-window.click.joinbutton',
|
|
812
|
+
value: 10,
|
|
813
|
+
});
|
|
814
|
+
cdl.saveTimestamp({
|
|
815
|
+
key: 'client.locus.join.request',
|
|
816
|
+
value: 12,
|
|
817
|
+
});
|
|
818
|
+
cdl.saveTimestamp({
|
|
819
|
+
key: 'client.locus.join.response',
|
|
820
|
+
value: 20,
|
|
821
|
+
});
|
|
822
|
+
cdl.saveTimestamp({
|
|
823
|
+
key: 'internal.host.meeting.participant.admitted',
|
|
824
|
+
value: 24,
|
|
825
|
+
});
|
|
826
|
+
cdl.saveTimestamp({
|
|
827
|
+
key: 'client.ice.start',
|
|
828
|
+
value: 30,
|
|
829
|
+
});
|
|
830
|
+
cdl.saveTimestamp({
|
|
831
|
+
key: 'client.ice.end',
|
|
832
|
+
value: 40,
|
|
833
|
+
});
|
|
834
|
+
assert.deepEqual(cdl.getTotalMediaJMTWithUserDelay(), 35);
|
|
835
|
+
});
|
|
836
|
+
|
|
837
|
+
it('calculates getTotalMediaJMTWithUserDelay correctly for guest join', () => {
|
|
838
|
+
cdl.saveTimestamp({
|
|
839
|
+
key: 'internal.client.meeting.click.joinbutton',
|
|
840
|
+
value: 5,
|
|
841
|
+
});
|
|
842
|
+
cdl.saveTimestamp({
|
|
843
|
+
key: 'internal.client.meeting.interstitial-window.showed',
|
|
844
|
+
value: 8,
|
|
845
|
+
});
|
|
846
|
+
cdl.saveTimestamp({
|
|
847
|
+
key: 'internal.client.interstitial-window.click.joinbutton',
|
|
848
|
+
value: 10,
|
|
849
|
+
});
|
|
850
|
+
cdl.saveTimestamp({
|
|
851
|
+
key: 'client.locus.join.request',
|
|
852
|
+
value: 12,
|
|
853
|
+
});
|
|
854
|
+
cdl.saveTimestamp({
|
|
855
|
+
key: 'client.locus.join.response',
|
|
856
|
+
value: 20,
|
|
857
|
+
});
|
|
858
|
+
cdl.saveTimestamp({
|
|
859
|
+
key: 'internal.host.meeting.participant.admitted',
|
|
860
|
+
value: 24,
|
|
861
|
+
});
|
|
862
|
+
cdl.saveTimestamp({
|
|
863
|
+
key: 'client.ice.start',
|
|
864
|
+
value: 30,
|
|
865
|
+
});
|
|
866
|
+
cdl.saveTimestamp({
|
|
867
|
+
key: 'client.ice.end',
|
|
868
|
+
value: 40,
|
|
869
|
+
});
|
|
870
|
+
assert.deepEqual(cdl.getTotalMediaJMTWithUserDelay(), 31);
|
|
871
|
+
});
|
|
872
|
+
|
|
630
873
|
it('calculates getJoinConfJMT correctly', () => {
|
|
631
874
|
cdl.saveTimestamp({
|
|
632
875
|
key: 'client.locus.join.request',
|
|
@@ -751,6 +994,18 @@ describe('internal-plugin-metrics', () => {
|
|
|
751
994
|
assert.deepEqual(cdl.getInterstitialToMediaOKJMT(), 10);
|
|
752
995
|
});
|
|
753
996
|
|
|
997
|
+
it('calculates getShareDuration correctly', () => {
|
|
998
|
+
cdl.saveTimestamp({
|
|
999
|
+
key: 'internal.client.share.initiated',
|
|
1000
|
+
value: 5,
|
|
1001
|
+
});
|
|
1002
|
+
cdl.saveTimestamp({
|
|
1003
|
+
key: 'internal.client.share.stopped',
|
|
1004
|
+
value: 7,
|
|
1005
|
+
});
|
|
1006
|
+
assert.deepEqual(cdl.getShareDuration(), 2);
|
|
1007
|
+
});
|
|
1008
|
+
|
|
754
1009
|
describe('calculates getU2CTime correctly', () => {
|
|
755
1010
|
it('returns undefined when no precomputed value available', () => {
|
|
756
1011
|
assert.deepEqual(cdl.getU2CTime(), undefined);
|