@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.
Files changed (35) hide show
  1. package/dist/call-diagnostic/call-diagnostic-metrics-latencies.js +92 -14
  2. package/dist/call-diagnostic/call-diagnostic-metrics-latencies.js.map +1 -1
  3. package/dist/call-diagnostic/call-diagnostic-metrics.js +348 -48
  4. package/dist/call-diagnostic/call-diagnostic-metrics.js.map +1 -1
  5. package/dist/call-diagnostic/call-diagnostic-metrics.util.js +21 -0
  6. package/dist/call-diagnostic/call-diagnostic-metrics.util.js.map +1 -1
  7. package/dist/call-diagnostic/config.js +3 -1
  8. package/dist/call-diagnostic/config.js.map +1 -1
  9. package/dist/index.js.map +1 -1
  10. package/dist/metrics.js +1 -1
  11. package/dist/metrics.types.js.map +1 -1
  12. package/dist/new-metrics.js +43 -1
  13. package/dist/new-metrics.js.map +1 -1
  14. package/dist/types/call-diagnostic/call-diagnostic-metrics-latencies.d.ts +23 -1
  15. package/dist/types/call-diagnostic/call-diagnostic-metrics.d.ts +176 -10
  16. package/dist/types/call-diagnostic/config.d.ts +2 -0
  17. package/dist/types/index.d.ts +2 -2
  18. package/dist/types/metrics.types.d.ts +18 -7
  19. package/dist/types/new-metrics.d.ts +19 -2
  20. package/package.json +11 -12
  21. package/src/call-diagnostic/call-diagnostic-metrics-latencies.ts +104 -14
  22. package/src/call-diagnostic/call-diagnostic-metrics.ts +363 -25
  23. package/src/call-diagnostic/call-diagnostic-metrics.util.ts +20 -0
  24. package/src/call-diagnostic/config.ts +3 -0
  25. package/src/index.ts +2 -0
  26. package/src/metrics.types.ts +25 -6
  27. package/src/new-metrics.ts +52 -1
  28. package/test/unit/spec/call-diagnostic/call-diagnostic-metrics-batcher.ts +20 -1
  29. package/test/unit/spec/call-diagnostic/call-diagnostic-metrics-latencies.ts +255 -0
  30. package/test/unit/spec/call-diagnostic/call-diagnostic-metrics.ts +829 -39
  31. package/test/unit/spec/call-diagnostic/call-diagnostic-metrics.util.ts +6 -0
  32. package/test/unit/spec/new-metrics.ts +67 -2
  33. package/test/unit/spec/prelogin-metrics-batcher.ts +72 -3
  34. package/dist/call-diagnostic-events-batcher.js +0 -60
  35. package/dist/call-diagnostic-events-batcher.js.map +0 -1
@@ -327,6 +327,7 @@ describe('internal-plugin-metrics', () => {
327
327
  {
328
328
  joinTimes: {
329
329
  downloadTime: undefined,
330
+ pageJmt: undefined,
330
331
  },
331
332
  },
332
333
  ],
@@ -338,6 +339,7 @@ describe('internal-plugin-metrics', () => {
338
339
  meetingInfoReqResp: undefined,
339
340
  refreshCaptchaServiceReqResp: undefined,
340
341
  downloadIntelligenceModelsReqResp: undefined,
342
+ clickToInterstitialWithUserDelay: undefined,
341
343
  },
342
344
  },
343
345
  ],
@@ -366,6 +368,8 @@ describe('internal-plugin-metrics', () => {
366
368
  totalJmt: undefined,
367
369
  clientJmt: undefined,
368
370
  downloadTime: undefined,
371
+ clickToInterstitialWithUserDelay: undefined,
372
+ totalJMTWithUserDelay: undefined,
369
373
  },
370
374
  },
371
375
  ],
@@ -402,6 +406,8 @@ describe('internal-plugin-metrics', () => {
402
406
  interstitialToMediaOKJMT: undefined,
403
407
  callInitMediaEngineReady: undefined,
404
408
  stayLobbyTime: undefined,
409
+ totalMediaJMTWithUserDelay: undefined,
410
+ totalJMTWithUserDelay: undefined,
405
411
  },
406
412
  },
407
413
  ],
@@ -19,7 +19,7 @@ describe('internal-plugin-metrics', () => {
19
19
  }
20
20
  });
21
21
 
22
- describe('check submitClientEvent when webex is not ready', () => {
22
+ describe('check submitClientEvent, submitFeatureEvent when webex is not ready', () => {
23
23
  let webex;
24
24
  //@ts-ignore
25
25
  webex = mockWebex();
@@ -36,6 +36,30 @@ describe('internal-plugin-metrics', () => {
36
36
  'NewMetrics: @submitClientEvent. Attempted to submit before webex.ready. Event name: client.alert.displayed'
37
37
  );
38
38
  });
39
+
40
+ it('checks the log', () => {
41
+ webex.internal.newMetrics.submitFeatureEvent({
42
+ name: 'client.feature.meeting.summary',
43
+ options: {
44
+ meetingId: '123',
45
+ },
46
+ payload: {
47
+ meetingSummaryInfo: {
48
+ featureName: 'syncSystemMuteStatus',
49
+ featureActions: [{
50
+ actionName: 'syncMeetingMicUnmuteStatusToSystem',
51
+ actionId: '14200',
52
+ isInitialValue: false,
53
+ clickCount: '1'
54
+ }]
55
+ },
56
+ },
57
+ });
58
+ assert.calledWith(
59
+ webex.logger.log,
60
+ 'NewMetrics: @submitFeatureEvent. Attempted to submit before webex.ready. Event name: client.feature.meeting.summary'
61
+ );
62
+ });
39
63
  });
40
64
 
41
65
  describe('new-metrics contstructor', () => {
@@ -65,6 +89,7 @@ describe('internal-plugin-metrics', () => {
65
89
  webex.internal.newMetrics.callDiagnosticMetrics.buildClientEventFetchRequestOptions =
66
90
  sinon.stub();
67
91
  webex.setTimingsAndFetch = sinon.stub();
92
+ webex.internal.newMetrics.callDiagnosticMetrics.submitFeatureEvent = sinon.stub();
68
93
  });
69
94
 
70
95
  afterEach(() => {
@@ -104,7 +129,7 @@ describe('internal-plugin-metrics', () => {
104
129
  metadata: { foo: 'bar' },
105
130
  });
106
131
  });
107
-
132
+
108
133
  it('submits Client Event successfully', () => {
109
134
  webex.internal.newMetrics.submitClientEvent({
110
135
  name: 'client.alert.displayed',
@@ -125,6 +150,46 @@ describe('internal-plugin-metrics', () => {
125
150
  });
126
151
  });
127
152
 
153
+ it('submits feature Event successfully', () => {
154
+ webex.internal.newMetrics.submitFeatureEvent({
155
+ name: 'client.feature.meeting.summary',
156
+ options: {
157
+ meetingId: '123',
158
+ },
159
+ payload: {
160
+ meetingSummaryInfo: {
161
+ featureName: 'syncSystemMuteStatus',
162
+ featureActions: [{
163
+ actionName: 'syncMeetingMicUnmuteStatusToSystem',
164
+ actionId: '14200',
165
+ isInitialValue: false,
166
+ clickCount: '1'
167
+ }]
168
+ },
169
+ },
170
+ });
171
+
172
+ assert.calledWith(webex.internal.newMetrics.callDiagnosticLatencies.saveTimestamp, {
173
+ key: 'client.feature.meeting.summary',
174
+ options: {meetingId: '123'},
175
+ });
176
+ assert.calledWith(webex.internal.newMetrics.callDiagnosticMetrics.submitFeatureEvent, {
177
+ name: 'client.feature.meeting.summary',
178
+ payload: {
179
+ meetingSummaryInfo: {
180
+ featureName: 'syncSystemMuteStatus',
181
+ featureActions: [{
182
+ actionName: 'syncMeetingMicUnmuteStatusToSystem',
183
+ actionId: '14200',
184
+ isInitialValue: false,
185
+ clickCount: '1'
186
+ }]
187
+ },
188
+ },
189
+ options: {meetingId: '123'},
190
+ delaySubmitEvent: false,
191
+ });
192
+ });
128
193
 
129
194
  it('submits MQE successfully', () => {
130
195
  webex.internal.newMetrics.submitMQE({
@@ -17,7 +17,7 @@ describe('internal-plugin-metrics', () => {
17
17
  let webex;
18
18
  let clock;
19
19
  let now;
20
-
20
+ const deviceManagerStub = {getPairedDevice: sinon.stub()};
21
21
  const preLoginId = 'my_prelogin_id';
22
22
 
23
23
  beforeEach(() => {
@@ -30,6 +30,7 @@ describe('internal-plugin-metrics', () => {
30
30
  newMetrics: NewMetrics,
31
31
  },
32
32
  });
33
+ webex.devicemanager = deviceManagerStub;
33
34
 
34
35
  webex.request = (options) =>
35
36
  Promise.resolve({body: {items: []}, waitForServiceTimeout: 15, options});
@@ -76,6 +77,7 @@ describe('internal-plugin-metrics', () => {
76
77
  clickToInterstitial: undefined,
77
78
  refreshCaptchaServiceReqResp: undefined,
78
79
  downloadIntelligenceModelsReqResp: undefined,
80
+ clickToInterstitialWithUserDelay: undefined,
79
81
  },
80
82
  name: 'client.interstitial-window.launched',
81
83
  },
@@ -216,9 +218,7 @@ describe('internal-plugin-metrics', () => {
216
218
  });
217
219
 
218
220
  assert.deepEqual(calls.args[0].type, ['diagnostic-event']);
219
-
220
221
  const prepareDiagnosticMetricItemCalls = prepareDiagnosticMetricItemSpy.getCalls();
221
-
222
222
  // second argument (item) also gets assigned a delay property but the key is a Symbol and haven't been able to test that..
223
223
  assert.deepEqual(prepareDiagnosticMetricItemCalls[0].args[0], webex);
224
224
  assert.deepEqual(prepareDiagnosticMetricItemCalls[0].args[1].eventPayload, {
@@ -231,6 +231,75 @@ describe('internal-plugin-metrics', () => {
231
231
  });
232
232
  assert.deepEqual(prepareDiagnosticMetricItemCalls[0].args[1].type, ['diagnostic-event']);
233
233
  });
234
+ it('adds the paired device to the metric payload if paired', async () => {
235
+ webex.internal.newMetrics.callDiagnosticMetrics.preLoginMetricsBatcher.prepareRequest = (
236
+ q
237
+ ) => Promise.resolve(q);
238
+ webex.devicemanager.getPairedDevice = sinon.stub().returns({
239
+ deviceInfo: {
240
+ id: 'my_device_id',
241
+ },
242
+ url: 'my_url',
243
+ mode: 'personal',
244
+ devices: [{productName: 'my_product_name'}],
245
+ });
246
+ webex.devicemanager.getPairedMethod = sinon.stub().returns("Manual");
247
+
248
+ const prepareItemSpy = sinon.spy(
249
+ webex.internal.newMetrics.callDiagnosticMetrics.preLoginMetricsBatcher,
250
+ 'prepareItem'
251
+ );
252
+ const prepareDiagnosticMetricItemSpy = sinon.spy(
253
+ CallDiagnosticUtils,
254
+ 'prepareDiagnosticMetricItem'
255
+ );
256
+
257
+ const promise =
258
+ webex.internal.newMetrics.callDiagnosticMetrics.submitToCallDiagnosticsPreLogin(
259
+ {
260
+ event: {name: 'client.interstitial-window.launched'},
261
+ },
262
+ preLoginId
263
+ );
264
+
265
+ await flushPromises();
266
+
267
+ clock.tick(config.metrics.batcherWait);
268
+
269
+ await promise;
270
+
271
+ const calls = prepareItemSpy.getCalls()[0];
272
+
273
+ assert.deepEqual(calls.args[0].eventPayload, {
274
+ event: {
275
+ joinTimes: {
276
+ meetingInfoReqResp: undefined,
277
+ clickToInterstitial: undefined,
278
+ clickToInterstitialWithUserDelay: undefined,
279
+ refreshCaptchaServiceReqResp: undefined,
280
+ downloadIntelligenceModelsReqResp: undefined,
281
+ },
282
+ name: 'client.interstitial-window.launched',
283
+ pairedDevice: {
284
+ deviceId: 'my_device_id',
285
+ deviceURL: 'my_url',
286
+ devicePairingType: 'Manual',
287
+ productName: 'my_product_name',
288
+ isPersonalDevice: true,
289
+ },
290
+ pairingState: 'paired',
291
+ },
292
+ origin: {
293
+ buildType: 'test',
294
+ networkType: 'unknown',
295
+ upgradeChannel: 'test',
296
+ },
297
+ });
298
+
299
+ assert.deepEqual(calls.args[0].type, ['diagnostic-event']);
300
+ assert.calledOnce(webex.devicemanager.getPairedDevice);
301
+
302
+ });
234
303
  });
235
304
 
236
305
  describe('savePreLoginId', () => {
@@ -1,60 +0,0 @@
1
- "use strict";
2
-
3
- var _Object$defineProperty = require("@babel/runtime-corejs2/core-js/object/define-property");
4
- var _interopRequireDefault = require("@babel/runtime-corejs2/helpers/interopRequireDefault");
5
- _Object$defineProperty(exports, "__esModule", {
6
- value: true
7
- });
8
- exports.default = void 0;
9
- var _assign = _interopRequireDefault(require("@babel/runtime-corejs2/core-js/object/assign"));
10
- var _promise = _interopRequireDefault(require("@babel/runtime-corejs2/core-js/promise"));
11
- var _batcher = _interopRequireDefault(require("./batcher"));
12
- /*!
13
- * Copyright (c) 2015-2020 Cisco Systems, Inc. See LICENSE file.
14
- */
15
-
16
- var CallDiagnosticEventsBatcher = _batcher.default.extend({
17
- namespace: 'Metrics',
18
- /**
19
- * @param {string} webClientDomain
20
- * @returns {string}
21
- */
22
- getBuildType: function getBuildType(webClientDomain) {
23
- if (webClientDomain !== null && webClientDomain !== void 0 && webClientDomain.includes('teams.webex.com') || webClientDomain !== null && webClientDomain !== void 0 && webClientDomain.includes('localhost') || webClientDomain !== null && webClientDomain !== void 0 && webClientDomain.includes('127.0.0.1') || process.env.NODE_ENV !== 'production') {
24
- return 'test';
25
- }
26
- return process.env.NODE_ENV === 'production' ? 'prod' : 'test';
27
- },
28
- prepareItem: function prepareItem(item) {
29
- var _item$event, _item$event$eventData;
30
- // networkType should be a enum value: `wifi`, `ethernet`, `cellular`, or `unknown`.
31
- // Browsers cannot provide such information right now. However, it is a required field.
32
- var origin = {
33
- buildType: this.getBuildType((_item$event = item.event) === null || _item$event === void 0 ? void 0 : (_item$event$eventData = _item$event.eventData) === null || _item$event$eventData === void 0 ? void 0 : _item$event$eventData.webClientDomain),
34
- networkType: 'unknown'
35
- };
36
- item.eventPayload.origin = (0, _assign.default)(origin, item.eventPayload.origin);
37
- return _promise.default.resolve(item);
38
- },
39
- prepareRequest: function prepareRequest(queue) {
40
- // Add sent timestamp
41
- queue.forEach(function (item) {
42
- item.eventPayload.originTime = item.eventPayload.originTime || {};
43
- item.eventPayload.originTime.sent = new Date().toISOString();
44
- });
45
- return _promise.default.resolve(queue);
46
- },
47
- submitHttpRequest: function submitHttpRequest(payload) {
48
- return this.webex.request({
49
- method: 'POST',
50
- service: 'metrics',
51
- resource: 'clientmetrics',
52
- body: {
53
- metrics: payload
54
- }
55
- });
56
- }
57
- });
58
- var _default = CallDiagnosticEventsBatcher;
59
- exports.default = _default;
60
- //# sourceMappingURL=call-diagnostic-events-batcher.js.map
@@ -1 +0,0 @@
1
- {"version":3,"names":["_batcher","_interopRequireDefault","require","CallDiagnosticEventsBatcher","Batcher","extend","namespace","getBuildType","webClientDomain","includes","process","env","NODE_ENV","prepareItem","item","_item$event","_item$event$eventData","origin","buildType","event","eventData","networkType","eventPayload","_assign","default","_promise","resolve","prepareRequest","queue","forEach","originTime","sent","Date","toISOString","submitHttpRequest","payload","webex","request","method","service","resource","body","metrics","_default","exports"],"sources":["call-diagnostic-events-batcher.js"],"sourcesContent":["/*!\n * Copyright (c) 2015-2020 Cisco Systems, Inc. See LICENSE file.\n */\n\nimport Batcher from './batcher';\n\nconst CallDiagnosticEventsBatcher = Batcher.extend({\n namespace: 'Metrics',\n\n /**\n * @param {string} webClientDomain\n * @returns {string}\n */\n getBuildType(webClientDomain) {\n if (\n webClientDomain?.includes('teams.webex.com') ||\n webClientDomain?.includes('localhost') ||\n webClientDomain?.includes('127.0.0.1') ||\n process.env.NODE_ENV !== 'production'\n ) {\n return 'test';\n }\n\n return process.env.NODE_ENV === 'production' ? 'prod' : 'test';\n },\n\n prepareItem(item) {\n // networkType should be a enum value: `wifi`, `ethernet`, `cellular`, or `unknown`.\n // Browsers cannot provide such information right now. However, it is a required field.\n const origin = {\n buildType: this.getBuildType(item.event?.eventData?.webClientDomain),\n networkType: 'unknown',\n };\n\n item.eventPayload.origin = Object.assign(origin, item.eventPayload.origin);\n\n return Promise.resolve(item);\n },\n\n prepareRequest(queue) {\n // Add sent timestamp\n queue.forEach((item) => {\n item.eventPayload.originTime = item.eventPayload.originTime || {};\n item.eventPayload.originTime.sent = new Date().toISOString();\n });\n\n return Promise.resolve(queue);\n },\n\n submitHttpRequest(payload) {\n return this.webex.request({\n method: 'POST',\n service: 'metrics',\n resource: 'clientmetrics',\n body: {\n metrics: payload,\n },\n });\n },\n});\n\nexport default CallDiagnosticEventsBatcher;\n"],"mappings":";;;;;;;;;;AAIA,IAAAA,QAAA,GAAAC,sBAAA,CAAAC,OAAA;AAJA;AACA;AACA;;AAIA,IAAMC,2BAA2B,GAAGC,gBAAO,CAACC,MAAM,CAAC;EACjDC,SAAS,EAAE,SAAS;EAEpB;AACF;AACA;AACA;EACEC,YAAY,WAAAA,aAACC,eAAe,EAAE;IAC5B,IACEA,eAAe,aAAfA,eAAe,eAAfA,eAAe,CAAEC,QAAQ,CAAC,iBAAiB,CAAC,IAC5CD,eAAe,aAAfA,eAAe,eAAfA,eAAe,CAAEC,QAAQ,CAAC,WAAW,CAAC,IACtCD,eAAe,aAAfA,eAAe,eAAfA,eAAe,CAAEC,QAAQ,CAAC,WAAW,CAAC,IACtCC,OAAO,CAACC,GAAG,CAACC,QAAQ,KAAK,YAAY,EACrC;MACA,OAAO,MAAM;IACf;IAEA,OAAOF,OAAO,CAACC,GAAG,CAACC,QAAQ,KAAK,YAAY,GAAG,MAAM,GAAG,MAAM;EAChE,CAAC;EAEDC,WAAW,WAAAA,YAACC,IAAI,EAAE;IAAA,IAAAC,WAAA,EAAAC,qBAAA;IAChB;IACA;IACA,IAAMC,MAAM,GAAG;MACbC,SAAS,EAAE,IAAI,CAACX,YAAY,EAAAQ,WAAA,GAACD,IAAI,CAACK,KAAK,cAAAJ,WAAA,wBAAAC,qBAAA,GAAVD,WAAA,CAAYK,SAAS,cAAAJ,qBAAA,uBAArBA,qBAAA,CAAuBR,eAAe,CAAC;MACpEa,WAAW,EAAE;IACf,CAAC;IAEDP,IAAI,CAACQ,YAAY,CAACL,MAAM,GAAG,IAAAM,OAAA,CAAAC,OAAA,EAAcP,MAAM,EAAEH,IAAI,CAACQ,YAAY,CAACL,MAAM,CAAC;IAE1E,OAAOQ,QAAA,CAAAD,OAAA,CAAQE,OAAO,CAACZ,IAAI,CAAC;EAC9B,CAAC;EAEDa,cAAc,WAAAA,eAACC,KAAK,EAAE;IACpB;IACAA,KAAK,CAACC,OAAO,CAAC,UAACf,IAAI,EAAK;MACtBA,IAAI,CAACQ,YAAY,CAACQ,UAAU,GAAGhB,IAAI,CAACQ,YAAY,CAACQ,UAAU,IAAI,CAAC,CAAC;MACjEhB,IAAI,CAACQ,YAAY,CAACQ,UAAU,CAACC,IAAI,GAAG,IAAIC,IAAI,EAAE,CAACC,WAAW,EAAE;IAC9D,CAAC,CAAC;IAEF,OAAOR,QAAA,CAAAD,OAAA,CAAQE,OAAO,CAACE,KAAK,CAAC;EAC/B,CAAC;EAEDM,iBAAiB,WAAAA,kBAACC,OAAO,EAAE;IACzB,OAAO,IAAI,CAACC,KAAK,CAACC,OAAO,CAAC;MACxBC,MAAM,EAAE,MAAM;MACdC,OAAO,EAAE,SAAS;MAClBC,QAAQ,EAAE,eAAe;MACzBC,IAAI,EAAE;QACJC,OAAO,EAAEP;MACX;IACF,CAAC,CAAC;EACJ;AACF,CAAC,CAAC;AAAC,IAAAQ,QAAA,GAEYxC,2BAA2B;AAAAyC,OAAA,CAAApB,OAAA,GAAAmB,QAAA"}