Socket
Socket
Sign inDemoInstall

@webex/internal-plugin-metrics

Package Overview
Dependencies
Maintainers
7
Versions
1204
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@webex/internal-plugin-metrics - npm Package Compare versions

Comparing version 3.0.0 to 3.1.0

dist/client-metrics-prelogin-batcher.js

104

dist/call-diagnostic/call-diagnostic-metrics-latencies.js

@@ -56,2 +56,3 @@ "use strict";

this.latencyTimestamps.clear();
this.precomputedLatencies.clear();
}

@@ -86,3 +87,4 @@

* @param key - key
* @param value -value
* @param value - value
* @param options - store options
* @throws

@@ -116,3 +118,4 @@ * @returns

* @param key - key
* @param value -value
* @param value - value
* @param accumulate - when it is true, it overwrites existing value with sum of the current value and the new measurement otherwise just store the new measurement
* @throws

@@ -124,6 +127,26 @@ * @returns

value: function saveLatency(key, value) {
this.precomputedLatencies.set(key, value);
var accumulate = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
var existingValue = accumulate ? this.precomputedLatencies.get(key) || 0 : 0;
this.precomputedLatencies.set(key, value + existingValue);
}
/**
* Measure latency for a request
* @param callback - callback for which you would like to measure latency
* @param key - key
* @param accumulate - when it is true, it overwrites existing value with sum of the current value and the new measurement otherwise just store the new measurement
* @returns
*/
}, {
key: "measureLatency",
value: function measureLatency(callback, key) {
var _this2 = this;
var accumulate = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
var start = performance.now();
return callback().finally(function () {
_this2.saveLatency(key, performance.now() - start, accumulate);
});
}
/**
* Store only the first timestamp value for the given key

@@ -189,2 +212,13 @@ * @param key - key

/**
* getU2CTime
* @returns - latency
*/
}, {
key: "getU2CTime",
value: function getU2CTime() {
var u2cLatency = this.precomputedLatencies.get('internal.get.u2c.time');
return u2cLatency ? Math.floor(u2cLatency) : undefined;
}
/**
* Device Register Time

@@ -220,13 +254,2 @@ * @returns - latency

/**
* Locus Join Response Sent Received
* @returns - latency
*/
}, {
key: "getJoinRespSentReceived",
value: function getJoinRespSentReceived() {
// TODO: not clear SPARK-440554
return undefined;
}
/**
* Time taken to do turn discovery

@@ -461,2 +484,12 @@ * @returns - latency

/**
* Total latency for all get cluster request.
*/
}, {
key: "getReachabilityClustersReqResp",
value: function getReachabilityClustersReqResp() {
var reachablityClusterReqResp = this.precomputedLatencies.get('internal.get.cluster.time');
return reachablityClusterReqResp ? Math.floor(reachablityClusterReqResp) : undefined;
}
/**
* Audio setup delay transmit

@@ -478,2 +511,45 @@ */

}
/**
* Total latency for all exchange ci token.
*/
}, {
key: "getExchangeCITokenJMT",
value: function getExchangeCITokenJMT() {
var exchangeCITokenJMT = this.precomputedLatencies.get('internal.exchange.ci.token.time');
return exchangeCITokenJMT ? Math.floor(exchangeCITokenJMT) : undefined;
}
/**
* Total latency for all refresh captcha requests.
*/
}, {
key: "getRefreshCaptchaReqResp",
value: function getRefreshCaptchaReqResp() {
var refreshCaptchaReqResp = this.precomputedLatencies.get('internal.refresh.captcha.time');
return refreshCaptchaReqResp ? Math.floor(refreshCaptchaReqResp) : undefined;
}
/**
* Get the latency for downloading intelligence models.
* @returns - latency
*/
}, {
key: "getDownloadIntelligenceModelsReqResp",
value: function getDownloadIntelligenceModelsReqResp() {
var downloadIntelligenceModelsReqResp = this.precomputedLatencies.get('internal.api.fetch.intelligence.models');
return downloadIntelligenceModelsReqResp ? Math.floor(downloadIntelligenceModelsReqResp) : undefined;
}
/**
* Get the total latency for all other app API requests.
* Excludes meeting info, because it's measured separately.
* @returns - latency
*/
}, {
key: "getOtherAppApiReqResp",
value: function getOtherAppApiReqResp() {
var otherAppApiJMT = this.precomputedLatencies.get('internal.other.app.api.time');
return otherAppApiJMT > 0 ? Math.floor(otherAppApiJMT) : undefined;
}
}]);

@@ -480,0 +556,0 @@ return CallDiagnosticLatencies;

67

dist/call-diagnostic/call-diagnostic-metrics.js

@@ -236,2 +236,5 @@ "use strict";

}
if (options !== null && options !== void 0 && options.browserLaunchMethod) {
origin.clientInfo.browserLaunchMethod = options.browserLaunchMethod;
}
return origin;

@@ -270,2 +273,4 @@ }

var device = this.webex.internal.device;
var _ref2 = device.config || {},
installationId = _ref2.installationId;
identifiers.userId = device.userId || preLoginId;

@@ -276,2 +281,5 @@ identifiers.deviceId = device.url;

identifiers.locusUrl = this.webex.internal.services.get('locus');
if (installationId) {
identifiers.machineId = installationId;
}
}

@@ -368,6 +376,6 @@ if (meeting !== null && meeting !== void 0 && (_meeting$locusInfo = meeting.locusInfo) !== null && _meeting$locusInfo !== void 0 && _meeting$locusInfo.fullState) {

key: "submitMQE",
value: function submitMQE(_ref2) {
var name = _ref2.name,
payload = _ref2.payload,
options = _ref2.options;
value: function submitMQE(_ref3) {
var name = _ref3.name,
payload = _ref3.payload,
options = _ref3.options;
var meetingId = options.meetingId,

@@ -447,9 +455,9 @@ mediaConnections = options.mediaConnections,

key: "getErrorPayloadForClientErrorCode",
value: function getErrorPayloadForClientErrorCode(_ref3) {
var clientErrorCode = _ref3.clientErrorCode,
serviceErrorCode = _ref3.serviceErrorCode,
serviceErrorName = _ref3.serviceErrorName,
rawErrorMessage = _ref3.rawErrorMessage,
payloadOverrides = _ref3.payloadOverrides,
httpStatusCode = _ref3.httpStatusCode;
value: function getErrorPayloadForClientErrorCode(_ref4) {
var clientErrorCode = _ref4.clientErrorCode,
serviceErrorCode = _ref4.serviceErrorCode,
serviceErrorName = _ref4.serviceErrorName,
rawErrorMessage = _ref4.rawErrorMessage,
payloadOverrides = _ref4.payloadOverrides,
httpStatusCode = _ref4.httpStatusCode;
var error;

@@ -571,2 +579,3 @@ if (clientErrorCode) {

serviceErrorCode: _config2.UNKNOWN_ERROR,
payloadOverrides: rawError.payloadOverrides,
rawErrorMessage: rawErrorMessage,

@@ -586,6 +595,6 @@ httpStatusCode: httpStatusCode

key: "createClientEventObjectInMeeting",
value: function createClientEventObjectInMeeting(_ref4) {
var name = _ref4.name,
options = _ref4.options,
errors = _ref4.errors;
value: function createClientEventObjectInMeeting(_ref5) {
var name = _ref5.name,
options = _ref5.options,
errors = _ref5.errors;
var meetingId = options.meetingId,

@@ -646,6 +655,6 @@ mediaConnections = options.mediaConnections,

key: "createClientEventObjectPreMeeting",
value: function createClientEventObjectPreMeeting(_ref5) {
var name = _ref5.name,
options = _ref5.options,
errors = _ref5.errors;
value: function createClientEventObjectPreMeeting(_ref6) {
var name = _ref6.name,
options = _ref6.options,
errors = _ref6.errors;
var correlationId = options.correlationId,

@@ -689,6 +698,6 @@ globalMeetingId = options.globalMeetingId,

key: "prepareClientEvent",
value: function prepareClientEvent(_ref6) {
var name = _ref6.name,
payload = _ref6.payload,
options = _ref6.options;
value: function prepareClientEvent(_ref7) {
var name = _ref7.name,
payload = _ref7.payload,
options = _ref7.options;
var meetingId = options.meetingId,

@@ -745,6 +754,6 @@ correlationId = options.correlationId,

key: "submitClientEvent",
value: function submitClientEvent(_ref7) {
var name = _ref7.name,
payload = _ref7.payload,
options = _ref7.options;
value: function submitClientEvent(_ref8) {
var name = _ref8.name,
payload = _ref8.payload,
options = _ref8.options;
this.logger.log(_config2.CALL_DIAGNOSTIC_LOG_IDENTIFIER, 'CallDiagnosticMetrics: @submitClientEvent. Submit Client Event CA event.', "name: ".concat(name));

@@ -794,3 +803,3 @@ var diagnosticEvent = this.prepareClientEvent({

function () {
var _buildClientEventFetchRequestOptions = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee(_ref8) {
var _buildClientEventFetchRequestOptions = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee(_ref9) {
var name, payload, options, clientEvent, diagnosticEvent, request;

@@ -800,3 +809,3 @@ return _regenerator.default.wrap(function _callee$(_context) {

case 0:
name = _ref8.name, payload = _ref8.payload, options = _ref8.options;
name = _ref9.name, payload = _ref9.payload, options = _ref9.options;
this.logger.log(_config2.CALL_DIAGNOSTIC_LOG_IDENTIFIER, 'CallDiagnosticMetrics: @buildClientEventFetchRequestOptions. Building request options object for fetch()...', "name: ".concat(name));

@@ -803,0 +812,0 @@ clientEvent = this.prepareClientEvent({

@@ -218,5 +218,11 @@ "use strict";

break;
case 'client.login.end':
joinTimes.otherAppApiReqResp = cdl.getOtherAppApiReqResp();
joinTimes.exchangeCITokenJMT = cdl.getExchangeCITokenJMT();
break;
case 'client.interstitial-window.launched':
joinTimes.meetingInfoReqResp = cdl.getMeetingInfoReqResp();
joinTimes.clickToInterstitial = cdl.getClickToInterstitial();
joinTimes.refreshCaptchaServiceReqResp = cdl.getRefreshCaptchaReqResp();
joinTimes.downloadIntelligenceModelsReqResp = cdl.getDownloadIntelligenceModelsReqResp();
break;

@@ -227,2 +233,4 @@ case 'client.call.initiated':

joinTimes.registerWDMDeviceJMT = cdl.getRegisterWDMDeviceJMT();
joinTimes.getU2CTime = cdl.getU2CTime();
joinTimes.getReachabilityClustersReqResp = cdl.getReachabilityClustersReqResp();
break;

@@ -233,3 +241,2 @@ case 'client.locus.join.response':

joinTimes.joinReqResp = cdl.getJoinReqResp();
joinTimes.joinReqSentReceived = cdl.getJoinRespSentReceived();
joinTimes.pageJmt = cdl.getPageJMT();

@@ -340,6 +347,6 @@ joinTimes.clickToInterstitial = cdl.getClickToInterstitial();

}
if (signalingState === 'stable' && iceConnectionState === 'connected') {
if (signalingState === 'stable' && (iceConnectionState === 'connected' || iceConnectionState === 'disconnected')) {
errorCode = _config.DTLS_HANDSHAKE_FAILED_CLIENT_CODE;
}
if (signalingState !== 'have-local-offer' && iceConnectionState !== 'connected') {
if (signalingState !== 'have-local-offer' && iceConnectionState !== 'connected' && iceConnectionState !== 'disconnected') {
if (turnServerUsed) {

@@ -346,0 +353,0 @@ errorCode = _config.ICE_FAILED_WITH_TURN_TLS_CLIENT_CODE;

@@ -21,2 +21,3 @@ "use strict";

var _clientMetricsBatcher = _interopRequireDefault(require("./client-metrics-batcher"));
var _clientMetricsPreloginBatcher = _interopRequireDefault(require("./client-metrics-prelogin-batcher"));
function ownKeys(e, r) { var t = _Object$keys(e); if (_Object$getOwnPropertySymbols) { var o = _Object$getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return _Object$getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }

@@ -53,3 +54,4 @@ function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { (0, _defineProperty2.default)(e, r, t[r]); }) : _Object$getOwnPropertyDescriptors ? _Object$defineProperties(e, _Object$getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { _Object$defineProperty(e, r, _Object$getOwnPropertyDescriptor(t, r)); }); } return e; } /* eslint-disable default-param-last */ /*!

batcher: _batcher.default,
clientMetricsBatcher: _clientMetricsBatcher.default
clientMetricsBatcher: _clientMetricsBatcher.default,
clientMetricsPreloginBatcher: _clientMetricsPreloginBatcher.default
},

@@ -69,2 +71,3 @@ namespace: 'Metrics',

getClientMetricsPayload: function getClientMetricsPayload(eventName, props) {
var _this$webex$meetings, _this$webex$meetings$, _this$webex$meetings$2;
if (!eventName) {

@@ -76,5 +79,8 @@ throw Error('Missing behavioral metric name. Please provide one');

};
// @ts-ignore
var providedClientVersion = (_this$webex$meetings = this.webex.meetings) === null || _this$webex$meetings === void 0 ? void 0 : (_this$webex$meetings$ = _this$webex$meetings.config) === null || _this$webex$meetings$ === void 0 ? void 0 : (_this$webex$meetings$2 = _this$webex$meetings$.metrics) === null || _this$webex$meetings$2 === void 0 ? void 0 : _this$webex$meetings$2.clientVersion;
payload.tags = _objectSpread(_objectSpread({}, props.tags), {}, {
browser: getBrowserName(),
os: getOSNameInternal(),
appVersion: providedClientVersion,
// Node does not like this so we need to check if it exists or not

@@ -125,10 +131,4 @@ // eslint-disable-next-line no-undef

if (preLoginId) {
var _payload = {
metrics: [payload]
};
// Do not batch these because pre-login events occur during onboarding, so we will be partially blind
// to users' progress through the reg flow if we wait to persist pre-login metrics for people who drop off because
// their metrics will not post from a queue flush in time
return this.postPreLoginMetric(_payload, preLoginId);
this.clientMetricsPreloginBatcher.savePreLoginId(preLoginId);
return this.clientMetricsPreloginBatcher.request(payload);
}

@@ -156,20 +156,5 @@ return this.clientMetricsBatcher.request(payload);

},
postPreLoginMetric: function postPreLoginMetric(payload, preLoginId) {
var _this = this;
return this.webex.credentials.getClientToken().then(function (token) {
return _this.request({
method: 'POST',
api: 'metrics',
resource: 'clientmetrics-prelogin',
headers: {
authorization: token.toString(),
'x-prelogin-userid': preLoginId
},
body: payload
});
});
},
version: "3.0.0"
version: "3.1.0"
});
var _default = exports.default = Metrics;
//# sourceMappingURL=metrics.js.map

@@ -53,2 +53,4 @@ "use strict";

_this = _super.call.apply(_super, [this].concat(args));
// @ts-ignore
// Call Diagnostic latencies

@@ -58,2 +60,5 @@ (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "callDiagnosticLatencies", void 0);

(0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "callDiagnosticMetrics", void 0);
_this.callDiagnosticLatencies = new _callDiagnosticMetricsLatencies.default({}, {
parent: _this.webex
});
_this.onReady();

@@ -76,6 +81,2 @@ return _this;

});
// @ts-ignore
_this2.callDiagnosticLatencies = new _callDiagnosticMetricsLatencies.default({}, {
parent: _this2.webex
});
});

@@ -82,0 +83,0 @@ }

@@ -54,3 +54,3 @@ "use strict";

var _this = this;
var batchId = (0, _lodash.uniqueId)('prelogin-ca-batch-');
var batchId = (0, _lodash.uniqueId)('prelogin-batch-');
if (this.preLoginId === undefined) {

@@ -57,0 +57,0 @@ this.webex.logger.error(PRE_LOGIN_METRICS_IDENTIFIER, "PreLoginMetricsBatcher: @submitHttpRequest#".concat(batchId, ". PreLoginId is not set."));

@@ -33,3 +33,4 @@ import { WebexPlugin } from '@webex/webex-core';

* @param key - key
* @param value -value
* @param value - value
* @param options - store options
* @throws

@@ -48,8 +49,17 @@ * @returns

* @param key - key
* @param value -value
* @param value - value
* @param accumulate - when it is true, it overwrites existing value with sum of the current value and the new measurement otherwise just store the new measurement
* @throws
* @returns
*/
saveLatency(key: PreComputedLatencies, value: number): void;
saveLatency(key: PreComputedLatencies, value: number, accumulate?: boolean): void;
/**
* Measure latency for a request
* @param callback - callback for which you would like to measure latency
* @param key - key
* @param accumulate - when it is true, it overwrites existing value with sum of the current value and the new measurement otherwise just store the new measurement
* @returns
*/
measureLatency(callback: () => Promise<unknown>, key: PreComputedLatencies, accumulate?: boolean): Promise<unknown>;
/**
* Store only the first timestamp value for the given key

@@ -86,2 +96,7 @@ * @param key - key

/**
* getU2CTime
* @returns - latency
*/
getU2CTime(): number;
/**
* Device Register Time

@@ -102,7 +117,2 @@ * @returns - latency

/**
* Locus Join Response Sent Received
* @returns - latency
*/
getJoinRespSentReceived(): any;
/**
* Time taken to do turn discovery

@@ -201,2 +211,6 @@ * @returns - latency

/**
* Total latency for all get cluster request.
*/
getReachabilityClustersReqResp(): number;
/**
* Audio setup delay transmit

@@ -209,2 +223,21 @@ */

getVideoJoinRespTxStart(): number;
/**
* Total latency for all exchange ci token.
*/
getExchangeCITokenJMT(): number;
/**
* Total latency for all refresh captcha requests.
*/
getRefreshCaptchaReqResp(): number;
/**
* Get the latency for downloading intelligence models.
* @returns - latency
*/
getDownloadIntelligenceModelsReqResp(): number;
/**
* Get the total latency for all other app API requests.
* Excludes meeting info, because it's measured separately.
* @returns - latency
*/
getOtherAppApiReqResp(): number;
}
import { StatelessWebexPlugin } from '@webex/webex-core';
import { Event, ClientType, SubClientType, NetworkType, EnvironmentType, NewEnvironmentType, ClientEvent, SubmitClientEventOptions, MediaQualityEvent, SubmitMQEOptions, SubmitMQEPayload, ClientLaunchMethodType, ClientEventError, ClientEventPayload, ClientSubServiceType } from '../metrics.types';
import { Event, ClientType, SubClientType, NetworkType, EnvironmentType, NewEnvironmentType, ClientEvent, SubmitClientEventOptions, MediaQualityEvent, SubmitMQEOptions, SubmitMQEPayload, ClientLaunchMethodType, ClientEventError, ClientEventPayload, ClientSubServiceType, BrowserLaunchMethodType } from '../metrics.types';
type GetOriginOptions = {

@@ -8,2 +8,3 @@ clientType: ClientType;

clientLaunchMethod?: ClientLaunchMethodType;
browserLaunchMethod?: BrowserLaunchMethodType;
environment?: EnvironmentType;

@@ -79,3 +80,3 @@ newEnvironment?: NewEnvironmentType;

clientInfo?: {
os?: "windows" | "mac" | "ios" | "android" | "chrome" | "linux" | "other" | "android-x64" | "android-arm64" | "uwp-arm64";
os?: "other" | "chrome" | "windows" | "mac" | "ios" | "android" | "linux" | "android-x64" | "android-arm64" | "uwp-arm64";
osVersion?: string;

@@ -92,14 +93,8 @@ localIP?: string;

clientType?: "MEETING_CENTER" | "EVENT_CENTER" | "TRAINING_CENTER" | "TEAMS_CLIENT" | "TEAMS_DEVICE" | "TEAMS_SHARE" | "SIP" | "RECORDING" | "CLOUD_AWARE_SIP" | "TEAMS_WXC_CLIENT" | "WXC_CLIENT" | "WXC_DEVICE" | "WEBEX_JS_SDK" | "VOICEA_CLIENT" | "CISCO_SIP_GW" | "WEBEX_SDK" | "CPAAS_THIRD_PARTY_SDK" | "WXC_THIRD_PARTY" | "WXCC";
subClientType?: "TEAMS_DEVICE" | "DESKTOP_APP" | "DESKTOP_APP_VDI" | "DEVICE_CURRENT" | "DEVICE_LEGACY_2020" | "HOLOGRAM_HEADSET_APP" | "HVDI_APP" | "MOBILE_APP" | "MOBILE_NETWORK" | "VDI_APP" | "WEB_APP";
clientVersion?: string; /**
* Returns the login type of the current user
* @returns one of 'login-ci','unverified-guest', null
*/
subClientType?: "TEAMS_DEVICE" | "DESKTOP_APP" | "DESKTOP_APP_VDI" | "DEVICE_CURRENT" | "DEVICE_LEGACY_2020" | "HOLOGRAM_HEADSET_APP" | "HVDI_APP" | "MIXED" | "MOBILE_APP" | "MOBILE_NETWORK" | "PAGE" | "VDI_APP" | "WEB_APP";
clientVersion?: string;
clientVersionStatus?: "CURRENT" | "LEGACY" | "UNSUPPORTED";
localClientVersion?: string;
modelNumber?: string;
joinFirstUpdateLater?: "ep-enabled" | "sp-enabled" | "not-enabled"; /**
* Returns if the meeting has converged architecture enabled
* @param options.meetingId
*/
joinFirstUpdateLater?: "ep-enabled" | "sp-enabled" | "not-enabled";
standbyUsed?: boolean;

@@ -191,2 +186,3 @@ prefetchDocShowUsed?: boolean;

msteamsConferenceId?: string;
msteamsMeetingId?: string;
oauth2ClientId?: string;

@@ -263,2 +259,3 @@ orgId?: string;

msteamsConferenceId?: string;
msteamsMeetingId?: string;
oauth2ClientId?: string;

@@ -346,3 +343,3 @@ orgId?: string;

fatal: boolean;
category: "other" | "signaling" | "media" | "network" | "expected";
category: "signaling" | "media" | "network" | "other" | "expected";
errorDescription?: string;

@@ -355,2 +352,3 @@ errorCode?: number;

rawErrorMessage?: string;
mediaDeviceErrors?: string;
shownToUser: boolean;

@@ -357,0 +355,0 @@ serviceErrorCode?: number;

@@ -8,3 +8,3 @@ /*!

import * as Utils from './utils';
import { ClientEvent, ClientEventLeaveReason, SubmitBehavioralEvent, SubmitClientEvent, SubmitInternalEvent, SubmitOperationalEvent, SubmitMQE } from './metrics.types';
import { ClientEvent, ClientEventLeaveReason, SubmitBehavioralEvent, SubmitClientEvent, SubmitInternalEvent, SubmitOperationalEvent, SubmitMQE, PreComputedLatencies } from './metrics.types';
import * as CALL_DIAGNOSTIC_CONFIG from './call-diagnostic/config';

@@ -16,2 +16,2 @@ import * as CallDiagnosticUtils from './call-diagnostic/call-diagnostic-metrics.util';

export { config, CALL_DIAGNOSTIC_CONFIG, NewMetrics, Utils, CallDiagnosticUtils, CallDiagnosticLatencies, CallDiagnosticMetrics, };
export type { ClientEvent, ClientEventLeaveReason, SubmitBehavioralEvent, SubmitClientEvent, SubmitInternalEvent, SubmitMQE, SubmitOperationalEvent, };
export type { ClientEvent, ClientEventLeaveReason, SubmitBehavioralEvent, SubmitClientEvent, SubmitInternalEvent, SubmitMQE, SubmitOperationalEvent, PreComputedLatencies, };

@@ -9,2 +9,3 @@ import { ClientEvent as RawClientEvent, Event as RawEvent, MediaQualityEvent as RawMediaQualityEvent } from '@webex/event-dictionary-ts';

export type ClientLaunchMethodType = NonNullable<RawEvent['origin']['clientInfo']>['clientLaunchMethod'];
export type BrowserLaunchMethodType = NonNullable<RawEvent['origin']['clientInfo']>['browserLaunchMethod'];
export type SubmitClientEventOptions = {

@@ -19,2 +20,3 @@ meetingId?: string;

clientLaunchMethod?: ClientLaunchMethodType;
browserLaunchMethod?: BrowserLaunchMethodType;
webexConferenceIdStr?: string;

@@ -107,2 +109,2 @@ globalMeetingId?: string;

}) => Promise<any>;
export type PreComputedLatencies = 'internal.client.pageJMT' | 'internal.download.time' | 'internal.click.to.interstitial' | 'internal.call.init.join.req';
export type PreComputedLatencies = 'internal.client.pageJMT' | 'internal.download.time' | 'internal.get.cluster.time' | 'internal.click.to.interstitial' | 'internal.refresh.captcha.time' | 'internal.exchange.ci.token.time' | 'internal.get.u2c.time' | 'internal.call.init.join.req' | 'internal.other.app.api.time' | 'internal.api.fetch.intelligence.models';

@@ -29,6 +29,6 @@ {

"@webex/legacy-tools": "0.0.0",
"@webex/test-helper-chai": "3.0.0",
"@webex/test-helper-mocha": "3.0.0",
"@webex/test-helper-mock-webex": "3.0.0",
"@webex/test-helper-test-users": "3.0.0",
"@webex/test-helper-chai": "3.1.0",
"@webex/test-helper-mocha": "3.1.0",
"@webex/test-helper-mock-webex": "3.1.0",
"@webex/test-helper-test-users": "3.1.0",
"eslint": "^8.24.0",

@@ -39,10 +39,10 @@ "prettier": "^2.7.1",

"dependencies": {
"@webex/common": "3.0.0",
"@webex/common-timers": "3.0.0",
"@webex/event-dictionary-ts": "^1.0.1329",
"@webex/internal-plugin-device": "3.0.0",
"@webex/internal-plugin-metrics": "3.0.0",
"@webex/test-helper-chai": "3.0.0",
"@webex/test-helper-mock-webex": "3.0.0",
"@webex/webex-core": "3.0.0",
"@webex/common": "3.1.0",
"@webex/common-timers": "3.1.0",
"@webex/event-dictionary-ts": "^1.0.1406",
"@webex/internal-plugin-device": "3.1.0",
"@webex/internal-plugin-metrics": "3.1.0",
"@webex/test-helper-chai": "3.1.0",
"@webex/test-helper-mock-webex": "3.1.0",
"@webex/webex-core": "3.1.0",
"ip-anonymize": "^0.1.0",

@@ -60,3 +60,3 @@ "lodash": "^4.17.21",

},
"version": "3.0.0"
"version": "3.1.0"
}

@@ -34,2 +34,3 @@ /* eslint-disable class-methods-use-this */

this.latencyTimestamps.clear();
this.precomputedLatencies.clear();
}

@@ -61,3 +62,4 @@

* @param key - key
* @param value -value
* @param value - value
* @param options - store options
* @throws

@@ -97,11 +99,32 @@ * @returns

* @param key - key
* @param value -value
* @param value - value
* @param accumulate - when it is true, it overwrites existing value with sum of the current value and the new measurement otherwise just store the new measurement
* @throws
* @returns
*/
public saveLatency(key: PreComputedLatencies, value: number) {
this.precomputedLatencies.set(key, value);
public saveLatency(key: PreComputedLatencies, value: number, accumulate = false) {
const existingValue = accumulate ? this.precomputedLatencies.get(key) || 0 : 0;
this.precomputedLatencies.set(key, value + existingValue);
}
/**
* Measure latency for a request
* @param callback - callback for which you would like to measure latency
* @param key - key
* @param accumulate - when it is true, it overwrites existing value with sum of the current value and the new measurement otherwise just store the new measurement
* @returns
*/
public measureLatency(
callback: () => Promise<unknown>,
key: PreComputedLatencies,
accumulate = false
) {
const start = performance.now();
return callback().finally(() => {
this.saveLatency(key, performance.now() - start, accumulate);
});
}
/**
* Store only the first timestamp value for the given key

@@ -165,2 +188,12 @@ * @param key - key

/**
* getU2CTime
* @returns - latency
*/
public getU2CTime() {
const u2cLatency = this.precomputedLatencies.get('internal.get.u2c.time');
return u2cLatency ? Math.floor(u2cLatency) : undefined;
}
/**
* Device Register Time

@@ -196,11 +229,2 @@ * @returns - latency

/**
* Locus Join Response Sent Received
* @returns - latency
*/
public getJoinRespSentReceived() {
// TODO: not clear SPARK-440554
return undefined;
}
/**
* Time taken to do turn discovery

@@ -428,2 +452,11 @@ * @returns - latency

/**
* Total latency for all get cluster request.
*/
public getReachabilityClustersReqResp() {
const reachablityClusterReqResp = this.precomputedLatencies.get('internal.get.cluster.time');
return reachablityClusterReqResp ? Math.floor(reachablityClusterReqResp) : undefined;
}
/**
* Audio setup delay transmit

@@ -441,2 +474,45 @@ */

}
/**
* Total latency for all exchange ci token.
*/
public getExchangeCITokenJMT() {
const exchangeCITokenJMT = this.precomputedLatencies.get('internal.exchange.ci.token.time');
return exchangeCITokenJMT ? Math.floor(exchangeCITokenJMT) : undefined;
}
/**
* Total latency for all refresh captcha requests.
*/
public getRefreshCaptchaReqResp() {
const refreshCaptchaReqResp = this.precomputedLatencies.get('internal.refresh.captcha.time');
return refreshCaptchaReqResp ? Math.floor(refreshCaptchaReqResp) : undefined;
}
/**
* Get the latency for downloading intelligence models.
* @returns - latency
*/
public getDownloadIntelligenceModelsReqResp() {
const downloadIntelligenceModelsReqResp = this.precomputedLatencies.get(
'internal.api.fetch.intelligence.models'
);
return downloadIntelligenceModelsReqResp
? Math.floor(downloadIntelligenceModelsReqResp)
: undefined;
}
/**
* Get the total latency for all other app API requests.
* Excludes meeting info, because it's measured separately.
* @returns - latency
*/
public getOtherAppApiReqResp() {
const otherAppApiJMT = this.precomputedLatencies.get('internal.other.app.api.time');
return otherAppApiJMT > 0 ? Math.floor(otherAppApiJMT) : undefined;
}
}

@@ -42,2 +42,3 @@ /* eslint-disable @typescript-eslint/no-unused-vars */

ClientSubServiceType,
BrowserLaunchMethodType,
} from '../metrics.types';

@@ -69,2 +70,3 @@ import CallDiagnosticEventsBatcher from './call-diagnostic-metrics-batcher';

clientLaunchMethod?: ClientLaunchMethodType;
browserLaunchMethod?: BrowserLaunchMethodType;
environment?: EnvironmentType;

@@ -263,2 +265,6 @@ newEnvironment?: NewEnvironmentType;

if (options?.browserLaunchMethod) {
origin.clientInfo.browserLaunchMethod = options.browserLaunchMethod;
}
return origin;

@@ -299,2 +305,4 @@ }

const {device} = this.webex.internal;
const {installationId} = device.config || {};
identifiers.userId = device.userId || preLoginId;

@@ -305,2 +313,6 @@ identifiers.deviceId = device.url;

identifiers.locusUrl = this.webex.internal.services.get('locus');
if (installationId) {
identifiers.machineId = installationId;
}
}

@@ -615,2 +627,3 @@

serviceErrorCode: UNKNOWN_ERROR,
payloadOverrides: rawError.payloadOverrides,
rawErrorMessage,

@@ -617,0 +630,0 @@ httpStatusCode,

@@ -247,5 +247,11 @@ /* eslint-disable valid-jsdoc */

break;
case 'client.login.end':
joinTimes.otherAppApiReqResp = cdl.getOtherAppApiReqResp();
joinTimes.exchangeCITokenJMT = cdl.getExchangeCITokenJMT();
break;
case 'client.interstitial-window.launched':
joinTimes.meetingInfoReqResp = cdl.getMeetingInfoReqResp();
joinTimes.clickToInterstitial = cdl.getClickToInterstitial();
joinTimes.refreshCaptchaServiceReqResp = cdl.getRefreshCaptchaReqResp();
joinTimes.downloadIntelligenceModelsReqResp = cdl.getDownloadIntelligenceModelsReqResp();
break;

@@ -257,2 +263,4 @@

joinTimes.registerWDMDeviceJMT = cdl.getRegisterWDMDeviceJMT();
joinTimes.getU2CTime = cdl.getU2CTime();
joinTimes.getReachabilityClustersReqResp = cdl.getReachabilityClustersReqResp();
break;

@@ -264,3 +272,2 @@

joinTimes.joinReqResp = cdl.getJoinReqResp();
joinTimes.joinReqSentReceived = cdl.getJoinRespSentReceived();
joinTimes.pageJmt = cdl.getPageJMT();

@@ -382,7 +389,14 @@ joinTimes.clickToInterstitial = cdl.getClickToInterstitial();

if (signalingState === 'stable' && iceConnectionState === 'connected') {
if (
signalingState === 'stable' &&
(iceConnectionState === 'connected' || iceConnectionState === 'disconnected')
) {
errorCode = DTLS_HANDSHAKE_FAILED_CLIENT_CODE;
}
if (signalingState !== 'have-local-offer' && iceConnectionState !== 'connected') {
if (
signalingState !== 'have-local-offer' &&
iceConnectionState !== 'connected' &&
iceConnectionState !== 'disconnected'
) {
if (turnServerUsed) {

@@ -389,0 +403,0 @@ errorCode = ICE_FAILED_WITH_TURN_TLS_CLIENT_CODE;

@@ -21,2 +21,3 @@ /*!

SubmitMQE,
PreComputedLatencies,
} from './metrics.types';

@@ -55,2 +56,3 @@ import * as CALL_DIAGNOSTIC_CONFIG from './call-diagnostic/config';

SubmitOperationalEvent,
PreComputedLatencies,
};

@@ -13,2 +13,3 @@ /* eslint-disable default-param-last */

import ClientMetricsBatcher from './client-metrics-batcher';
import ClientMetricsPreloginBatcher from './client-metrics-prelogin-batcher';

@@ -41,2 +42,3 @@ const {getOSName, getOSVersion, getBrowserName, getBrowserVersion} = BrowserDetection();

clientMetricsBatcher: ClientMetricsBatcher,
clientMetricsPreloginBatcher: ClientMetricsPreloginBatcher,
},

@@ -61,2 +63,4 @@

const payload = {metricName: eventName};
// @ts-ignore
const providedClientVersion = this.webex.meetings?.config?.metrics?.clientVersion;

@@ -67,2 +71,3 @@ payload.tags = {

os: getOSNameInternal(),
appVersion: providedClientVersion,

@@ -121,10 +126,5 @@ // Node does not like this so we need to check if it exists or not

if (preLoginId) {
const _payload = {
metrics: [payload],
};
this.clientMetricsPreloginBatcher.savePreLoginId(preLoginId);
// Do not batch these because pre-login events occur during onboarding, so we will be partially blind
// to users' progress through the reg flow if we wait to persist pre-login metrics for people who drop off because
// their metrics will not post from a queue flush in time
return this.postPreLoginMetric(_payload, preLoginId);
return this.clientMetricsPreloginBatcher.request(payload);
}

@@ -154,19 +154,4 @@

},
postPreLoginMetric(payload, preLoginId) {
return this.webex.credentials.getClientToken().then((token) =>
this.request({
method: 'POST',
api: 'metrics',
resource: 'clientmetrics-prelogin',
headers: {
authorization: token.toString(),
'x-prelogin-userid': preLoginId,
},
body: payload,
})
);
},
});
export default Metrics;

@@ -19,2 +19,6 @@ import {

export type BrowserLaunchMethodType = NonNullable<
RawEvent['origin']['clientInfo']
>['browserLaunchMethod'];
export type SubmitClientEventOptions = {

@@ -29,2 +33,3 @@ meetingId?: string;

clientLaunchMethod?: ClientLaunchMethodType;
browserLaunchMethod?: BrowserLaunchMethodType;
webexConferenceIdStr?: string;

@@ -169,3 +174,9 @@ globalMeetingId?: string;

| 'internal.download.time'
| 'internal.get.cluster.time'
| 'internal.click.to.interstitial'
| 'internal.call.init.join.req';
| 'internal.refresh.captcha.time'
| 'internal.exchange.ci.token.time'
| 'internal.get.u2c.time'
| 'internal.call.init.join.req'
| 'internal.other.app.api.time'
| 'internal.api.fetch.intelligence.models';

@@ -46,2 +46,4 @@ /* eslint-disable @typescript-eslint/no-unused-vars */

// @ts-ignore
this.callDiagnosticLatencies = new CallDiagnosticLatencies({}, {parent: this.webex});
this.onReady();

@@ -58,4 +60,2 @@ }

this.callDiagnosticMetrics = new CallDiagnosticMetrics({}, {parent: this.webex});
// @ts-ignore
this.callDiagnosticLatencies = new CallDiagnosticLatencies({}, {parent: this.webex});
});

@@ -62,0 +62,0 @@ }

@@ -51,3 +51,3 @@ import {uniqueId} from 'lodash';

submitHttpRequest(payload: any) {
const batchId = uniqueId('prelogin-ca-batch-');
const batchId = uniqueId('prelogin-batch-');
if (this.preLoginId === undefined) {

@@ -54,0 +54,0 @@ this.webex.logger.error(

@@ -106,2 +106,8 @@ /*!

.returns(10);
webex.internal.newMetrics.callDiagnosticLatencies.getRefreshCaptchaReqResp = sinon
.stub()
.returns(10);
webex.internal.newMetrics.callDiagnosticLatencies.getDownloadIntelligenceModelsReqResp =
sinon.stub().returns(42);
const promise = webex.internal.newMetrics.callDiagnosticMetrics.submitToCallDiagnostics(

@@ -123,2 +129,4 @@ //@ts-ignore

meetingInfoReqResp: 10,
refreshCaptchaServiceReqResp: 10,
downloadIntelligenceModelsReqResp: 42,
},

@@ -136,2 +144,8 @@ });

.returns(10);
webex.internal.newMetrics.callDiagnosticLatencies.getU2CTime = sinon
.stub()
.returns(20);
webex.internal.newMetrics.callDiagnosticLatencies.getReachabilityClustersReqResp = sinon
.stub()
.returns(10);
const promise = webex.internal.newMetrics.callDiagnosticMetrics.submitToCallDiagnostics(

@@ -153,2 +167,4 @@ //@ts-ignore

showInterstitialTime: 10,
getU2CTime: 20,
getReachabilityClustersReqResp: 10
},

@@ -166,5 +182,2 @@ });

.returns(10);
webex.internal.newMetrics.callDiagnosticLatencies.getJoinRespSentReceived = sinon
.stub()
.returns(20);
webex.internal.newMetrics.callDiagnosticLatencies.getPageJMT = sinon.stub().returns(30);

@@ -199,3 +212,2 @@ webex.internal.newMetrics.callDiagnosticLatencies.getClientJMT = sinon.stub().returns(5);

joinReqResp: 10,
joinReqSentReceived: 20,
meetingInfoReqResp: 10,

@@ -366,5 +378,4 @@ pageJmt: 30,

//TODO: The following two skipped tests needs investigation: https://jira-eng-gpk2.cisco.com/jira/browse/SPARK-485382
describe('when the request fails', () => {
it.skip('does not clear the queue', async () => {
it('does not clear the queue', async () => {
// avoid setting .sent timestamp

@@ -416,3 +427,3 @@ webex.internal.newMetrics.callDiagnosticMetrics.callDiagnosticEventsBatcher.prepareRequest =

describe('prepareItem', () => {
it.skip('calls prepareDiagnosticMetricItem correctly', async () => {
it('calls prepareDiagnosticMetricItem correctly', async () => {
// avoid setting .sent timestamp

@@ -419,0 +430,0 @@ webex.internal.newMetrics.callDiagnosticMetrics.callDiagnosticEventsBatcher.prepareRequest =

@@ -44,3 +44,3 @@ import {assert} from '@webex/test-helper-chai';

it('should save latency correctly', () => {
it('should save latency correctly by default and overwrites', () => {
assert.deepEqual(cdl.precomputedLatencies.size, 0);

@@ -50,4 +50,34 @@ cdl.saveLatency('internal.client.pageJMT', 10);

assert.deepEqual(cdl.precomputedLatencies.get('internal.client.pageJMT'), 10);
cdl.saveLatency('internal.client.pageJMT', 20);
assert.deepEqual(cdl.precomputedLatencies.size, 1);
assert.deepEqual(cdl.precomputedLatencies.get('internal.client.pageJMT'), 20);
});
it('should overwrite latency when accumulate is false', () => {
assert.deepEqual(cdl.precomputedLatencies.size, 0);
cdl.saveLatency('internal.client.pageJMT', 10, false);
assert.deepEqual(cdl.precomputedLatencies.size, 1);
assert.deepEqual(cdl.precomputedLatencies.get('internal.client.pageJMT'), 10);
cdl.saveLatency('internal.client.pageJMT', 20, false);
assert.deepEqual(cdl.precomputedLatencies.size, 1);
assert.deepEqual(cdl.precomputedLatencies.get('internal.client.pageJMT'), 20);
});
it('should save latency correctly when accumulate is true', () => {
assert.deepEqual(cdl.precomputedLatencies.size, 0);
cdl.saveLatency('internal.client.pageJMT', 10, true);
assert.deepEqual(cdl.precomputedLatencies.size, 1);
assert.deepEqual(cdl.precomputedLatencies.get('internal.client.pageJMT'), 10);
});
it('should save latency correctly when accumulate is true and there is existing value', () => {
assert.deepEqual(cdl.precomputedLatencies.size, 0);
cdl.saveLatency('internal.client.pageJMT', 10);
assert.deepEqual(cdl.precomputedLatencies.size, 1);
assert.deepEqual(cdl.precomputedLatencies.get('internal.client.pageJMT'), 10);
cdl.saveLatency('internal.client.pageJMT', 10, true);
assert.deepEqual(cdl.precomputedLatencies.size, 1);
assert.deepEqual(cdl.precomputedLatencies.get('internal.client.pageJMT'), 20);
});
it('should save only first timestamp correctly', () => {

@@ -83,4 +113,9 @@ assert.deepEqual(cdl.latencyTimestamps.size, 0);

assert.deepEqual(cdl.latencyTimestamps.size, 2);
cdl.saveLatency('internal.api.fetch.intelligence.models', 42);
assert.deepEqual(cdl.precomputedLatencies.size, 1);
cdl.clearTimestamps();
assert.deepEqual(cdl.latencyTimestamps.size, 0);
assert.deepEqual(cdl.precomputedLatencies.size, 0);
});

@@ -117,2 +152,123 @@

describe('measureLatency', () => {
let clock;
let saveLatencySpy;
beforeEach(() => {
clock = sinon.useFakeTimers();
saveLatencySpy = sinon.stub(cdl, 'saveLatency');
});
afterEach(() => {
clock.restore();
sinon.restore();
});
it('checks measureLatency with accumulate false', async () => {
const key = 'internal.client.pageJMT';
const accumulate = false;
const callbackStub = sinon.stub().callsFake(() => {
clock.tick(50);
return Promise.resolve('test');
});
// accumulate should be false by default
const promise = cdl.measureLatency(callbackStub, 'internal.client.pageJMT');
const resolvedValue = await promise;
assert.deepEqual(resolvedValue, 'test');
assert.calledOnceWithExactly(callbackStub);
assert.calledOnceWithExactly(saveLatencySpy, key, 50, accumulate);
});
it('checks measureLatency with accumulate true', async () => {
const key = 'internal.download.time';
const accumulate = true;
const callbackStub = sinon.stub().callsFake(() => {
clock.tick(20);
return Promise.resolve('test123');
});
const promise = cdl.measureLatency(callbackStub, 'internal.download.time', accumulate);
const resolvedValue = await promise;
assert.deepEqual(resolvedValue, 'test123');
assert.calledOnceWithExactly(callbackStub);
assert.calledOnceWithExactly(saveLatencySpy, key, 20, accumulate);
});
it('checks measureLatency when callBack rejects', async () => {
const key = 'internal.client.pageJMT';
const accumulate = false;
const error = new Error('some error');
const callbackStub = sinon.stub().callsFake(() => {
clock.tick(50);
return Promise.reject(error);
});
const promise = cdl.measureLatency(callbackStub, 'internal.client.pageJMT', accumulate);
const rejectedValue = await assert.isRejected(promise);
assert.deepEqual(rejectedValue, error);
assert.calledOnceWithExactly(callbackStub);
assert.calledOnceWithExactly(saveLatencySpy, key, 50, accumulate);
});
});
describe('getRefreshCaptchaReqResp', () => {
it('returns undefined when no precomputed value available', () => {
assert.deepEqual(cdl.getRefreshCaptchaReqResp(), undefined);
});
it('returns the correct value', () => {
cdl.saveLatency('internal.refresh.captcha.time', 123);
assert.deepEqual(cdl.getRefreshCaptchaReqResp(), 123);
});
it('returns the correct whole number', () => {
cdl.saveLatency('internal.refresh.captcha.time', 321.44);
assert.deepEqual(cdl.getRefreshCaptchaReqResp(), 321);
});
});
describe('getReachabilityClustersReqResp', () => {
it('returns undefined when no precomputed value available', () => {
assert.deepEqual(cdl.getReachabilityClustersReqResp(), undefined);
});
it('returns the correct value', () => {
cdl.saveLatency('internal.get.cluster.time', 123);
assert.deepEqual(cdl.getReachabilityClustersReqResp(), 123);
});
it('returns the correct whole number', () => {
cdl.saveLatency('internal.get.cluster.time', 321.44);
assert.deepEqual(cdl.getReachabilityClustersReqResp(), 321);
});
});
describe('getExchangeCITokenJMT', () => {
it('returns undefined when no precomputed value available', () => {
assert.deepEqual(cdl.getExchangeCITokenJMT(), undefined);
});
it('returns the correct value', () => {
cdl.saveLatency('internal.exchange.ci.token.time', 123);
assert.deepEqual(cdl.getExchangeCITokenJMT(), 123);
});
it('returns the correct whole number', () => {
cdl.saveLatency('internal.exchange.ci.token.time', 321.44);
assert.deepEqual(cdl.getExchangeCITokenJMT(), 321);
});
});
describe('saveTimestamp', () => {

@@ -519,2 +675,20 @@ afterEach(() => {

it('calculates getU2CTime correctly', () => {
it('returns undefined when no precomputed value available', () => {
assert.deepEqual(cdl.getU2CTime(), undefined);
});
it('returns the correct value', () => {
cdl.saveLatency('internal.get.u2c.time', 123);
assert.deepEqual(cdl.getU2CTime(), 123);
});
it('returns the correct whole number', () => {
cdl.saveLatency('internal.get.u2c.time', 321.44);
assert.deepEqual(cdl.getU2CTime(), 321);
});
});
it('calculates getDownloadTimeJMT correctly', () => {

@@ -524,3 +698,27 @@ cdl.saveLatency('internal.download.time', 1000);

});
describe('getOtherAppApiReqResp', () => {
it('returns undefined when no precomputed value available', () => {
assert.deepEqual(cdl.getOtherAppApiReqResp(), undefined);
});
it('returns undefined if it is less than 0', () => {
cdl.saveLatency('internal.other.app.api.time', 0);
assert.deepEqual(cdl.getOtherAppApiReqResp(), undefined);
});
it('returns the correct value', () => {
cdl.saveLatency('internal.other.app.api.time', 123);
assert.deepEqual(cdl.getOtherAppApiReqResp(), 123);
});
it('returns the correct whole number', () => {
cdl.saveLatency('internal.other.app.api.time', 321.44);
assert.deepEqual(cdl.getOtherAppApiReqResp(), 321);
});
});
});
});

@@ -304,8 +304,20 @@ import {assert} from '@webex/test-helper-chai';

['client.exit.app', {}],
['client.webexapp.launched', {
joinTimes: {
downloadTime: undefined,
}
}],
[
'client.login.end',
{
joinTimes: {
otherAppApiReqResp: undefined,
exchangeCITokenJMT: undefined,
},
},
],
[
'client.webexapp.launched',
{
joinTimes: {
downloadTime: undefined,
},
},
],
[
'client.interstitial-window.launched',

@@ -316,2 +328,4 @@ {

meetingInfoReqResp: undefined,
refreshCaptchaServiceReqResp: undefined,
downloadIntelligenceModelsReqResp: undefined,
},

@@ -327,2 +341,4 @@ },

registerWDMDeviceJMT: undefined,
getU2CTime: undefined,
getReachabilityClustersReqResp: undefined,
},

@@ -338,3 +354,2 @@ },

joinReqResp: undefined,
joinReqSentReceived: undefined,
pageJmt: undefined,

@@ -345,3 +360,3 @@ clickToInterstitial: undefined,

clientJmt: undefined,
downloadTime: undefined
downloadTime: undefined,
},

@@ -610,2 +625,8 @@ },

signalingState: 'stable',
iceConnectionState: 'disconnected',
turnServerUsed: true,
errorCode: DTLS_HANDSHAKE_FAILED_CLIENT_CODE,
},
{
signalingState: 'stable',
iceConnectionState: 'failed',

@@ -612,0 +633,0 @@ turnServerUsed: true,

@@ -107,5 +107,11 @@ /*!

webex.config.metrics.appType = 'sdk';
webex.meetings = {
config: {
metrics: {
clientVersion: '43.0.105'
}
}
}
sinon.spy(webex, 'request');
sinon.spy(metrics, 'postPreLoginMetric');
sinon.spy(metrics, 'aliasUser');

@@ -184,2 +190,3 @@ });

tags: {
appVersion: '43.0.105',
browser: '',

@@ -204,3 +211,3 @@ domain: 'whatever',

describe('before login', () => {
it('posts pre-login metric', () => {
it('clientMetricsPreloginBatcher pre-login metric', () => {
const date = clock.now;

@@ -213,4 +220,2 @@ const promise = metrics.submitClientMetrics(eventName, mockPayload, preLoginId);

.then(() => {
assert.called(metrics.postPreLoginMetric);
assert.calledOnce(webex.credentials.getClientToken);
assert.calledOnce(webex.request);

@@ -303,29 +308,2 @@ const req = webex.request.args[0][0];

describe('#postPreLoginMetric()', () => {
it('returns an HttpResponse object', () => {
const promise = metrics.postPreLoginMetric(preLoginProps, preLoginId);
return promiseTick(50)
.then(() => clock.tick(config.metrics.batcherWait))
.then(() => promise)
.then(() => {
assert.calledOnce(webex.request);
const req = webex.request.args[0][0];
const metric = req.body.metrics[0];
const {headers} = req;
assert.property(headers, 'x-prelogin-userid');
assert.property(metric, 'metricName');
assert.property(metric, 'tags');
assert.property(metric, 'fields');
assert.property(metric, 'timestamp');
assert.equal(metric.timestamp, transformedProps.timestamp);
assert.equal(metric.metricName, eventName);
assert.equal(metric.tags.testTag, 'tag value');
assert.equal(metric.fields.testField, 123);
});
});
});
describe('#aliasUser()', () => {

@@ -332,0 +310,0 @@ it('returns an HttpResponse object', () =>

import {assert} from '@webex/test-helper-chai';
import {NewMetrics} from '@webex/internal-plugin-metrics';
import {NewMetrics, CallDiagnosticLatencies} from '@webex/internal-plugin-metrics';
import MockWebex from '@webex/test-helper-mock-webex';

@@ -9,20 +9,22 @@ import sinon from 'sinon';

const mockWebex = () => new MockWebex({
children: {
newMetrics: NewMetrics,
},
meetings: {
meetingCollection: {
get: sinon.stub(),
},
},
request: sinon.stub().resolves({}),
logger: {
log: sinon.stub(),
error: sinon.stub(),
}
});
describe('check submitClientEvent when webex is not ready', () => {
let webex;
//@ts-ignore
webex = new MockWebex({
children: {
newMetrics: NewMetrics,
},
meetings: {
meetingCollection: {
get: sinon.stub(),
},
},
request: sinon.stub().resolves({}),
logger: {
log: sinon.stub(),
error: sinon.stub(),
}
});
webex = mockWebex();

@@ -42,2 +44,12 @@ it('checks the log', () => {

});
describe('new-metrics contstructor', () => {
it('checks callDiagnosticLatencies is defined before ready emit', () => {
const webex = mockWebex();
assert.instanceOf(webex.internal.newMetrics.callDiagnosticLatencies, CallDiagnosticLatencies);
});
});
describe('new-metrics', () => {

@@ -48,17 +60,3 @@ let webex;

//@ts-ignore
webex = new MockWebex({
children: {
newMetrics: NewMetrics,
},
meetings: {
meetingCollection: {
get: sinon.stub(),
},
},
request: sinon.stub().resolves({}),
logger: {
log: sinon.stub(),
error: sinon.stub(),
}
});
webex = mockWebex();

@@ -65,0 +63,0 @@ webex.emit('ready');

@@ -77,2 +77,4 @@ /*!

clickToInterstitial: undefined,
refreshCaptchaServiceReqResp: undefined,
downloadIntelligenceModelsReqResp: undefined,
},

@@ -142,3 +144,3 @@ name: 'client.interstitial-window.launched',

'Pre Login Metrics -->',
`PreLoginMetricsBatcher: @submitHttpRequest#prelogin-ca-batch-${expectedBatchId}. Request failed:`,
`PreLoginMetricsBatcher: @submitHttpRequest#prelogin-batch-${expectedBatchId}. Request failed:`,
`error: formattedError`

@@ -153,3 +155,4 @@ );

it('fails if preLoinId is not set', async () => {
webex.internal.newMetrics.callDiagnosticMetrics.preLoginMetricsBatcher.preLoginId = undefined;
webex.internal.newMetrics.callDiagnosticMetrics.preLoginMetricsBatcher.preLoginId =
undefined;

@@ -182,3 +185,3 @@ const promise =

it('calls prepareDiagnosticMetricItem correctly', async () => {
// avoid setting .sent timestamp
// avoid setting .sent timestamp
webex.internal.newMetrics.callDiagnosticMetrics.preLoginMetricsBatcher.prepareRequest = (q) =>

@@ -185,0 +188,0 @@ Promise.resolve(q);

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is too big to display

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc