@webex/internal-plugin-metrics 3.0.0-beta.232 → 3.0.0-beta.234

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.
@@ -146,6 +146,11 @@ var isBrowserMediaErrorName = function isBrowserMediaErrorName(errorName) {
146
146
  */
147
147
  exports.isBrowserMediaErrorName = isBrowserMediaErrorName;
148
148
  var getBuildType = function getBuildType(webClientDomain) {
149
+ var markAsTestEvent = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
150
+ // used temporary to test pre join in production without creating noise data, SPARK-468456
151
+ if (markAsTestEvent) {
152
+ return 'test';
153
+ }
149
154
  if (webClientDomain !== null && webClientDomain !== void 0 && webClientDomain.includes('localhost') || webClientDomain !== null && webClientDomain !== void 0 && webClientDomain.includes('127.0.0.1') || process.env.NODE_ENV !== 'production') {
150
155
  return 'test';
151
156
  }
@@ -160,14 +165,14 @@ var getBuildType = function getBuildType(webClientDomain) {
160
165
  */
161
166
  exports.getBuildType = getBuildType;
162
167
  var prepareDiagnosticMetricItem = function prepareDiagnosticMetricItem(webex, item) {
163
- var _item$event, _item$event$eventData, _item$eventPayload, _item$eventPayload$ev;
168
+ var _item$eventPayload, _item$eventPayload$ev, _item$eventPayload$ev2, _item$eventPayload2, _item$eventPayload2$e, _item$eventPayload2$e2, _item$eventPayload3, _item$eventPayload3$e;
164
169
  var origin = {
165
- buildType: 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),
170
+ buildType: exports.getBuildType((_item$eventPayload = item.eventPayload) === null || _item$eventPayload === void 0 ? void 0 : (_item$eventPayload$ev = _item$eventPayload.event) === null || _item$eventPayload$ev === void 0 ? void 0 : (_item$eventPayload$ev2 = _item$eventPayload$ev.eventData) === null || _item$eventPayload$ev2 === void 0 ? void 0 : _item$eventPayload$ev2.webClientDomain, (_item$eventPayload2 = item.eventPayload) === null || _item$eventPayload2 === void 0 ? void 0 : (_item$eventPayload2$e = _item$eventPayload2.event) === null || _item$eventPayload2$e === void 0 ? void 0 : (_item$eventPayload2$e2 = _item$eventPayload2$e.eventData) === null || _item$eventPayload2$e2 === void 0 ? void 0 : _item$eventPayload2$e2.markAsTestEvent),
166
171
  networkType: 'unknown'
167
172
  };
168
173
 
169
174
  // check event names and append latencies?
170
- var eventName = (_item$eventPayload = item.eventPayload) === null || _item$eventPayload === void 0 ? void 0 : (_item$eventPayload$ev = _item$eventPayload.event) === null || _item$eventPayload$ev === void 0 ? void 0 : _item$eventPayload$ev.name;
175
+ var eventName = (_item$eventPayload3 = item.eventPayload) === null || _item$eventPayload3 === void 0 ? void 0 : (_item$eventPayload3$e = _item$eventPayload3.event) === null || _item$eventPayload3$e === void 0 ? void 0 : _item$eventPayload3$e.name;
171
176
  var joinTimes = {};
172
177
  var audioSetupDelay = {};
173
178
  var videoSetupDelay = {};
@@ -1 +1 @@
1
- {"version":3,"names":["BrowserDetection","getOSName","getOSVersion","getBrowserName","getBrowserVersion","anonymizeIPAddress","localIp","anonymize","userAgentToString","clientName","webexVersion","userAgentOption","browserInfo","clientInfo","util","format","indexOf","toLowerCase","split","osInfo","process","env","NODE_ENV","clearEmptyKeysRecursively","obj","length","forEach","key","filter","x","isLocusServiceErrorCode","errorCode","code","charAt","isMeetingInfoServiceError","rawError","body","data","meetingInfo","url","includes","WBX_APP_API_URL","isBrowserMediaErrorName","errorName","BROWSER_MEDIA_ERROR_NAME_TO_CLIENT_ERROR_CODES_MAP","getBuildType","webClientDomain","prepareDiagnosticMetricItem","webex","item","origin","buildType","event","eventData","networkType","eventName","eventPayload","name","joinTimes","audioSetupDelay","videoSetupDelay","cdl","internal","newMetrics","callDiagnosticLatencies","meetingInfoReqResp","getMeetingInfoReqResp","clickToInterstitial","getClickToInterstitial","showInterstitialTime","getShowInterstitialTime","callInitJoinReq","getCallInitJoinReq","joinReqResp","getJoinReqResp","joinReqSentReceived","getJoinRespSentReceived","pageJmt","getPageJMT","interstitialToJoinOK","getInterstitialToJoinOK","totalJmt","getTotalJMT","clientJmt","getClientJMT","ICESetupTime","getICESetupTime","audioICESetupTime","getAudioICESetupTime","videoICESetupTime","getVideoICESetupTime","shareICESetupTime","getShareICESetupTime","localSDPGenRemoteSDPRecv","getLocalSDPGenRemoteSDPRecv","totalMediaJMT","getTotalMediaJMT","interstitialToMediaOKJMT","getInterstitialToMediaOKJMT","callInitMediaEngineReady","getCallInitMediaEngineReady","stayLobbyTime","getStayLobbyTime","joinRespRxStart","getAudioJoinRespRxStart","joinRespTxStart","getAudioJoinRespTxStart","getVideoJoinRespRxStart","getVideoJoinRespTxStart","setMetricTimings","options","json","JSON","parse","now","Date","toISOString","metrics","metric","originTime","triggered","sent","extractVersionMetadata","version","majorVersion","minorVersion"],"sources":["call-diagnostic-metrics.util.ts"],"sourcesContent":["/* eslint-disable valid-jsdoc */\nimport anonymize from 'ip-anonymize';\nimport util from 'util';\n\nimport {BrowserDetection} from '@webex/common';\nimport {isEmpty, merge} from 'lodash';\nimport {\n ClientEvent,\n Event,\n MediaQualityEventAudioSetupDelayPayload,\n MediaQualityEventVideoSetupDelayPayload,\n MetricEventNames,\n} from '../metrics.types';\nimport {BROWSER_MEDIA_ERROR_NAME_TO_CLIENT_ERROR_CODES_MAP, WBX_APP_API_URL} from './config';\n\nconst {getOSName, getOSVersion, getBrowserName, getBrowserVersion} = BrowserDetection();\n\nexport const anonymizeIPAddress = (localIp) => anonymize(localIp, 28, 96);\n\n/**\n * Returns a formated string of the user agent.\n *\n * @returns {string} formatted user agent information\n */\nexport const userAgentToString = ({clientName, webexVersion}) => {\n let userAgentOption;\n let browserInfo;\n const clientInfo = util.format('client=%s', `${clientName}`);\n\n if (\n ['chrome', 'firefox', 'msie', 'msedge', 'safari'].indexOf(getBrowserName().toLowerCase()) !== -1\n ) {\n browserInfo = util.format(\n 'browser=%s',\n `${getBrowserName().toLowerCase()}/${getBrowserVersion().split('.')[0]}`\n );\n }\n const osInfo = util.format('os=%s', `${getOSName()}/${getOSVersion().split('.')[0]}`);\n\n if (browserInfo) {\n userAgentOption = `(${browserInfo}`;\n }\n if (osInfo) {\n userAgentOption = userAgentOption\n ? `${userAgentOption}; ${clientInfo}; ${osInfo}`\n : `${clientInfo}; (${osInfo}`;\n }\n if (userAgentOption) {\n userAgentOption += ')';\n\n return util.format(\n 'webex-js-sdk/%s %s',\n `${process.env.NODE_ENV}-${webexVersion}`,\n userAgentOption\n );\n }\n\n return util.format('webex-js-sdk/%s', `${process.env.NODE_ENV}-${webexVersion}`);\n};\n\n/**\n * Iterates object recursively and removes any\n * property that returns isEmpty for it's associated value\n * isEmpty = implementation from Lodash.\n *\n * It modifies the object in place (mutable)\n *\n * @param obj - input\n * @returns\n */\nexport const clearEmptyKeysRecursively = (obj: any) => {\n // Check if the object is empty\n if (Object.keys(obj).length === 0) {\n return;\n }\n\n Object.keys(obj).forEach((key) => {\n if (\n (typeof obj[key] === 'object' || typeof obj[key] === 'string' || Array.isArray(obj[key])) &&\n isEmpty(obj[key])\n ) {\n delete obj[key];\n }\n if (Array.isArray(obj[key])) {\n obj[key] = [...obj[key].filter((x) => !!x)];\n }\n if (typeof obj[key] === 'object') {\n clearEmptyKeysRecursively(obj[key]);\n }\n });\n};\n\n/**\n * Locus error codes start with 2. The next three digits are the\n * HTTP status code related to the error code (like 400, 403, 502, etc.)\n * The remaining three digits are just an increasing integer.\n * If it is 7 digits and starts with a 2, it is locus.\n *\n * @param errorCode\n * @returns {boolean}\n */\nexport const isLocusServiceErrorCode = (errorCode: string | number) => {\n const code = `${errorCode}`;\n\n if (code.length === 7 && code.charAt(0) === '2') {\n return true;\n }\n\n return false;\n};\n\n/**\n * MeetingInfo errors sometimes has body.data.meetingInfo object\n * MeetingInfo errors come with a wbxappapi url\n *\n * @param {Object} rawError\n * @returns {boolean}\n */\nexport const isMeetingInfoServiceError = (rawError: any) => {\n if (rawError.body?.data?.meetingInfo || rawError.body?.url?.includes(WBX_APP_API_URL)) {\n return true;\n }\n\n return false;\n};\n\n/**\n * MDN Media Devices getUserMedia() method returns a name if it errs\n * Documentation can be found here: https://developer.mozilla.org/en-US/docs/Web/API/MediaDevices/getUserMedia\n *\n * @param errorCode\n * @returns\n */\nexport const isBrowserMediaErrorName = (errorName: any) => {\n if (BROWSER_MEDIA_ERROR_NAME_TO_CLIENT_ERROR_CODES_MAP[errorName]) {\n return true;\n }\n\n return false;\n};\n\n/**\n * @param webClientDomain\n * @returns\n */\nexport const getBuildType = (webClientDomain): Event['origin']['buildType'] => {\n if (\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 'prod';\n};\n\n/**\n * Prepare metric item for submission.\n * @param {Object} webex sdk instance\n * @param {Object} item\n * @returns {Object} prepared item\n */\nexport const prepareDiagnosticMetricItem = (webex: any, item: any) => {\n const origin: Partial<Event['origin']> = {\n buildType: getBuildType(item.event?.eventData?.webClientDomain),\n networkType: 'unknown',\n };\n\n // check event names and append latencies?\n const eventName = item.eventPayload?.event?.name as MetricEventNames;\n const joinTimes: ClientEvent['payload']['joinTimes'] = {};\n const audioSetupDelay: MediaQualityEventAudioSetupDelayPayload = {};\n const videoSetupDelay: MediaQualityEventVideoSetupDelayPayload = {};\n\n const cdl = webex.internal.newMetrics.callDiagnosticLatencies;\n\n switch (eventName) {\n case 'client.interstitial-window.launched':\n joinTimes.meetingInfoReqResp = cdl.getMeetingInfoReqResp();\n joinTimes.clickToInterstitial = cdl.getClickToInterstitial();\n break;\n\n case 'client.call.initiated':\n joinTimes.meetingInfoReqResp = cdl.getMeetingInfoReqResp();\n joinTimes.showInterstitialTime = cdl.getShowInterstitialTime();\n break;\n\n case 'client.locus.join.response':\n joinTimes.meetingInfoReqResp = cdl.getMeetingInfoReqResp();\n joinTimes.callInitJoinReq = cdl.getCallInitJoinReq();\n joinTimes.joinReqResp = cdl.getJoinReqResp();\n joinTimes.joinReqSentReceived = cdl.getJoinRespSentReceived();\n joinTimes.pageJmt = cdl.getPageJMT();\n joinTimes.clickToInterstitial = cdl.getClickToInterstitial();\n joinTimes.interstitialToJoinOK = cdl.getInterstitialToJoinOK();\n joinTimes.totalJmt = cdl.getTotalJMT();\n joinTimes.clientJmt = cdl.getClientJMT();\n break;\n\n case 'client.ice.end':\n joinTimes.ICESetupTime = cdl.getICESetupTime();\n joinTimes.audioICESetupTime = cdl.getAudioICESetupTime();\n joinTimes.videoICESetupTime = cdl.getVideoICESetupTime();\n joinTimes.shareICESetupTime = cdl.getShareICESetupTime();\n break;\n\n case 'client.media.rx.start':\n joinTimes.localSDPGenRemoteSDPRecv = cdl.getLocalSDPGenRemoteSDPRecv();\n break;\n\n case 'client.media-engine.ready':\n joinTimes.totalMediaJMT = cdl.getTotalMediaJMT();\n joinTimes.interstitialToMediaOKJMT = cdl.getInterstitialToMediaOKJMT();\n joinTimes.callInitMediaEngineReady = cdl.getCallInitMediaEngineReady();\n joinTimes.stayLobbyTime = cdl.getStayLobbyTime();\n break;\n\n case 'client.mediaquality.event':\n audioSetupDelay.joinRespRxStart = cdl.getAudioJoinRespRxStart();\n audioSetupDelay.joinRespTxStart = cdl.getAudioJoinRespTxStart();\n videoSetupDelay.joinRespRxStart = cdl.getVideoJoinRespRxStart();\n videoSetupDelay.joinRespTxStart = cdl.getVideoJoinRespTxStart();\n }\n\n if (!isEmpty(joinTimes)) {\n item.eventPayload.event = merge(item.eventPayload.event, {joinTimes});\n }\n\n if (!isEmpty(audioSetupDelay)) {\n item.eventPayload.event = merge(item.eventPayload.event, {audioSetupDelay});\n }\n\n if (!isEmpty(videoSetupDelay)) {\n item.eventPayload.event = merge(item.eventPayload.event, {videoSetupDelay});\n }\n\n item.eventPayload.origin = Object.assign(origin, item.eventPayload.origin);\n\n return item;\n};\n\n/**\n * Sets the originTime value(s) before the request/fetch.\n * This function is only useful if you are about to submit a metrics\n * request using pre-built fetch options;\n *\n * @param {any} options\n * @returns {any} the updated options object\n */\nexport const setMetricTimings = (options) => {\n if (options.body && options.json) {\n const body = JSON.parse(options.body);\n\n const now = new Date().toISOString();\n body.metrics?.forEach((metric) => {\n if (metric.eventPayload) {\n // The event will effectively be triggered and sent at the same time.\n // The existing triggered time is from when the options were built.\n metric.eventPayload.originTime = {\n triggered: now,\n sent: now,\n };\n }\n });\n options.body = JSON.stringify(body);\n }\n\n return options;\n};\n\nexport const extractVersionMetadata = (version: string) => {\n // extract major and minor version\n const [majorVersion, minorVersion] = version.split('.');\n\n return {\n majorVersion: parseInt(majorVersion, 10),\n minorVersion: parseInt(minorVersion, 10),\n };\n};\n"],"mappings":"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"}
1
+ {"version":3,"names":["BrowserDetection","getOSName","getOSVersion","getBrowserName","getBrowserVersion","anonymizeIPAddress","localIp","anonymize","userAgentToString","clientName","webexVersion","userAgentOption","browserInfo","clientInfo","util","format","indexOf","toLowerCase","split","osInfo","process","env","NODE_ENV","clearEmptyKeysRecursively","obj","length","forEach","key","filter","x","isLocusServiceErrorCode","errorCode","code","charAt","isMeetingInfoServiceError","rawError","body","data","meetingInfo","url","includes","WBX_APP_API_URL","isBrowserMediaErrorName","errorName","BROWSER_MEDIA_ERROR_NAME_TO_CLIENT_ERROR_CODES_MAP","getBuildType","webClientDomain","markAsTestEvent","prepareDiagnosticMetricItem","webex","item","origin","buildType","exports","eventPayload","event","eventData","networkType","eventName","name","joinTimes","audioSetupDelay","videoSetupDelay","cdl","internal","newMetrics","callDiagnosticLatencies","meetingInfoReqResp","getMeetingInfoReqResp","clickToInterstitial","getClickToInterstitial","showInterstitialTime","getShowInterstitialTime","callInitJoinReq","getCallInitJoinReq","joinReqResp","getJoinReqResp","joinReqSentReceived","getJoinRespSentReceived","pageJmt","getPageJMT","interstitialToJoinOK","getInterstitialToJoinOK","totalJmt","getTotalJMT","clientJmt","getClientJMT","ICESetupTime","getICESetupTime","audioICESetupTime","getAudioICESetupTime","videoICESetupTime","getVideoICESetupTime","shareICESetupTime","getShareICESetupTime","localSDPGenRemoteSDPRecv","getLocalSDPGenRemoteSDPRecv","totalMediaJMT","getTotalMediaJMT","interstitialToMediaOKJMT","getInterstitialToMediaOKJMT","callInitMediaEngineReady","getCallInitMediaEngineReady","stayLobbyTime","getStayLobbyTime","joinRespRxStart","getAudioJoinRespRxStart","joinRespTxStart","getAudioJoinRespTxStart","getVideoJoinRespRxStart","getVideoJoinRespTxStart","setMetricTimings","options","json","JSON","parse","now","Date","toISOString","metrics","metric","originTime","triggered","sent","extractVersionMetadata","version","majorVersion","minorVersion"],"sources":["call-diagnostic-metrics.util.ts"],"sourcesContent":["/* eslint-disable valid-jsdoc */\nimport anonymize from 'ip-anonymize';\nimport util from 'util';\n\nimport {BrowserDetection} from '@webex/common';\nimport {isEmpty, merge} from 'lodash';\nimport {\n ClientEvent,\n Event,\n MediaQualityEventAudioSetupDelayPayload,\n MediaQualityEventVideoSetupDelayPayload,\n MetricEventNames,\n} from '../metrics.types';\nimport {BROWSER_MEDIA_ERROR_NAME_TO_CLIENT_ERROR_CODES_MAP, WBX_APP_API_URL} from './config';\n\nconst {getOSName, getOSVersion, getBrowserName, getBrowserVersion} = BrowserDetection();\n\nexport const anonymizeIPAddress = (localIp) => anonymize(localIp, 28, 96);\n\n/**\n * Returns a formated string of the user agent.\n *\n * @returns {string} formatted user agent information\n */\nexport const userAgentToString = ({clientName, webexVersion}) => {\n let userAgentOption;\n let browserInfo;\n const clientInfo = util.format('client=%s', `${clientName}`);\n\n if (\n ['chrome', 'firefox', 'msie', 'msedge', 'safari'].indexOf(getBrowserName().toLowerCase()) !== -1\n ) {\n browserInfo = util.format(\n 'browser=%s',\n `${getBrowserName().toLowerCase()}/${getBrowserVersion().split('.')[0]}`\n );\n }\n const osInfo = util.format('os=%s', `${getOSName()}/${getOSVersion().split('.')[0]}`);\n\n if (browserInfo) {\n userAgentOption = `(${browserInfo}`;\n }\n if (osInfo) {\n userAgentOption = userAgentOption\n ? `${userAgentOption}; ${clientInfo}; ${osInfo}`\n : `${clientInfo}; (${osInfo}`;\n }\n if (userAgentOption) {\n userAgentOption += ')';\n\n return util.format(\n 'webex-js-sdk/%s %s',\n `${process.env.NODE_ENV}-${webexVersion}`,\n userAgentOption\n );\n }\n\n return util.format('webex-js-sdk/%s', `${process.env.NODE_ENV}-${webexVersion}`);\n};\n\n/**\n * Iterates object recursively and removes any\n * property that returns isEmpty for it's associated value\n * isEmpty = implementation from Lodash.\n *\n * It modifies the object in place (mutable)\n *\n * @param obj - input\n * @returns\n */\nexport const clearEmptyKeysRecursively = (obj: any) => {\n // Check if the object is empty\n if (Object.keys(obj).length === 0) {\n return;\n }\n\n Object.keys(obj).forEach((key) => {\n if (\n (typeof obj[key] === 'object' || typeof obj[key] === 'string' || Array.isArray(obj[key])) &&\n isEmpty(obj[key])\n ) {\n delete obj[key];\n }\n if (Array.isArray(obj[key])) {\n obj[key] = [...obj[key].filter((x) => !!x)];\n }\n if (typeof obj[key] === 'object') {\n clearEmptyKeysRecursively(obj[key]);\n }\n });\n};\n\n/**\n * Locus error codes start with 2. The next three digits are the\n * HTTP status code related to the error code (like 400, 403, 502, etc.)\n * The remaining three digits are just an increasing integer.\n * If it is 7 digits and starts with a 2, it is locus.\n *\n * @param errorCode\n * @returns {boolean}\n */\nexport const isLocusServiceErrorCode = (errorCode: string | number) => {\n const code = `${errorCode}`;\n\n if (code.length === 7 && code.charAt(0) === '2') {\n return true;\n }\n\n return false;\n};\n\n/**\n * MeetingInfo errors sometimes has body.data.meetingInfo object\n * MeetingInfo errors come with a wbxappapi url\n *\n * @param {Object} rawError\n * @returns {boolean}\n */\nexport const isMeetingInfoServiceError = (rawError: any) => {\n if (rawError.body?.data?.meetingInfo || rawError.body?.url?.includes(WBX_APP_API_URL)) {\n return true;\n }\n\n return false;\n};\n\n/**\n * MDN Media Devices getUserMedia() method returns a name if it errs\n * Documentation can be found here: https://developer.mozilla.org/en-US/docs/Web/API/MediaDevices/getUserMedia\n *\n * @param errorCode\n * @returns\n */\nexport const isBrowserMediaErrorName = (errorName: any) => {\n if (BROWSER_MEDIA_ERROR_NAME_TO_CLIENT_ERROR_CODES_MAP[errorName]) {\n return true;\n }\n\n return false;\n};\n\n/**\n * @param webClientDomain\n * @returns\n */\nexport const getBuildType = (\n webClientDomain,\n markAsTestEvent = false\n): Event['origin']['buildType'] => {\n // used temporary to test pre join in production without creating noise data, SPARK-468456\n if (markAsTestEvent) {\n return 'test';\n }\n\n if (\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 'prod';\n};\n\n/**\n * Prepare metric item for submission.\n * @param {Object} webex sdk instance\n * @param {Object} item\n * @returns {Object} prepared item\n */\nexport const prepareDiagnosticMetricItem = (webex: any, item: any) => {\n const origin: Partial<Event['origin']> = {\n buildType: exports.getBuildType(\n item.eventPayload?.event?.eventData?.webClientDomain,\n item.eventPayload?.event?.eventData?.markAsTestEvent\n ),\n networkType: 'unknown',\n };\n\n // check event names and append latencies?\n const eventName = item.eventPayload?.event?.name as MetricEventNames;\n const joinTimes: ClientEvent['payload']['joinTimes'] = {};\n const audioSetupDelay: MediaQualityEventAudioSetupDelayPayload = {};\n const videoSetupDelay: MediaQualityEventVideoSetupDelayPayload = {};\n\n const cdl = webex.internal.newMetrics.callDiagnosticLatencies;\n\n switch (eventName) {\n case 'client.interstitial-window.launched':\n joinTimes.meetingInfoReqResp = cdl.getMeetingInfoReqResp();\n joinTimes.clickToInterstitial = cdl.getClickToInterstitial();\n break;\n\n case 'client.call.initiated':\n joinTimes.meetingInfoReqResp = cdl.getMeetingInfoReqResp();\n joinTimes.showInterstitialTime = cdl.getShowInterstitialTime();\n break;\n\n case 'client.locus.join.response':\n joinTimes.meetingInfoReqResp = cdl.getMeetingInfoReqResp();\n joinTimes.callInitJoinReq = cdl.getCallInitJoinReq();\n joinTimes.joinReqResp = cdl.getJoinReqResp();\n joinTimes.joinReqSentReceived = cdl.getJoinRespSentReceived();\n joinTimes.pageJmt = cdl.getPageJMT();\n joinTimes.clickToInterstitial = cdl.getClickToInterstitial();\n joinTimes.interstitialToJoinOK = cdl.getInterstitialToJoinOK();\n joinTimes.totalJmt = cdl.getTotalJMT();\n joinTimes.clientJmt = cdl.getClientJMT();\n break;\n\n case 'client.ice.end':\n joinTimes.ICESetupTime = cdl.getICESetupTime();\n joinTimes.audioICESetupTime = cdl.getAudioICESetupTime();\n joinTimes.videoICESetupTime = cdl.getVideoICESetupTime();\n joinTimes.shareICESetupTime = cdl.getShareICESetupTime();\n break;\n\n case 'client.media.rx.start':\n joinTimes.localSDPGenRemoteSDPRecv = cdl.getLocalSDPGenRemoteSDPRecv();\n break;\n\n case 'client.media-engine.ready':\n joinTimes.totalMediaJMT = cdl.getTotalMediaJMT();\n joinTimes.interstitialToMediaOKJMT = cdl.getInterstitialToMediaOKJMT();\n joinTimes.callInitMediaEngineReady = cdl.getCallInitMediaEngineReady();\n joinTimes.stayLobbyTime = cdl.getStayLobbyTime();\n break;\n\n case 'client.mediaquality.event':\n audioSetupDelay.joinRespRxStart = cdl.getAudioJoinRespRxStart();\n audioSetupDelay.joinRespTxStart = cdl.getAudioJoinRespTxStart();\n videoSetupDelay.joinRespRxStart = cdl.getVideoJoinRespRxStart();\n videoSetupDelay.joinRespTxStart = cdl.getVideoJoinRespTxStart();\n }\n\n if (!isEmpty(joinTimes)) {\n item.eventPayload.event = merge(item.eventPayload.event, {joinTimes});\n }\n\n if (!isEmpty(audioSetupDelay)) {\n item.eventPayload.event = merge(item.eventPayload.event, {audioSetupDelay});\n }\n\n if (!isEmpty(videoSetupDelay)) {\n item.eventPayload.event = merge(item.eventPayload.event, {videoSetupDelay});\n }\n\n item.eventPayload.origin = Object.assign(origin, item.eventPayload.origin);\n\n return item;\n};\n\n/**\n * Sets the originTime value(s) before the request/fetch.\n * This function is only useful if you are about to submit a metrics\n * request using pre-built fetch options;\n *\n * @param {any} options\n * @returns {any} the updated options object\n */\nexport const setMetricTimings = (options) => {\n if (options.body && options.json) {\n const body = JSON.parse(options.body);\n\n const now = new Date().toISOString();\n body.metrics?.forEach((metric) => {\n if (metric.eventPayload) {\n // The event will effectively be triggered and sent at the same time.\n // The existing triggered time is from when the options were built.\n metric.eventPayload.originTime = {\n triggered: now,\n sent: now,\n };\n }\n });\n options.body = JSON.stringify(body);\n }\n\n return options;\n};\n\nexport const extractVersionMetadata = (version: string) => {\n // extract major and minor version\n const [majorVersion, minorVersion] = version.split('.');\n\n return {\n majorVersion: parseInt(majorVersion, 10),\n minorVersion: parseInt(minorVersion, 10),\n };\n};\n"],"mappings":"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"}
package/dist/index.js CHANGED
@@ -8,7 +8,7 @@ var _interopRequireDefault = require("@babel/runtime-corejs2/helpers/interopRequ
8
8
  _Object$defineProperty(exports, "__esModule", {
9
9
  value: true
10
10
  });
11
- exports.CALL_DIAGNOSTIC_CONFIG = void 0;
11
+ exports.CallDiagnosticUtils = exports.CALL_DIAGNOSTIC_CONFIG = void 0;
12
12
  _Object$defineProperty(exports, "NewMetrics", {
13
13
  enumerable: true,
14
14
  get: function get() {
@@ -43,6 +43,8 @@ var Utils = _interopRequireWildcard(require("./utils"));
43
43
  exports.Utils = Utils;
44
44
  var CALL_DIAGNOSTIC_CONFIG = _interopRequireWildcard(require("./call-diagnostic/config"));
45
45
  exports.CALL_DIAGNOSTIC_CONFIG = CALL_DIAGNOSTIC_CONFIG;
46
+ var CallDiagnosticUtils = _interopRequireWildcard(require("./call-diagnostic/call-diagnostic-metrics.util"));
47
+ exports.CallDiagnosticUtils = CallDiagnosticUtils;
46
48
  function _getRequireWildcardCache(nodeInterop) { if (typeof _WeakMap !== "function") return null; var cacheBabelInterop = new _WeakMap(); var cacheNodeInterop = new _WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
47
49
  function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || _typeof(obj) !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = _Object$defineProperty && _Object$getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? _Object$getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { _Object$defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
48
50
  /*!
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"names":["registerInternalPlugin","Metrics","config","NewMetrics"],"sources":["index.ts"],"sourcesContent":["/*!\n * Copyright (c) 2015-2020 Cisco Systems, Inc. See LICENSE file.\n */\n\nimport '@webex/internal-plugin-device';\n\nimport {registerInternalPlugin} from '@webex/webex-core';\n\nimport Metrics from './metrics';\nimport config from './config';\nimport NewMetrics from './new-metrics';\nimport * as Utils from './utils';\nimport {\n ClientEvent,\n ClientEventLeaveReason,\n SubmitBehavioralEvent,\n SubmitClientEvent,\n SubmitInternalEvent,\n SubmitOperationalEvent,\n SubmitMQE,\n} from './metrics.types';\nimport * as CALL_DIAGNOSTIC_CONFIG from './call-diagnostic/config';\n\nregisterInternalPlugin('metrics', Metrics, {\n config,\n});\n\nregisterInternalPlugin('newMetrics', NewMetrics, {\n config,\n});\n\nexport {default, getOSNameInternal} from './metrics';\nexport {config, CALL_DIAGNOSTIC_CONFIG, NewMetrics, Utils};\nexport type {\n ClientEvent,\n ClientEventLeaveReason,\n SubmitBehavioralEvent,\n SubmitClientEvent,\n SubmitInternalEvent,\n SubmitMQE,\n SubmitOperationalEvent,\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAIA;AAEA;AAEA;AACA;AACA;AACA;AAAiC;AAUjC;AAAmE;AAAA;AAAA;AArBnE;AACA;AACA;;AAqBA,IAAAA,iCAAsB,EAAC,SAAS,EAAEC,gBAAO,EAAE;EACzCC,MAAM,EAANA;AACF,CAAC,CAAC;AAEF,IAAAF,iCAAsB,EAAC,YAAY,EAAEG,mBAAU,EAAE;EAC/CD,MAAM,EAANA;AACF,CAAC,CAAC"}
1
+ {"version":3,"names":["registerInternalPlugin","Metrics","config","NewMetrics"],"sources":["index.ts"],"sourcesContent":["/*!\n * Copyright (c) 2015-2020 Cisco Systems, Inc. See LICENSE file.\n */\n\nimport '@webex/internal-plugin-device';\n\nimport {registerInternalPlugin} from '@webex/webex-core';\n\nimport Metrics from './metrics';\nimport config from './config';\nimport NewMetrics from './new-metrics';\nimport * as Utils from './utils';\nimport {\n ClientEvent,\n ClientEventLeaveReason,\n SubmitBehavioralEvent,\n SubmitClientEvent,\n SubmitInternalEvent,\n SubmitOperationalEvent,\n SubmitMQE,\n} from './metrics.types';\nimport * as CALL_DIAGNOSTIC_CONFIG from './call-diagnostic/config';\nimport * as CallDiagnosticUtils from './call-diagnostic/call-diagnostic-metrics.util';\n\nregisterInternalPlugin('metrics', Metrics, {\n config,\n});\n\nregisterInternalPlugin('newMetrics', NewMetrics, {\n config,\n});\n\nexport {default, getOSNameInternal} from './metrics';\nexport {config, CALL_DIAGNOSTIC_CONFIG, NewMetrics, Utils, CallDiagnosticUtils};\nexport type {\n ClientEvent,\n ClientEventLeaveReason,\n SubmitBehavioralEvent,\n SubmitClientEvent,\n SubmitInternalEvent,\n SubmitMQE,\n SubmitOperationalEvent,\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAIA;AAEA;AAEA;AACA;AACA;AACA;AAAiC;AAUjC;AAAmE;AACnE;AAAsF;AAAA;AAAA;AAtBtF;AACA;AACA;;AAsBA,IAAAA,iCAAsB,EAAC,SAAS,EAAEC,gBAAO,EAAE;EACzCC,MAAM,EAANA;AACF,CAAC,CAAC;AAEF,IAAAF,iCAAsB,EAAC,YAAY,EAAEG,mBAAU,EAAE;EAC/CD,MAAM,EAANA;AACF,CAAC,CAAC"}
package/dist/metrics.js CHANGED
@@ -161,7 +161,7 @@ var Metrics = _webexCore.WebexPlugin.extend({
161
161
  });
162
162
  });
163
163
  },
164
- version: "3.0.0-beta.232"
164
+ version: "3.0.0-beta.234"
165
165
  });
166
166
  var _default = Metrics;
167
167
  exports.default = _default;
@@ -8,8 +8,8 @@ _Object$defineProperty(exports, "__esModule", {
8
8
  });
9
9
  exports.default = void 0;
10
10
  var _regenerator = _interopRequireDefault(require("@babel/runtime-corejs2/regenerator"));
11
- var _stringify = _interopRequireDefault(require("@babel/runtime-corejs2/core-js/json/stringify"));
12
11
  var _promise = _interopRequireDefault(require("@babel/runtime-corejs2/core-js/promise"));
12
+ var _stringify = _interopRequireDefault(require("@babel/runtime-corejs2/core-js/json/stringify"));
13
13
  var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/asyncToGenerator"));
14
14
  var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/classCallCheck"));
15
15
  var _createClass2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/createClass"));
@@ -170,6 +170,11 @@ var Metrics = /*#__PURE__*/function (_WebexPlugin) {
170
170
  var name = _ref6.name,
171
171
  payload = _ref6.payload,
172
172
  options = _ref6.options;
173
+ if (!this.callDiagnosticLatencies || !this.callDiagnosticMetrics) {
174
+ // @ts-ignore
175
+ this.webex.logger.log("NewMetrics: @submitClientEvent. Attempted to submit before webex.ready. Event name: ".concat(name));
176
+ return _promise.default.resolve();
177
+ }
173
178
  this.callDiagnosticLatencies.saveTimestamp({
174
179
  key: name,
175
180
  options: {
@@ -1 +1 @@
1
- {"version":3,"names":["Metrics","args","onReady","webex","once","callDiagnosticMetrics","CallDiagnosticMetrics","parent","callDiagnosticLatencies","CallDiagnosticLatencies","name","payload","options","clearTimestamps","saveTimestamp","key","Error","submitMQE","meetingId","submitClientEvent","preLoginId","request","method","api","resource","headers","authorization","body","metrics","then","res","logger","log","catch","err","error","generateCommonErrorMetadata","reject","qs","alias","buildClientEventFetchRequestOptions","setTimingsAndFetch","setMetricTimings","WebexPlugin"],"sources":["new-metrics.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/no-unused-vars */\n/* eslint-disable class-methods-use-this */\n/* eslint-disable valid-jsdoc */\n\n// @ts-ignore\nimport {WebexPlugin} from '@webex/webex-core';\n\nimport CallDiagnosticMetrics from './call-diagnostic/call-diagnostic-metrics';\nimport {\n RecursivePartial,\n ClientEvent,\n FeatureEvent,\n BehavioralEvent,\n OperationalEvent,\n MediaQualityEvent,\n InternalEvent,\n SubmitClientEventOptions,\n} from './metrics.types';\nimport CallDiagnosticLatencies from './call-diagnostic/call-diagnostic-metrics-latencies';\nimport {setMetricTimings} from './call-diagnostic/call-diagnostic-metrics.util';\nimport {generateCommonErrorMetadata} from './utils';\n\n/**\n * Metrics plugin to centralize all types of metrics.\n * @class\n */\nclass Metrics extends WebexPlugin {\n // eslint-disable-next-line no-use-before-define\n static instance: Metrics;\n\n // Call Diagnostic latencies\n callDiagnosticLatencies: CallDiagnosticLatencies;\n // Helper classes to handle the different types of metrics\n callDiagnosticMetrics: CallDiagnosticMetrics;\n\n /**\n * Constructor\n * @param args\n * @constructor\n * @private\n * @returns\n */\n constructor(...args) {\n super(...args);\n\n this.onReady();\n }\n\n /**\n * On Ready\n */\n private onReady() {\n // @ts-ignore\n this.webex.once('ready', () => {\n // @ts-ignore\n this.callDiagnosticMetrics = new CallDiagnosticMetrics({}, {parent: this.webex});\n // @ts-ignore\n this.callDiagnosticLatencies = new CallDiagnosticLatencies({}, {parent: this.webex});\n });\n }\n\n /**\n * Used for internal purposes only\n * @param args\n */\n submitInternalEvent({\n name,\n payload,\n options,\n }: {\n name: InternalEvent['name'];\n payload?: RecursivePartial<InternalEvent['payload']>;\n options?: any;\n }) {\n if (name === 'internal.reset.join.latencies') {\n this.callDiagnosticLatencies.clearTimestamps();\n } else {\n this.callDiagnosticLatencies.saveTimestamp({key: name});\n }\n }\n\n /**\n * Behavioral event\n * @param args\n */\n submitBehavioralEvent({\n name,\n payload,\n options,\n }: {\n name: BehavioralEvent['name'];\n payload?: RecursivePartial<BehavioralEvent['payload']>;\n options?: any;\n }) {\n this.callDiagnosticLatencies.saveTimestamp({key: name});\n throw new Error('Not implemented.');\n }\n\n /**\n * Operational event\n * @param args\n */\n submitOperationalEvent({\n name,\n payload,\n options,\n }: {\n name: OperationalEvent['name'];\n payload?: RecursivePartial<OperationalEvent['payload']>;\n options?: any;\n }) {\n throw new Error('Not implemented.');\n }\n\n /**\n * Call Analyzer: Media Quality Event\n * @param args\n */\n submitMQE({\n name,\n payload,\n options,\n }: {\n name: MediaQualityEvent['name'];\n payload: RecursivePartial<MediaQualityEvent['payload']> & {\n intervals: MediaQualityEvent['payload']['intervals'];\n };\n options: any;\n }) {\n this.callDiagnosticLatencies.saveTimestamp({key: name});\n this.callDiagnosticMetrics.submitMQE({name, payload, options});\n }\n\n /**\n * Call Analyzer: Feature Usage Event\n * @param args\n */\n submitFeatureEvent({\n name,\n payload,\n options,\n }: {\n name: FeatureEvent['name'];\n payload?: RecursivePartial<FeatureEvent['payload']>;\n options: any;\n }) {\n throw new Error('Not implemented.');\n }\n\n /**\n * Call Analyzer: Client Event\n * @public\n * @param args\n */\n public submitClientEvent({\n name,\n payload,\n options,\n }: {\n name: ClientEvent['name'];\n payload?: RecursivePartial<ClientEvent['payload']>;\n options?: SubmitClientEventOptions;\n }): Promise<any> {\n this.callDiagnosticLatencies.saveTimestamp({\n key: name,\n options: {meetingId: options?.meetingId},\n });\n\n return this.callDiagnosticMetrics.submitClientEvent({name, payload, options});\n }\n\n /**\n * Submit a pre-login metric to clientmetrics\n * @public\n * @param payload\n * @param preLoginId - pre-login ID of user\n * @returns\n */\n public postPreLoginMetric(payload: any, preLoginId: string): Promise<any> {\n // @ts-ignore\n return this.webex\n .request({\n method: 'POST',\n api: 'metrics',\n resource: 'clientmetrics-prelogin',\n headers: {\n authorization: false,\n 'x-prelogin-userid': preLoginId,\n },\n body: {\n metrics: [payload],\n },\n })\n .then((res) => {\n // @ts-ignore\n this.webex.logger.log(\n `NewMetrics: @postPreLoginMetric. Request successful:`,\n `res: ${JSON.stringify(res)}`\n );\n\n return res;\n })\n .catch((err) => {\n // @ts-ignore\n this.logger.error(\n `NewMetrics: @postPreLoginMetric. Request failed:`,\n `err: ${generateCommonErrorMetadata(err)}`\n );\n\n return Promise.reject(err);\n });\n }\n\n /**\n * Issue request to alias a user's pre-login ID with their CI UUID\n * @param {string} preLoginId\n * @returns {Object} HttpResponse object\n */\n public clientMetricsAliasUser(preLoginId: string) {\n // @ts-ignore\n return this.webex\n .request({\n method: 'POST',\n api: 'metrics',\n resource: 'clientmetrics',\n headers: {\n 'x-prelogin-userid': preLoginId,\n },\n body: {},\n qs: {\n alias: true,\n },\n })\n .then((res) => {\n // @ts-ignore\n this.webex.logger.log(\n `NewMetrics: @clientMetricsAliasUser. Request successful:`,\n `res: ${JSON.stringify(res)}`\n );\n\n return res;\n })\n .catch((err) => {\n // @ts-ignore\n this.logger.error(\n `NewMetrics: @clientMetricsAliasUser. Request failed:`,\n `err: ${generateCommonErrorMetadata(err)}`\n );\n\n return Promise.reject(err);\n });\n }\n\n /**\n * Returns a promise that will resolve to fetch options for submitting a metric.\n *\n * This is to support quickly submitting metrics when the browser/tab is closing.\n * Calling submitClientEvent will not work because there some async steps that will\n * not complete before the browser is closed. Instead, we pre-gather all the\n * information/options needed for the request(s), and then simply and quickly\n * fire the fetch(es) when beforeUnload is triggered.\n *\n * We must use fetch instead of request because fetch has a keepalive option that\n * allows the request it to outlive the page.\n *\n * Note: the timings values will be wrong, but setMetricTimingsAndFetch() will\n * properly adjust them before submitting.\n *\n * @public\n * @param {Object} arg\n * @param {String} arg.name - event name\n * @param {Object} arg.payload - event payload\n * @param {Object} arg.options - other options\n * @returns {Promise} promise that resolves to options to be used with fetch\n */\n public async buildClientEventFetchRequestOptions({\n name,\n payload,\n options,\n }: {\n name: ClientEvent['name'];\n payload?: RecursivePartial<ClientEvent['payload']>;\n options?: SubmitClientEventOptions;\n }): Promise<any> {\n return this.callDiagnosticMetrics.buildClientEventFetchRequestOptions({\n name,\n payload,\n options,\n });\n }\n\n /**\n * Submits a metric from pre-built request options via the fetch API. Updates\n * the \"$timings\" and \"originTime\" values to Date.now() since the existing times\n * were set when the options were built (not submitted).\n\n * @param {any} options - the pre-built request options for submitting a metric\n * @returns {Promise} promise that resolves to the response object\n */\n public setMetricTimingsAndFetch(options: any): Promise<any> {\n // @ts-ignore\n return this.webex.setTimingsAndFetch(setMetricTimings(options));\n }\n}\n\nexport default Metrics;\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAKA;AAEA;AAWA;AACA;AACA;AAAoD;AAAA;AAEpD;AACA;AACA;AACA;AAHA,IAIMA,OAAO;EAAA;EAAA;EACX;;EAGA;;EAEA;;EAGA;AACF;AACA;AACA;AACA;AACA;AACA;EACE,mBAAqB;IAAA;IAAA;IAAA,kCAANC,IAAI;MAAJA,IAAI;IAAA;IACjB,gDAASA,IAAI;IAAE;IAAA;IAEf,MAAKC,OAAO,EAAE;IAAC;EACjB;;EAEA;AACF;AACA;EAFE;IAAA;IAAA,OAGA,mBAAkB;MAAA;MAChB;MACA,IAAI,CAACC,KAAK,CAACC,IAAI,CAAC,OAAO,EAAE,YAAM;QAC7B;QACA,MAAI,CAACC,qBAAqB,GAAG,IAAIC,8BAAqB,CAAC,CAAC,CAAC,EAAE;UAACC,MAAM,EAAE,MAAI,CAACJ;QAAK,CAAC,CAAC;QAChF;QACA,MAAI,CAACK,uBAAuB,GAAG,IAAIC,uCAAuB,CAAC,CAAC,CAAC,EAAE;UAACF,MAAM,EAAE,MAAI,CAACJ;QAAK,CAAC,CAAC;MACtF,CAAC,CAAC;IACJ;;IAEA;AACF;AACA;AACA;EAHE;IAAA;IAAA,OAIA,mCAQG;MAAA,IAPDO,IAAI,QAAJA,IAAI;QACJC,OAAO,QAAPA,OAAO;QACPC,OAAO,QAAPA,OAAO;MAMP,IAAIF,IAAI,KAAK,+BAA+B,EAAE;QAC5C,IAAI,CAACF,uBAAuB,CAACK,eAAe,EAAE;MAChD,CAAC,MAAM;QACL,IAAI,CAACL,uBAAuB,CAACM,aAAa,CAAC;UAACC,GAAG,EAAEL;QAAI,CAAC,CAAC;MACzD;IACF;;IAEA;AACF;AACA;AACA;EAHE;IAAA;IAAA,OAIA,sCAQG;MAAA,IAPDA,IAAI,SAAJA,IAAI;QACJC,OAAO,SAAPA,OAAO;QACPC,OAAO,SAAPA,OAAO;MAMP,IAAI,CAACJ,uBAAuB,CAACM,aAAa,CAAC;QAACC,GAAG,EAAEL;MAAI,CAAC,CAAC;MACvD,MAAM,IAAIM,KAAK,CAAC,kBAAkB,CAAC;IACrC;;IAEA;AACF;AACA;AACA;EAHE;IAAA;IAAA,OAIA,uCAQG;MAAA,IAPDN,IAAI,SAAJA,IAAI;QACJC,OAAO,SAAPA,OAAO;QACPC,OAAO,SAAPA,OAAO;MAMP,MAAM,IAAII,KAAK,CAAC,kBAAkB,CAAC;IACrC;;IAEA;AACF;AACA;AACA;EAHE;IAAA;IAAA,OAIA,0BAUG;MAAA,IATDN,IAAI,SAAJA,IAAI;QACJC,OAAO,SAAPA,OAAO;QACPC,OAAO,SAAPA,OAAO;MAQP,IAAI,CAACJ,uBAAuB,CAACM,aAAa,CAAC;QAACC,GAAG,EAAEL;MAAI,CAAC,CAAC;MACvD,IAAI,CAACL,qBAAqB,CAACY,SAAS,CAAC;QAACP,IAAI,EAAJA,IAAI;QAAEC,OAAO,EAAPA,OAAO;QAAEC,OAAO,EAAPA;MAAO,CAAC,CAAC;IAChE;;IAEA;AACF;AACA;AACA;EAHE;IAAA;IAAA,OAIA,mCAQG;MAAA,IAPDF,IAAI,SAAJA,IAAI;QACJC,OAAO,SAAPA,OAAO;QACPC,OAAO,SAAPA,OAAO;MAMP,MAAM,IAAII,KAAK,CAAC,kBAAkB,CAAC;IACrC;;IAEA;AACF;AACA;AACA;AACA;EAJE;IAAA;IAAA,OAKA,kCAQiB;MAAA,IAPfN,IAAI,SAAJA,IAAI;QACJC,OAAO,SAAPA,OAAO;QACPC,OAAO,SAAPA,OAAO;MAMP,IAAI,CAACJ,uBAAuB,CAACM,aAAa,CAAC;QACzCC,GAAG,EAAEL,IAAI;QACTE,OAAO,EAAE;UAACM,SAAS,EAAEN,OAAO,aAAPA,OAAO,uBAAPA,OAAO,CAAEM;QAAS;MACzC,CAAC,CAAC;MAEF,OAAO,IAAI,CAACb,qBAAqB,CAACc,iBAAiB,CAAC;QAACT,IAAI,EAAJA,IAAI;QAAEC,OAAO,EAAPA,OAAO;QAAEC,OAAO,EAAPA;MAAO,CAAC,CAAC;IAC/E;;IAEA;AACF;AACA;AACA;AACA;AACA;AACA;EANE;IAAA;IAAA,OAOA,4BAA0BD,OAAY,EAAES,UAAkB,EAAgB;MAAA;MACxE;MACA,OAAO,IAAI,CAACjB,KAAK,CACdkB,OAAO,CAAC;QACPC,MAAM,EAAE,MAAM;QACdC,GAAG,EAAE,SAAS;QACdC,QAAQ,EAAE,wBAAwB;QAClCC,OAAO,EAAE;UACPC,aAAa,EAAE,KAAK;UACpB,mBAAmB,EAAEN;QACvB,CAAC;QACDO,IAAI,EAAE;UACJC,OAAO,EAAE,CAACjB,OAAO;QACnB;MACF,CAAC,CAAC,CACDkB,IAAI,CAAC,UAACC,GAAG,EAAK;QACb;QACA,MAAI,CAAC3B,KAAK,CAAC4B,MAAM,CAACC,GAAG,wEAEX,wBAAeF,GAAG,CAAC,EAC5B;QAED,OAAOA,GAAG;MACZ,CAAC,CAAC,CACDG,KAAK,CAAC,UAACC,GAAG,EAAK;QACd;QACA,MAAI,CAACH,MAAM,CAACI,KAAK,oEAEP,IAAAC,kCAA2B,EAACF,GAAG,CAAC,EACzC;QAED,OAAO,iBAAQG,MAAM,CAACH,GAAG,CAAC;MAC5B,CAAC,CAAC;IACN;;IAEA;AACF;AACA;AACA;AACA;EAJE;IAAA;IAAA,OAKA,gCAA8Bd,UAAkB,EAAE;MAAA;MAChD;MACA,OAAO,IAAI,CAACjB,KAAK,CACdkB,OAAO,CAAC;QACPC,MAAM,EAAE,MAAM;QACdC,GAAG,EAAE,SAAS;QACdC,QAAQ,EAAE,eAAe;QACzBC,OAAO,EAAE;UACP,mBAAmB,EAAEL;QACvB,CAAC;QACDO,IAAI,EAAE,CAAC,CAAC;QACRW,EAAE,EAAE;UACFC,KAAK,EAAE;QACT;MACF,CAAC,CAAC,CACDV,IAAI,CAAC,UAACC,GAAG,EAAK;QACb;QACA,MAAI,CAAC3B,KAAK,CAAC4B,MAAM,CAACC,GAAG,4EAEX,wBAAeF,GAAG,CAAC,EAC5B;QAED,OAAOA,GAAG;MACZ,CAAC,CAAC,CACDG,KAAK,CAAC,UAACC,GAAG,EAAK;QACd;QACA,MAAI,CAACH,MAAM,CAACI,KAAK,wEAEP,IAAAC,kCAA2B,EAACF,GAAG,CAAC,EACzC;QAED,OAAO,iBAAQG,MAAM,CAACH,GAAG,CAAC;MAC5B,CAAC,CAAC;IACN;;IAEA;AACF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;EArBE;IAAA;IAAA;MAAA,mHAsBA;QAAA;QAAA;UAAA;YAAA;cACExB,IAAI,SAAJA,IAAI,EACJC,OAAO,SAAPA,OAAO,EACPC,OAAO,SAAPA,OAAO;cAAA,iCAMA,IAAI,CAACP,qBAAqB,CAACmC,mCAAmC,CAAC;gBACpE9B,IAAI,EAAJA,IAAI;gBACJC,OAAO,EAAPA,OAAO;gBACPC,OAAO,EAAPA;cACF,CAAC,CAAC;YAAA;YAAA;cAAA;UAAA;QAAA;MAAA,CACH;MAAA;QAAA;MAAA;MAAA;IAAA;IAED;AACF;AACA;AACA;AACA;AACA;AACA;EANE;IAAA;IAAA,OAQA,kCAAgCA,OAAY,EAAgB;MAC1D;MACA,OAAO,IAAI,CAACT,KAAK,CAACsC,kBAAkB,CAAC,IAAAC,wCAAgB,EAAC9B,OAAO,CAAC,CAAC;IACjE;EAAC;EAAA;AAAA,EApRmB+B,sBAAW;AAAA,8BAA3B3C,OAAO;AAAA,eAuREA,OAAO;AAAA"}
1
+ {"version":3,"names":["Metrics","args","onReady","webex","once","callDiagnosticMetrics","CallDiagnosticMetrics","parent","callDiagnosticLatencies","CallDiagnosticLatencies","name","payload","options","clearTimestamps","saveTimestamp","key","Error","submitMQE","logger","log","resolve","meetingId","submitClientEvent","preLoginId","request","method","api","resource","headers","authorization","body","metrics","then","res","catch","err","error","generateCommonErrorMetadata","reject","qs","alias","buildClientEventFetchRequestOptions","setTimingsAndFetch","setMetricTimings","WebexPlugin"],"sources":["new-metrics.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/no-unused-vars */\n/* eslint-disable class-methods-use-this */\n/* eslint-disable valid-jsdoc */\n\n// @ts-ignore\nimport {WebexPlugin} from '@webex/webex-core';\n\nimport CallDiagnosticMetrics from './call-diagnostic/call-diagnostic-metrics';\nimport {\n RecursivePartial,\n ClientEvent,\n FeatureEvent,\n BehavioralEvent,\n OperationalEvent,\n MediaQualityEvent,\n InternalEvent,\n SubmitClientEventOptions,\n} from './metrics.types';\nimport CallDiagnosticLatencies from './call-diagnostic/call-diagnostic-metrics-latencies';\nimport {setMetricTimings} from './call-diagnostic/call-diagnostic-metrics.util';\nimport {generateCommonErrorMetadata} from './utils';\n\n/**\n * Metrics plugin to centralize all types of metrics.\n * @class\n */\nclass Metrics extends WebexPlugin {\n // eslint-disable-next-line no-use-before-define\n static instance: Metrics;\n\n // Call Diagnostic latencies\n callDiagnosticLatencies: CallDiagnosticLatencies;\n // Helper classes to handle the different types of metrics\n callDiagnosticMetrics: CallDiagnosticMetrics;\n\n /**\n * Constructor\n * @param args\n * @constructor\n * @private\n * @returns\n */\n constructor(...args) {\n super(...args);\n\n this.onReady();\n }\n\n /**\n * On Ready\n */\n private onReady() {\n // @ts-ignore\n this.webex.once('ready', () => {\n // @ts-ignore\n this.callDiagnosticMetrics = new CallDiagnosticMetrics({}, {parent: this.webex});\n // @ts-ignore\n this.callDiagnosticLatencies = new CallDiagnosticLatencies({}, {parent: this.webex});\n });\n }\n\n /**\n * Used for internal purposes only\n * @param args\n */\n submitInternalEvent({\n name,\n payload,\n options,\n }: {\n name: InternalEvent['name'];\n payload?: RecursivePartial<InternalEvent['payload']>;\n options?: any;\n }) {\n if (name === 'internal.reset.join.latencies') {\n this.callDiagnosticLatencies.clearTimestamps();\n } else {\n this.callDiagnosticLatencies.saveTimestamp({key: name});\n }\n }\n\n /**\n * Behavioral event\n * @param args\n */\n submitBehavioralEvent({\n name,\n payload,\n options,\n }: {\n name: BehavioralEvent['name'];\n payload?: RecursivePartial<BehavioralEvent['payload']>;\n options?: any;\n }) {\n this.callDiagnosticLatencies.saveTimestamp({key: name});\n throw new Error('Not implemented.');\n }\n\n /**\n * Operational event\n * @param args\n */\n submitOperationalEvent({\n name,\n payload,\n options,\n }: {\n name: OperationalEvent['name'];\n payload?: RecursivePartial<OperationalEvent['payload']>;\n options?: any;\n }) {\n throw new Error('Not implemented.');\n }\n\n /**\n * Call Analyzer: Media Quality Event\n * @param args\n */\n submitMQE({\n name,\n payload,\n options,\n }: {\n name: MediaQualityEvent['name'];\n payload: RecursivePartial<MediaQualityEvent['payload']> & {\n intervals: MediaQualityEvent['payload']['intervals'];\n };\n options: any;\n }) {\n this.callDiagnosticLatencies.saveTimestamp({key: name});\n this.callDiagnosticMetrics.submitMQE({name, payload, options});\n }\n\n /**\n * Call Analyzer: Feature Usage Event\n * @param args\n */\n submitFeatureEvent({\n name,\n payload,\n options,\n }: {\n name: FeatureEvent['name'];\n payload?: RecursivePartial<FeatureEvent['payload']>;\n options: any;\n }) {\n throw new Error('Not implemented.');\n }\n\n /**\n * Call Analyzer: Client Event\n * @public\n * @param args\n */\n public submitClientEvent({\n name,\n payload,\n options,\n }: {\n name: ClientEvent['name'];\n payload?: RecursivePartial<ClientEvent['payload']>;\n options?: SubmitClientEventOptions;\n }): Promise<any> {\n if (!this.callDiagnosticLatencies || !this.callDiagnosticMetrics) {\n // @ts-ignore\n this.webex.logger.log(\n `NewMetrics: @submitClientEvent. Attempted to submit before webex.ready. Event name: ${name}`\n );\n\n return Promise.resolve();\n }\n this.callDiagnosticLatencies.saveTimestamp({\n key: name,\n options: {meetingId: options?.meetingId},\n });\n\n return this.callDiagnosticMetrics.submitClientEvent({name, payload, options});\n }\n\n /**\n * Submit a pre-login metric to clientmetrics\n * @public\n * @param payload\n * @param preLoginId - pre-login ID of user\n * @returns\n */\n public postPreLoginMetric(payload: any, preLoginId: string): Promise<any> {\n // @ts-ignore\n return this.webex\n .request({\n method: 'POST',\n api: 'metrics',\n resource: 'clientmetrics-prelogin',\n headers: {\n authorization: false,\n 'x-prelogin-userid': preLoginId,\n },\n body: {\n metrics: [payload],\n },\n })\n .then((res) => {\n // @ts-ignore\n this.webex.logger.log(\n `NewMetrics: @postPreLoginMetric. Request successful:`,\n `res: ${JSON.stringify(res)}`\n );\n\n return res;\n })\n .catch((err) => {\n // @ts-ignore\n this.logger.error(\n `NewMetrics: @postPreLoginMetric. Request failed:`,\n `err: ${generateCommonErrorMetadata(err)}`\n );\n\n return Promise.reject(err);\n });\n }\n\n /**\n * Issue request to alias a user's pre-login ID with their CI UUID\n * @param {string} preLoginId\n * @returns {Object} HttpResponse object\n */\n public clientMetricsAliasUser(preLoginId: string) {\n // @ts-ignore\n return this.webex\n .request({\n method: 'POST',\n api: 'metrics',\n resource: 'clientmetrics',\n headers: {\n 'x-prelogin-userid': preLoginId,\n },\n body: {},\n qs: {\n alias: true,\n },\n })\n .then((res) => {\n // @ts-ignore\n this.webex.logger.log(\n `NewMetrics: @clientMetricsAliasUser. Request successful:`,\n `res: ${JSON.stringify(res)}`\n );\n\n return res;\n })\n .catch((err) => {\n // @ts-ignore\n this.logger.error(\n `NewMetrics: @clientMetricsAliasUser. Request failed:`,\n `err: ${generateCommonErrorMetadata(err)}`\n );\n\n return Promise.reject(err);\n });\n }\n\n /**\n * Returns a promise that will resolve to fetch options for submitting a metric.\n *\n * This is to support quickly submitting metrics when the browser/tab is closing.\n * Calling submitClientEvent will not work because there some async steps that will\n * not complete before the browser is closed. Instead, we pre-gather all the\n * information/options needed for the request(s), and then simply and quickly\n * fire the fetch(es) when beforeUnload is triggered.\n *\n * We must use fetch instead of request because fetch has a keepalive option that\n * allows the request it to outlive the page.\n *\n * Note: the timings values will be wrong, but setMetricTimingsAndFetch() will\n * properly adjust them before submitting.\n *\n * @public\n * @param {Object} arg\n * @param {String} arg.name - event name\n * @param {Object} arg.payload - event payload\n * @param {Object} arg.options - other options\n * @returns {Promise} promise that resolves to options to be used with fetch\n */\n public async buildClientEventFetchRequestOptions({\n name,\n payload,\n options,\n }: {\n name: ClientEvent['name'];\n payload?: RecursivePartial<ClientEvent['payload']>;\n options?: SubmitClientEventOptions;\n }): Promise<any> {\n return this.callDiagnosticMetrics.buildClientEventFetchRequestOptions({\n name,\n payload,\n options,\n });\n }\n\n /**\n * Submits a metric from pre-built request options via the fetch API. Updates\n * the \"$timings\" and \"originTime\" values to Date.now() since the existing times\n * were set when the options were built (not submitted).\n\n * @param {any} options - the pre-built request options for submitting a metric\n * @returns {Promise} promise that resolves to the response object\n */\n public setMetricTimingsAndFetch(options: any): Promise<any> {\n // @ts-ignore\n return this.webex.setTimingsAndFetch(setMetricTimings(options));\n }\n}\n\nexport default Metrics;\n"],"mappings":"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"}
@@ -50,7 +50,7 @@ export declare const isBrowserMediaErrorName: (errorName: any) => boolean;
50
50
  * @param webClientDomain
51
51
  * @returns
52
52
  */
53
- export declare const getBuildType: (webClientDomain: any) => Event['origin']['buildType'];
53
+ export declare const getBuildType: (webClientDomain: any, markAsTestEvent?: boolean) => Event['origin']['buildType'];
54
54
  /**
55
55
  * Prepare metric item for submission.
56
56
  * @param {Object} webex sdk instance
@@ -7,6 +7,7 @@ import NewMetrics from './new-metrics';
7
7
  import * as Utils from './utils';
8
8
  import { ClientEvent, ClientEventLeaveReason, SubmitBehavioralEvent, SubmitClientEvent, SubmitInternalEvent, SubmitOperationalEvent, SubmitMQE } from './metrics.types';
9
9
  import * as CALL_DIAGNOSTIC_CONFIG from './call-diagnostic/config';
10
+ import * as CallDiagnosticUtils from './call-diagnostic/call-diagnostic-metrics.util';
10
11
  export { default, getOSNameInternal } from './metrics';
11
- export { config, CALL_DIAGNOSTIC_CONFIG, NewMetrics, Utils };
12
+ export { config, CALL_DIAGNOSTIC_CONFIG, NewMetrics, Utils, CallDiagnosticUtils };
12
13
  export type { ClientEvent, ClientEventLeaveReason, SubmitBehavioralEvent, SubmitClientEvent, SubmitInternalEvent, SubmitMQE, SubmitOperationalEvent, };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@webex/internal-plugin-metrics",
3
- "version": "3.0.0-beta.232",
3
+ "version": "3.0.0-beta.234",
4
4
  "description": "",
5
5
  "license": "MIT",
6
6
  "main": "dist/index.js",
@@ -29,12 +29,12 @@
29
29
  "build": "yarn run -T tsc --declaration true --declarationDir ./dist/types"
30
30
  },
31
31
  "dependencies": {
32
- "@webex/common": "3.0.0-beta.232",
33
- "@webex/common-timers": "3.0.0-beta.232",
34
- "@webex/internal-plugin-device": "3.0.0-beta.232",
35
- "@webex/internal-plugin-metrics": "3.0.0-beta.232",
36
- "@webex/test-helper-chai": "3.0.0-beta.232",
37
- "@webex/test-helper-mock-webex": "3.0.0-beta.232",
38
- "@webex/webex-core": "3.0.0-beta.232"
32
+ "@webex/common": "3.0.0-beta.234",
33
+ "@webex/common-timers": "3.0.0-beta.234",
34
+ "@webex/internal-plugin-device": "3.0.0-beta.234",
35
+ "@webex/internal-plugin-metrics": "3.0.0-beta.234",
36
+ "@webex/test-helper-chai": "3.0.0-beta.234",
37
+ "@webex/test-helper-mock-webex": "3.0.0-beta.234",
38
+ "@webex/webex-core": "3.0.0-beta.234"
39
39
  }
40
40
  }
@@ -143,7 +143,15 @@ export const isBrowserMediaErrorName = (errorName: any) => {
143
143
  * @param webClientDomain
144
144
  * @returns
145
145
  */
146
- export const getBuildType = (webClientDomain): Event['origin']['buildType'] => {
146
+ export const getBuildType = (
147
+ webClientDomain,
148
+ markAsTestEvent = false
149
+ ): Event['origin']['buildType'] => {
150
+ // used temporary to test pre join in production without creating noise data, SPARK-468456
151
+ if (markAsTestEvent) {
152
+ return 'test';
153
+ }
154
+
147
155
  if (
148
156
  webClientDomain?.includes('localhost') ||
149
157
  webClientDomain?.includes('127.0.0.1') ||
@@ -163,7 +171,10 @@ export const getBuildType = (webClientDomain): Event['origin']['buildType'] => {
163
171
  */
164
172
  export const prepareDiagnosticMetricItem = (webex: any, item: any) => {
165
173
  const origin: Partial<Event['origin']> = {
166
- buildType: getBuildType(item.event?.eventData?.webClientDomain),
174
+ buildType: exports.getBuildType(
175
+ item.eventPayload?.event?.eventData?.webClientDomain,
176
+ item.eventPayload?.event?.eventData?.markAsTestEvent
177
+ ),
167
178
  networkType: 'unknown',
168
179
  };
169
180
 
package/src/index.ts CHANGED
@@ -20,6 +20,7 @@ import {
20
20
  SubmitMQE,
21
21
  } from './metrics.types';
22
22
  import * as CALL_DIAGNOSTIC_CONFIG from './call-diagnostic/config';
23
+ import * as CallDiagnosticUtils from './call-diagnostic/call-diagnostic-metrics.util';
23
24
 
24
25
  registerInternalPlugin('metrics', Metrics, {
25
26
  config,
@@ -30,7 +31,7 @@ registerInternalPlugin('newMetrics', NewMetrics, {
30
31
  });
31
32
 
32
33
  export {default, getOSNameInternal} from './metrics';
33
- export {config, CALL_DIAGNOSTIC_CONFIG, NewMetrics, Utils};
34
+ export {config, CALL_DIAGNOSTIC_CONFIG, NewMetrics, Utils, CallDiagnosticUtils};
34
35
  export type {
35
36
  ClientEvent,
36
37
  ClientEventLeaveReason,
@@ -161,6 +161,14 @@ class Metrics extends WebexPlugin {
161
161
  payload?: RecursivePartial<ClientEvent['payload']>;
162
162
  options?: SubmitClientEventOptions;
163
163
  }): Promise<any> {
164
+ if (!this.callDiagnosticLatencies || !this.callDiagnosticMetrics) {
165
+ // @ts-ignore
166
+ this.webex.logger.log(
167
+ `NewMetrics: @submitClientEvent. Attempted to submit before webex.ready. Event name: ${name}`
168
+ );
169
+
170
+ return Promise.resolve();
171
+ }
164
172
  this.callDiagnosticLatencies.saveTimestamp({
165
173
  key: name,
166
174
  options: {meetingId: options?.meetingId},
@@ -4,6 +4,7 @@
4
4
 
5
5
  import {assert} from '@webex/test-helper-chai';
6
6
  import {config, Utils} from '@webex/internal-plugin-metrics';
7
+ import {CallDiagnosticUtils} from '@webex/internal-plugin-metrics';
7
8
  import MockWebex from '@webex/test-helper-mock-webex';
8
9
  import sinon from 'sinon';
9
10
  import FakeTimers from '@sinonjs/fake-timers';
@@ -347,5 +348,51 @@ describe('plugin-metrics', () => {
347
348
  });
348
349
  });
349
350
  });
351
+
352
+ describe('prepareItem', () => {
353
+ it('calls prepareDiagnosticMetricItem correctly', async () => {
354
+ // avoid setting .sent timestamp
355
+ webex.internal.newMetrics.callDiagnosticMetrics.callDiagnosticEventsBatcher.prepareRequest =
356
+ (q) => Promise.resolve(q);
357
+
358
+ const prepareItemSpy = sinon.spy(webex.internal.newMetrics.callDiagnosticMetrics.callDiagnosticEventsBatcher, 'prepareItem');
359
+ const prepareDiagnosticMetricItemSpy = sinon.spy(CallDiagnosticUtils, 'prepareDiagnosticMetricItem');
360
+
361
+ const promise = webex.internal.newMetrics.callDiagnosticMetrics.submitToCallDiagnostics({
362
+ event: 'my.event',
363
+ });
364
+
365
+ await flushPromises();
366
+
367
+ clock.tick(config.metrics.batcherWait);
368
+
369
+ await promise;
370
+
371
+ const calls = prepareItemSpy.getCalls()[0];
372
+
373
+ // item also gets assigned a delay property but the key is a Symbol and haven't been able to test that..
374
+ assert.deepEqual(calls.args[0].eventPayload, {
375
+ event: 'my.event',
376
+ origin: {buildType: 'test', networkType: 'unknown'},
377
+ });
378
+
379
+ assert.deepEqual(calls.args[0].type, ['diagnostic-event']);
380
+
381
+
382
+ const prepareDiagnosticMetricItemCalls = prepareDiagnosticMetricItemSpy.getCalls()
383
+
384
+ // second argument (item) also gets assigned a delay property but the key is a Symbol and haven't been able to test that..
385
+ assert.deepEqual(prepareDiagnosticMetricItemCalls[0].args[0], webex);
386
+ assert.deepEqual(prepareDiagnosticMetricItemCalls[0].args[1].eventPayload, {
387
+ event: 'my.event',
388
+ origin: {
389
+ buildType: 'test',
390
+ networkType: 'unknown',
391
+ },
392
+ });
393
+ assert.deepEqual(prepareDiagnosticMetricItemCalls[0].args[1].type, ['diagnostic-event']);
394
+
395
+ })
396
+ })
350
397
  });
351
398
  });
@@ -1,6 +1,10 @@
1
1
  import {assert} from '@webex/test-helper-chai';
2
2
  import sinon from 'sinon';
3
- import {
3
+
4
+ import * as CallDiagnosticUtils from '../../../../src/call-diagnostic/call-diagnostic-metrics.util';
5
+ import CallDiagnosticLatencies from '../../../../src/call-diagnostic/call-diagnostic-metrics-latencies';
6
+
7
+ const {
4
8
  clearEmptyKeysRecursively,
5
9
  extractVersionMetadata,
6
10
  getBuildType,
@@ -9,8 +13,7 @@ import {
9
13
  isMeetingInfoServiceError,
10
14
  prepareDiagnosticMetricItem,
11
15
  setMetricTimings,
12
- } from '../../../../src/call-diagnostic/call-diagnostic-metrics.util';
13
- import CallDiagnosticLatencies from '../../../../src/call-diagnostic/call-diagnostic-metrics-latencies';
16
+ } = CallDiagnosticUtils;
14
17
 
15
18
  describe('internal-plugin-metrics', () => {
16
19
  describe('clearEmptyKeysRecursively', () => {
@@ -135,12 +138,13 @@ describe('internal-plugin-metrics', () => {
135
138
  });
136
139
 
137
140
  [
138
- ['https://localhost', 'test'],
139
- ['https://127.0.0.1', 'test'],
140
- ['https://web.webex.com', 'prod'],
141
- ].forEach(([webClientDomain, expected]) => {
141
+ ['https://localhost', undefined, 'test'],
142
+ ['https://127.0.0.1', undefined, 'test'],
143
+ ['https://web.webex.com', undefined, 'prod'],
144
+ ['https://web.webex.com', true, 'test'],
145
+ ].forEach(([webClientDomain, markAsTestEvent, expected]) => {
142
146
  it(`returns expected result for ${webClientDomain}`, () => {
143
- assert.deepEqual(getBuildType(webClientDomain), expected);
147
+ assert.deepEqual(getBuildType(webClientDomain, markAsTestEvent as any), expected);
144
148
  });
145
149
  });
146
150
 
@@ -148,6 +152,11 @@ describe('internal-plugin-metrics', () => {
148
152
  process.env.NODE_ENV = 'foo';
149
153
  assert.deepEqual(getBuildType('production'), 'test');
150
154
  });
155
+
156
+ it('returns "test" for NODE_ENV "production" and markAsTestEvent = true', () => {
157
+ process.env.NODE_ENV = 'production';
158
+ assert.deepEqual(getBuildType('my.domain', true), 'test');
159
+ });
151
160
  });
152
161
 
153
162
  describe('prepareDiagnosticMetricItem', async () => {
@@ -272,6 +281,22 @@ describe('internal-plugin-metrics', () => {
272
281
  check(eventName as string, expectedEvent);
273
282
  });
274
283
  });
284
+
285
+ it('calls getBuildType correctly', () => {
286
+ const getBuildTypeSpy = sinon.spy(CallDiagnosticUtils, 'getBuildType');
287
+ const markAsTestEvent = true;
288
+ const webClientDomain = 'https://web.webex.com';
289
+
290
+ // just submit any event
291
+ prepareDiagnosticMetricItem(webex, {
292
+ eventPayload: {
293
+ event: {name: 'client.exit.app', eventData: {markAsTestEvent, webClientDomain}}
294
+ },
295
+ type: ['diagnostic-event'],
296
+ });
297
+
298
+ assert.calledOnceWithExactly(getBuildTypeSpy, webClientDomain, markAsTestEvent);
299
+ })
275
300
  });
276
301
 
277
302
  describe('setMetricTimings', async () => {
@@ -5,6 +5,40 @@ import sinon from 'sinon';
5
5
  import {Utils} from '@webex/internal-plugin-metrics';
6
6
 
7
7
  describe('internal-plugin-metrics', () => {
8
+
9
+ describe('check submitClientEvent when webex is not ready', () => {
10
+ let webex;
11
+ //@ts-ignore
12
+ webex = new MockWebex({
13
+ children: {
14
+ newMetrics: NewMetrics,
15
+ },
16
+ meetings: {
17
+ meetingCollection: {
18
+ get: sinon.stub(),
19
+ },
20
+ },
21
+ request: sinon.stub().resolves({}),
22
+ logger: {
23
+ log: sinon.stub(),
24
+ error: sinon.stub(),
25
+ }
26
+ });
27
+
28
+ it('checks the log', () => {
29
+ webex.internal.newMetrics.submitClientEvent({
30
+ name: 'client.alert.displayed',
31
+ options: {
32
+ meetingId: '123',
33
+ },
34
+ });
35
+ assert.calledWith(
36
+ webex.logger.log,
37
+ 'NewMetrics: @submitClientEvent. Attempted to submit before webex.ready. Event name: client.alert.displayed'
38
+ );
39
+ });
40
+ });
41
+
8
42
  describe('new-metrics', () => {
9
43
  let webex;
10
44
 
@@ -62,6 +96,7 @@ describe('internal-plugin-metrics', () => {
62
96
  });
63
97
  });
64
98
 
99
+
65
100
  it('submits MQE successfully', () => {
66
101
  webex.internal.newMetrics.submitMQE({
67
102
  name: 'client.mediaquality.event',