@webex/internal-plugin-mercury 3.0.0-beta.9 → 3.0.0-bnr.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/src/mercury.js CHANGED
@@ -15,16 +15,11 @@ import {
15
15
  Forbidden,
16
16
  NotAuthorized,
17
17
  UnknownResponse,
18
- ConnectionError
18
+ ConnectionError,
19
19
  // NotFound
20
20
  } from './errors';
21
21
 
22
- const normalReconnectReasons = [
23
- 'idle',
24
- 'done (forced)',
25
- 'pong not received',
26
- 'pong mismatch'
27
- ];
22
+ const normalReconnectReasons = ['idle', 'done (forced)', 'pong not received', 'pong mismatch'];
28
23
 
29
24
  const Mercury = WebexPlugin.extend({
30
25
  namespace: 'Mercury',
@@ -32,14 +27,14 @@ const Mercury = WebexPlugin.extend({
32
27
  session: {
33
28
  connected: {
34
29
  default: false,
35
- type: 'boolean'
30
+ type: 'boolean',
36
31
  },
37
32
  connecting: {
38
33
  default: false,
39
- type: 'boolean'
34
+ type: 'boolean',
40
35
  },
41
36
  socket: 'object',
42
- localClusterServiceUrls: 'object'
37
+ localClusterServiceUrls: 'object',
43
38
  },
44
39
 
45
40
  derived: {
@@ -47,8 +42,8 @@ const Mercury = WebexPlugin.extend({
47
42
  deps: ['connected'],
48
43
  fn() {
49
44
  return this.connected;
50
- }
51
- }
45
+ },
46
+ },
52
47
  },
53
48
 
54
49
  @oneFlight
@@ -61,12 +56,13 @@ const Mercury = WebexPlugin.extend({
61
56
 
62
57
  this.connecting = true;
63
58
 
64
- return Promise.resolve(this.webex.internal.device.registered || this.webex.internal.device.register())
65
- .then(() => {
66
- this.logger.info('mercury: connecting');
59
+ return Promise.resolve(
60
+ this.webex.internal.device.registered || this.webex.internal.device.register()
61
+ ).then(() => {
62
+ this.logger.info('mercury: connecting');
67
63
 
68
- return this._connectWithBackoff(webSocketUrl);
69
- });
64
+ return this._connectWithBackoff(webSocketUrl);
65
+ });
70
66
  },
71
67
 
72
68
  @oneFlight
@@ -121,7 +117,8 @@ const Mercury = WebexPlugin.extend({
121
117
  webSocketUrl = this.webex.internal.device.webSocketUrl;
122
118
  }
123
119
 
124
- return this.webex.internal.feature.getFeature('developer', 'web-high-availability')
120
+ return this.webex.internal.feature
121
+ .getFeature('developer', 'web-high-availability')
125
122
  .then((haMessagingEnabled) => {
126
123
  if (haMessagingEnabled) {
127
124
  return this.webex.internal.services.convertUrlToPriorityHostUrl(webSocketUrl);
@@ -138,13 +135,13 @@ const Mercury = WebexPlugin.extend({
138
135
  Object.assign(webSocketUrl.query, {
139
136
  outboundWireFormat: 'text',
140
137
  bufferStates: true,
141
- aliasHttpStatus: true
138
+ aliasHttpStatus: true,
142
139
  });
143
140
 
144
141
  if (webSharedMercury) {
145
142
  Object.assign(webSocketUrl.query, {
146
143
  mercuryRegistrationStatus: true,
147
- isRegistrationRefreshEnabled: true
144
+ isRegistrationRefreshEnabled: true,
148
145
  });
149
146
  Reflect.deleteProperty(webSocketUrl.query, 'bufferStates');
150
147
  }
@@ -183,7 +180,7 @@ const Mercury = WebexPlugin.extend({
183
180
  pongTimeout: this.config.pongTimeout,
184
181
  token: token.toString(),
185
182
  trackingId: `${this.webex.sessionId}_${Date.now()}`,
186
- logger: this.logger
183
+ logger: this.logger,
187
184
  };
188
185
 
189
186
  // if the consumer has supplied request options use them
@@ -201,16 +198,17 @@ const Mercury = WebexPlugin.extend({
201
198
  .then(() => {
202
199
  this.webex.internal.metrics.submitClientMetrics('web-ha-mercury', {
203
200
  fields: {
204
- success: true
201
+ success: true,
205
202
  },
206
203
  tags: {
207
204
  action: 'connected',
208
- url: attemptWSUrl
209
- }
205
+ url: attemptWSUrl,
206
+ },
210
207
  });
211
208
  callback();
212
209
 
213
- return this.webex.internal.feature.getFeature('developer', 'web-high-availability')
210
+ return this.webex.internal.feature
211
+ .getFeature('developer', 'web-high-availability')
214
212
  .then((haMessagingEnabled) => {
215
213
  if (haMessagingEnabled) {
216
214
  return this.webex.internal.device.refresh();
@@ -231,17 +229,17 @@ const Mercury = WebexPlugin.extend({
231
229
  // UnknownResponse is produced by IE for any 4XXX; treated it like a bad
232
230
  // web socket url and let WDM handle the token checking
233
231
  if (reason instanceof UnknownResponse) {
234
- this.logger.info('mercury: received unknown response code, refreshing device registration');
232
+ this.logger.info(
233
+ 'mercury: received unknown response code, refreshing device registration'
234
+ );
235
235
 
236
- return this.webex.internal.device.refresh()
237
- .then(() => callback(reason));
236
+ return this.webex.internal.device.refresh().then(() => callback(reason));
238
237
  }
239
238
  // NotAuthorized implies expired token
240
239
  if (reason instanceof NotAuthorized) {
241
240
  this.logger.info('mercury: received authorization error, reauthorizing');
242
241
 
243
- return this.webex.credentials.refresh({force: true})
244
- .then(() => callback(reason));
242
+ return this.webex.credentials.refresh({force: true}).then(() => callback(reason));
245
243
  }
246
244
  // // NotFound implies expired web socket url
247
245
  // else if (reason instanceof NotFound) {
@@ -258,19 +256,22 @@ const Mercury = WebexPlugin.extend({
258
256
  return callback(reason);
259
257
  }
260
258
  if (reason instanceof ConnectionError) {
261
- return this.webex.internal.feature.getFeature('developer', 'web-high-availability')
259
+ return this.webex.internal.feature
260
+ .getFeature('developer', 'web-high-availability')
262
261
  .then((haMessagingEnabled) => {
263
262
  if (haMessagingEnabled) {
264
- this.logger.info('mercury: received a generic connection error, will try to connect to another datacenter');
263
+ this.logger.info(
264
+ 'mercury: received a generic connection error, will try to connect to another datacenter'
265
+ );
265
266
  this.webex.internal.metrics.submitClientMetrics('web-ha-mercury', {
266
267
  fields: {
267
- success: false
268
+ success: false,
268
269
  },
269
270
  tags: {
270
271
  action: 'failed',
271
272
  error: reason.message,
272
- url: attemptWSUrl
273
- }
273
+ url: attemptWSUrl,
274
+ },
274
275
  });
275
276
 
276
277
  return this.webex.internal.services.markFailedUrl(attemptWSUrl);
@@ -299,7 +300,9 @@ const Mercury = WebexPlugin.extend({
299
300
 
300
301
  this.backoffCall = undefined;
301
302
  if (err) {
302
- this.logger.info(`mercury: failed to connect after ${call.getNumRetries()} retries; log statement about next retry was inaccurate; ${err}`);
303
+ this.logger.info(
304
+ `mercury: failed to connect after ${call.getNumRetries()} retries; log statement about next retry was inaccurate; ${err}`
305
+ );
303
306
 
304
307
  return reject(err);
305
308
  }
@@ -315,10 +318,12 @@ const Mercury = WebexPlugin.extend({
315
318
  this._attemptConnection(webSocketUrl, callback);
316
319
  }, onComplete);
317
320
 
318
- call.setStrategy(new backoff.ExponentialStrategy({
319
- initialDelay: this.config.backoffTimeReset,
320
- maxDelay: this.config.backoffTimeMax
321
- }));
321
+ call.setStrategy(
322
+ new backoff.ExponentialStrategy({
323
+ initialDelay: this.config.backoffTimeReset,
324
+ maxDelay: this.config.backoffTimeMax,
325
+ })
326
+ );
322
327
 
323
328
  if (this.config.maxRetries) {
324
329
  call.failAfter(this.config.maxRetries);
@@ -334,7 +339,9 @@ const Mercury = WebexPlugin.extend({
334
339
  const number = call.getNumRetries();
335
340
  const delay = Math.min(call.strategy_.nextBackoffDelay_, this.config.backoffTimeMax);
336
341
 
337
- this.logger.info(`mercury: failed to connect; attempting retry ${number + 1} in ${delay} ms`);
342
+ this.logger.info(
343
+ `mercury: failed to connect; attempting retry ${number + 1} in ${delay} ms`
344
+ );
338
345
  /* istanbul ignore if */
339
346
  if (process.env.NODE_ENV === 'development') {
340
347
  this.logger.debug('mercury: ', err, err.stack);
@@ -354,8 +361,7 @@ const Mercury = WebexPlugin.extend({
354
361
  _emit(...args) {
355
362
  try {
356
363
  this.trigger(...args);
357
- }
358
- catch (error) {
364
+ } catch (error) {
359
365
  this.logger.error('mercury: error occurred in event handler', error);
360
366
  }
361
367
  },
@@ -373,7 +379,7 @@ const Mercury = WebexPlugin.extend({
373
379
  if ((this.webex[namespace] || this.webex.internal[namespace])[handlerName]) {
374
380
  handlers.push({
375
381
  name: handlerName,
376
- namespace
382
+ namespace,
377
383
  });
378
384
  }
379
385
 
@@ -395,8 +401,10 @@ const Mercury = WebexPlugin.extend({
395
401
 
396
402
  switch (event.code) {
397
403
  case 1003:
398
- // metric: disconnect
399
- this.logger.info(`mercury: Mercury service rejected last message; will not reconnect: ${event.reason}`);
404
+ // metric: disconnect
405
+ this.logger.info(
406
+ `mercury: Mercury service rejected last message; will not reconnect: ${event.reason}`
407
+ );
400
408
  this._emit('offline.permanent', event);
401
409
  break;
402
410
  case 4000:
@@ -421,8 +429,7 @@ const Mercury = WebexPlugin.extend({
421
429
  this._reconnect(socketUrl);
422
430
  // metric: disconnect
423
431
  // if (reason === done forced) metric: force closure
424
- }
425
- else {
432
+ } else {
426
433
  this.logger.info('mercury: socket disconnected; will not reconnect');
427
434
  this._emit('offline.permanent', event);
428
435
  }
@@ -432,8 +439,7 @@ const Mercury = WebexPlugin.extend({
432
439
  // unexpected disconnect
433
440
  this._emit('offline.permanent', event);
434
441
  }
435
- }
436
- catch (error) {
442
+ } catch (error) {
437
443
  this.logger.error('mercury: error occurred in close handler', error);
438
444
  }
439
445
  },
@@ -450,20 +456,29 @@ const Mercury = WebexPlugin.extend({
450
456
  this._applyOverrides(data);
451
457
 
452
458
  return this._getEventHandlers(data.eventType)
453
- .reduce((promise, handler) => promise.then(() => {
454
- const {namespace, name} = handler;
455
-
456
- return new Promise((resolve) => resolve((this.webex[namespace] || this.webex.internal[namespace])[name](data)))
457
- .catch((reason) => this.logger.error(`mercury: error occurred in autowired event handler for ${data.eventType}`, reason));
458
- }), Promise.resolve())
459
+ .reduce(
460
+ (promise, handler) =>
461
+ promise.then(() => {
462
+ const {namespace, name} = handler;
463
+
464
+ return new Promise((resolve) =>
465
+ resolve((this.webex[namespace] || this.webex.internal[namespace])[name](data))
466
+ ).catch((reason) =>
467
+ this.logger.error(
468
+ `mercury: error occurred in autowired event handler for ${data.eventType}`,
469
+ reason
470
+ )
471
+ );
472
+ }),
473
+ Promise.resolve()
474
+ )
459
475
  .then(() => {
460
476
  this._emit('event', event.data);
461
477
  const [namespace] = data.eventType.split('.');
462
478
 
463
479
  if (namespace === data.eventType) {
464
480
  this._emit(`event:${namespace}`, envelope);
465
- }
466
- else {
481
+ } else {
467
482
  this._emit(`event:${namespace}`, envelope);
468
483
  this._emit(`event:${data.eventType}`, envelope);
469
484
  }
@@ -477,7 +492,7 @@ const Mercury = WebexPlugin.extend({
477
492
  this.logger.info('mercury: reconnecting');
478
493
 
479
494
  return this.connect(webSocketUrl);
480
- }
495
+ },
481
496
  });
482
497
 
483
498
  export default Mercury;
@@ -14,7 +14,7 @@ import {
14
14
  ConnectionError,
15
15
  Forbidden,
16
16
  NotAuthorized,
17
- UnknownResponse
17
+ UnknownResponse,
18
18
  // NotFound
19
19
  } from '../errors';
20
20
 
@@ -88,7 +88,9 @@ export default class Socket extends EventEmitter {
88
88
  * @returns {WebSocket}
89
89
  */
90
90
  static getWebSocketConstructor() {
91
- throw new Error('Socket.getWebSocketConstructor() must be implemented in an environmentally appropriate way');
91
+ throw new Error(
92
+ 'Socket.getWebSocketConstructor() must be implemented in an environmentally appropriate way'
93
+ );
92
94
  }
93
95
 
94
96
  /**
@@ -127,18 +129,19 @@ export default class Socket extends EventEmitter {
127
129
 
128
130
  options = defaults(options, {
129
131
  code: 1000,
130
- reason: 'Done'
132
+ reason: 'Done',
131
133
  });
132
134
 
133
135
  const closeTimer = safeSetTimeout(() => {
134
136
  try {
135
137
  this.logger.info('socket: no close event received, forcing closure');
136
- resolve(this.onclose({
137
- code: 1000,
138
- reason: 'Done (forced)'
139
- }));
140
- }
141
- catch (error) {
138
+ resolve(
139
+ this.onclose({
140
+ code: 1000,
141
+ reason: 'Done (forced)',
142
+ })
143
+ );
144
+ } catch (error) {
142
145
  this.logger.warn('socket: force-close failed', error);
143
146
  }
144
147
  }, this.forceCloseDelay);
@@ -184,19 +187,15 @@ export default class Socket extends EventEmitter {
184
187
 
185
188
  options = options || {};
186
189
 
187
- checkRequired([
188
- 'forceCloseDelay',
189
- 'pingInterval',
190
- 'pongTimeout',
191
- 'token',
192
- 'trackingId',
193
- 'logger'
194
- ], options);
190
+ checkRequired(
191
+ ['forceCloseDelay', 'pingInterval', 'pongTimeout', 'token', 'trackingId', 'logger'],
192
+ options
193
+ );
195
194
 
196
195
  Object.keys(options).forEach((key) => {
197
196
  Reflect.defineProperty(this, key, {
198
197
  enumerable: false,
199
- value: options[key]
198
+ value: options[key],
200
199
  });
201
200
  });
202
201
 
@@ -213,10 +212,10 @@ export default class Socket extends EventEmitter {
213
212
  this.logger.info('socket: closed before open', event.code, event.reason);
214
213
  switch (event.code) {
215
214
  case 1005:
216
- // IE 11 doesn't seem to allow 4XXX codes, so if we get a 1005, assume
217
- // it's a bad websocket url. That'll trigger a device refresh; if it
218
- // turns out we had a bad token, the device refresh should 401 and
219
- // trigger a token refresh.
215
+ // IE 11 doesn't seem to allow 4XXX codes, so if we get a 1005, assume
216
+ // it's a bad websocket url. That'll trigger a device refresh; if it
217
+ // turns out we had a bad token, the device refresh should 401 and
218
+ // trigger a token refresh.
220
219
  return reject(new UnknownResponse(event));
221
220
  case 4400:
222
221
  return reject(new BadRequest(event));
@@ -224,8 +223,8 @@ export default class Socket extends EventEmitter {
224
223
  return reject(new NotAuthorized(event));
225
224
  case 4403:
226
225
  return reject(new Forbidden(event));
227
- // case 4404:
228
- // return reject(new NotFound(event));
226
+ // case 4404:
227
+ // return reject(new NotFound(event));
229
228
  default:
230
229
  return reject(new ConnectionError(event));
231
230
  }
@@ -281,7 +280,9 @@ export default class Socket extends EventEmitter {
281
280
 
282
281
  this.logger.debug('socket: sequence number: ', sequenceNumber);
283
282
  if (this.expectedSequenceNumber && sequenceNumber !== this.expectedSequenceNumber) {
284
- this.logger.debug(`socket: sequence number mismatch indicates lost mercury message. expected: ${this.expectedSequenceNumber}, actual: ${sequenceNumber}`);
283
+ this.logger.debug(
284
+ `socket: sequence number mismatch indicates lost mercury message. expected: ${this.expectedSequenceNumber}, actual: ${sequenceNumber}`
285
+ );
285
286
  this.emit('sequence-mismatch', sequenceNumber, this.expectedSequenceNumber);
286
287
  }
287
288
  this.expectedSequenceNumber = sequenceNumber + 1;
@@ -294,12 +295,10 @@ export default class Socket extends EventEmitter {
294
295
  this._acknowledge(processedEvent);
295
296
  if (data.type === 'pong') {
296
297
  this.emit('pong', processedEvent);
297
- }
298
- else {
298
+ } else {
299
299
  this.emit('message', processedEvent);
300
300
  }
301
- }
302
- catch (error) {
301
+ } catch (error) {
303
302
  // The above code should only be able to throw if we receive an unparsable
304
303
  // message from Mercury. At this time, the only action we have is to
305
304
  // ignore it and move on.
@@ -347,7 +346,7 @@ export default class Socket extends EventEmitter {
347
346
 
348
347
  return this.send({
349
348
  messageId: event.data.id,
350
- type: 'ack'
349
+ type: 'ack',
351
350
  });
352
351
  }
353
352
 
@@ -363,14 +362,18 @@ export default class Socket extends EventEmitter {
363
362
  id: uuid.v4(),
364
363
  type: 'authorization',
365
364
  data: {
366
- token: this.token
365
+ token: this.token,
367
366
  },
368
367
  trackingId: this.trackingId,
369
- logLevelToken: this.logLevelToken
368
+ logLevelToken: this.logLevelToken,
370
369
  });
371
370
 
372
371
  const waitForBufferState = (event) => {
373
- if (!event.data.type && (event.data.data.eventType === 'mercury.buffer_state' || event.data.data.eventType === 'mercury.registration_status')) {
372
+ if (
373
+ !event.data.type &&
374
+ (event.data.data.eventType === 'mercury.buffer_state' ||
375
+ event.data.data.eventType === 'mercury.registration_status')
376
+ ) {
374
377
  this.removeListener('message', waitForBufferState);
375
378
  this._ping();
376
379
  resolve();
@@ -423,11 +426,10 @@ export default class Socket extends EventEmitter {
423
426
  this.logger.debug('socket: expected', id, 'received', event.data.id);
424
427
  this.close({
425
428
  code: 1000,
426
- reason: 'Pong mismatch'
429
+ reason: 'Pong mismatch',
427
430
  });
428
431
  }
429
- }
430
- catch (error) {
432
+ } catch (error) {
431
433
  // This try/catch block was added as a debugging step; to the best of my
432
434
  // knowledge, the above can never throw.
433
435
  /* istanbul ignore next */
@@ -440,13 +442,11 @@ export default class Socket extends EventEmitter {
440
442
  this.logger.info('socket: pong not receive in expected period, closing socket');
441
443
  this.close({
442
444
  code: 1000,
443
- reason: 'Pong not received'
444
- })
445
- .catch((reason) => {
446
- this.logger.warn('socket: failed to close socket after missed pong', reason);
447
- });
448
- }
449
- catch (error) {
445
+ reason: 'Pong not received',
446
+ }).catch((reason) => {
447
+ this.logger.warn('socket: failed to close socket after missed pong', reason);
448
+ });
449
+ } catch (error) {
450
450
  // This try/catch block was added as a debugging step; to the best of my
451
451
  // knowledge, the above can never throw.
452
452
  /* istanbul ignore next */
@@ -458,8 +458,7 @@ export default class Socket extends EventEmitter {
458
458
  try {
459
459
  clearTimeout(this.pongTimer);
460
460
  this.pingTimer = safeSetTimeout(() => this._ping(), this.pingInterval);
461
- }
462
- catch (error) {
461
+ } catch (error) {
463
462
  // This try/catch block was added as a debugging step; to the best of my
464
463
  // knowledge, the above can never throw.
465
464
  /* istanbul ignore next */
@@ -476,7 +475,7 @@ export default class Socket extends EventEmitter {
476
475
 
477
476
  return this.send({
478
477
  id,
479
- type: 'ping'
478
+ type: 'ping',
480
479
  });
481
480
  }
482
481
  }
@@ -1,3 +1,5 @@
1
+ /* eslint-disable no-restricted-globals */
2
+
1
3
  /*!
2
4
  * Copyright (c) 2015-2020 Cisco Systems, Inc. See LICENSE file.
3
5
  */
@@ -12,18 +14,14 @@ Socket.getWebSocketConstructor = function getWebSocketConstructor() {
12
14
 
13
15
  if (typeof WebSocket !== 'undefined') {
14
16
  ws = WebSocket;
15
- }
16
- else if (typeof MozWebSocket !== 'undefined') {
17
+ } else if (typeof MozWebSocket !== 'undefined') {
17
18
  // eslint-disable-next-line no-undef
18
19
  ws = MozWebSocket;
19
- }
20
- else if (typeof global !== 'undefined') {
20
+ } else if (typeof global !== 'undefined') {
21
21
  ws = global.WebSocket || global.MozWebSocket;
22
- }
23
- else if (typeof window !== 'undefined') {
22
+ } else if (typeof window !== 'undefined') {
24
23
  ws = window.WebSocket || window.MozWebSocket;
25
- }
26
- else if (typeof self !== 'undefined') {
24
+ } else if (typeof self !== 'undefined') {
27
25
  ws = self.WebSocket || self.MozWebSocket;
28
26
  }
29
27
 
@@ -16,34 +16,37 @@ describe('plugin-mercury', function () {
16
16
  describe('Mercury', () => {
17
17
  let webex;
18
18
 
19
- beforeEach(() => testUsers.create({count: 1})
20
- .then((users) => {
19
+ beforeEach(() =>
20
+ testUsers.create({count: 1}).then((users) => {
21
21
  webex = new WebexCore({
22
22
  credentials: {
23
- supertoken: users[0].token
23
+ supertoken: users[0].token,
24
24
  },
25
25
  config: {
26
26
  credentials: {
27
- refreshCallback
28
- }
29
- }
27
+ refreshCallback,
28
+ },
29
+ },
30
30
  });
31
- }));
31
+ })
32
+ );
32
33
 
33
34
  afterEach(() => webex && webex.internal.mercury.disconnect());
34
35
 
35
36
  describe('#connect()', () => {
36
37
  it('connects to mercury', () => webex.internal.mercury.connect());
37
38
 
38
- it('refreshes the access token when a 4401 is received', () => webex.internal.device.register()
39
- .then(() => {
40
- // eslint-disable-next-line camelcase
41
- webex.credentials.supertoken.access_token = 'fake token';
39
+ it('refreshes the access token when a 4401 is received', () =>
40
+ webex.internal.device
41
+ .register()
42
+ .then(() => {
43
+ // eslint-disable-next-line camelcase
44
+ webex.credentials.supertoken.access_token = 'fake token';
42
45
 
43
- return webex.internal.mercury.connect();
44
- })
45
- // eslint-disable-next-line camelcase
46
- .then(() => assert.notEqual(webex.credentials.supertoken.access_token, 'fake token')));
46
+ return webex.internal.mercury.connect();
47
+ })
48
+ // eslint-disable-next-line camelcase
49
+ .then(() => assert.notEqual(webex.credentials.supertoken.access_token, 'fake token')));
47
50
 
48
51
  // This doesn't work as designed yet. The only way to get a 4404 is to try
49
52
  // to connect to someone else's valid registration; the intent was to get
@@ -70,26 +73,34 @@ describe('plugin-mercury', function () {
70
73
  });
71
74
 
72
75
  describe('when web-high-availability is enabled', () => {
73
- flaky(it, process.env.SKIP_FLAKY_TESTS)('connects to mercury using service catalog url', () => {
74
- let defaultWebSocketUrl;
75
-
76
- // we need to ensure the feature is set for user before "registering"
77
- // the device
78
- return webex.internal.device.register()
79
- .then(() => webex.internal.feature.setFeature('developer', 'web-high-availability', true))
80
- .then(() => webex.internal.device.unregister())
81
- // start the test flow the device list
82
- .then(() => webex.internal.device.register())
83
- .then(() => {
84
- defaultWebSocketUrl = webex.internal.device.webSocketUrl;
85
- })
86
- .then(() => webex.internal.mercury.connect())
87
- .then(() => webex.internal.device.getWebSocketUrl())
88
- .then((wsUrl) => {
89
- assert.notEqual(defaultWebSocketUrl, webex.internal.mercury.socket.url);
90
- assert.include(webex.internal.mercury.socket.url, wsUrl);
91
- });
92
- });
76
+ flaky(it, process.env.SKIP_FLAKY_TESTS)(
77
+ 'connects to mercury using service catalog url',
78
+ () => {
79
+ let defaultWebSocketUrl;
80
+
81
+ // we need to ensure the feature is set for user before "registering"
82
+ // the device
83
+ return (
84
+ webex.internal.device
85
+ .register()
86
+ .then(() =>
87
+ webex.internal.feature.setFeature('developer', 'web-high-availability', true)
88
+ )
89
+ .then(() => webex.internal.device.unregister())
90
+ // start the test flow the device list
91
+ .then(() => webex.internal.device.register())
92
+ .then(() => {
93
+ defaultWebSocketUrl = webex.internal.device.webSocketUrl;
94
+ })
95
+ .then(() => webex.internal.mercury.connect())
96
+ .then(() => webex.internal.device.getWebSocketUrl())
97
+ .then((wsUrl) => {
98
+ assert.notEqual(defaultWebSocketUrl, webex.internal.mercury.socket.url);
99
+ assert.include(webex.internal.mercury.socket.url, wsUrl);
100
+ })
101
+ );
102
+ }
103
+ );
93
104
  });
94
105
  });
95
106
 
@@ -98,10 +109,9 @@ describe('plugin-mercury', function () {
98
109
 
99
110
  webex.internal.mercury.on('event:mercury.buffer_state', spy);
100
111
 
101
- return webex.internal.mercury.connect()
102
- .then(() => {
103
- assert.calledOnce(spy);
104
- });
112
+ return webex.internal.mercury.connect().then(() => {
113
+ assert.calledOnce(spy);
114
+ });
105
115
  });
106
116
  });
107
117
  });