Skip to content

Commit 4bf90f7

Browse files
authoredJan 13, 2021
feat(client): update banner with connection, test status, ping times (#3611)
The banner is visible in videos so we can have some client side info on the state if it breaks.
1 parent 68c4a3a commit 4bf90f7

File tree

5 files changed

+132
-39
lines changed

5 files changed

+132
-39
lines changed
 

‎client/karma.js

+9-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,8 @@ var stringify = require('../common/stringify')
22
var constant = require('./constants')
33
var util = require('../common/util')
44

5-
function Karma (socket, iframe, opener, navigator, location, document) {
5+
function Karma (updater, socket, iframe, opener, navigator, location, document) {
6+
this.updater = updater
67
var startEmitted = false
78
var karmaNavigating = false
89
var self = this
@@ -190,6 +191,7 @@ function Karma (socket, iframe, opener, navigator, location, document) {
190191
}
191192

192193
socket.emit('karma_error', message)
194+
self.updater.updateTestStatus(`karma_error ${message}`)
193195
this.complete()
194196
return false
195197
}
@@ -212,17 +214,20 @@ function Karma (socket, iframe, opener, navigator, location, document) {
212214

213215
if (!startEmitted) {
214216
socket.emit('start', { total: null })
217+
self.updater.updateTestStatus('start')
215218
startEmitted = true
216219
}
217220

218221
if (resultsBufferLimit === 1) {
222+
self.updater.updateTestStatus('result')
219223
return socket.emit('result', convertedResult)
220224
}
221225

222226
resultsBuffer.push(convertedResult)
223227

224228
if (resultsBuffer.length === resultsBufferLimit) {
225229
socket.emit('result', resultsBuffer)
230+
self.updater.updateTestStatus('result')
226231
resultsBuffer = []
227232
}
228233
}
@@ -232,6 +237,7 @@ function Karma (socket, iframe, opener, navigator, location, document) {
232237
socket.emit('result', resultsBuffer)
233238
resultsBuffer = []
234239
}
240+
235241
// A test could have incorrectly issued a navigate. Wait one turn
236242
// to ensure the error from an incorrect navigate is processed.
237243
setTimeout(() => {
@@ -240,6 +246,7 @@ function Karma (socket, iframe, opener, navigator, location, document) {
240246
}
241247

242248
socket.emit('complete', result || {})
249+
self.updater.updateTestStatus('complete')
243250

244251
if (returnUrl) {
245252
location.href = returnUrl
@@ -258,6 +265,7 @@ function Karma (socket, iframe, opener, navigator, location, document) {
258265
}
259266

260267
socket.on('execute', function (cfg) {
268+
self.updater.updateTestStatus('execute')
261269
// reset startEmitted and reload the iframe
262270
startEmitted = false
263271
self.config = cfg

‎client/main.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,6 @@ var socket = io(location.host, {
2020
})
2121

2222
// instantiate the updater of the view
23-
new StatusUpdater(socket, util.elm('title'), util.elm('banner'), util.elm('browsers'))
24-
window.karma = new Karma(socket, util.elm('context'), window.open,
23+
var updater = new StatusUpdater(socket, util.elm('title'), util.elm('banner'), util.elm('browsers'))
24+
window.karma = new Karma(updater, socket, util.elm('context'), window.open,
2525
window.navigator, window.location, window.document)

‎client/updater.js

+48-14
Original file line numberDiff line numberDiff line change
@@ -21,26 +21,60 @@ function StatusUpdater (socket, titleElement, bannerElement, browsersElement) {
2121
}
2222
}
2323

24-
function updateBanner (status) {
25-
return function (param) {
26-
if (!titleElement || !bannerElement) {
27-
return
28-
}
29-
var paramStatus = param ? status.replace('$', param) : status
30-
titleElement.textContent = 'Karma v' + VERSION + ' - ' + paramStatus
31-
bannerElement.className = status === 'connected' ? 'online' : 'offline'
24+
var connectionText = 'never-connected'
25+
var testText = 'loading'
26+
var pingText = ''
27+
28+
function updateBanner () {
29+
if (!titleElement || !bannerElement) {
30+
return
3231
}
32+
titleElement.textContent = `Karma v ${VERSION} - ${connectionText}; test: ${testText}; ${pingText}`
33+
bannerElement.className = connectionText === 'connected' ? 'online' : 'offline'
34+
}
35+
36+
function updateConnectionStatus (connectionStatus) {
37+
connectionText = connectionStatus || connectionText
38+
updateBanner()
3339
}
40+
function updateTestStatus (testStatus) {
41+
testText = testStatus || testText
42+
updateBanner()
43+
}
44+
function updatePingStatus (pingStatus) {
45+
pingText = pingStatus || pingText
46+
updateBanner()
47+
}
48+
49+
socket.on('connect', () => {
50+
updateConnectionStatus('connected')
51+
})
52+
socket.on('disconnect', () => {
53+
updateConnectionStatus('disconnected')
54+
})
55+
socket.on('reconnecting', (sec) => {
56+
updateConnectionStatus(`reconnecting in ${sec} seconds`)
57+
})
58+
socket.on('reconnect', () => {
59+
updateConnectionStatus('reconnected')
60+
})
61+
socket.on('reconnect_failed', () => {
62+
updateConnectionStatus('reconnect_failed')
63+
})
3464

35-
socket.on('connect', updateBanner('connected'))
36-
socket.on('disconnect', updateBanner('disconnected'))
37-
socket.on('reconnecting', updateBanner('reconnecting in $ seconds...'))
38-
socket.on('reconnect', updateBanner('connected'))
39-
socket.on('reconnect_failed', updateBanner('failed to reconnect'))
4065
socket.on('info', updateBrowsersInfo)
41-
socket.on('disconnect', function () {
66+
socket.on('disconnect', () => {
4267
updateBrowsersInfo([])
4368
})
69+
70+
socket.on('ping', () => {
71+
updatePingStatus('ping...')
72+
})
73+
socket.on('pong', (latency) => {
74+
updatePingStatus(`ping ${latency}ms`)
75+
})
76+
77+
return { updateTestStatus: updateTestStatus }
4478
}
4579

4680
module.exports = StatusUpdater

‎static/karma.js

+59-17
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,8 @@ var stringify = require('../common/stringify')
1212
var constant = require('./constants')
1313
var util = require('../common/util')
1414

15-
function Karma (socket, iframe, opener, navigator, location, document) {
15+
function Karma (updater, socket, iframe, opener, navigator, location, document) {
16+
this.updater = updater
1617
var startEmitted = false
1718
var karmaNavigating = false
1819
var self = this
@@ -200,6 +201,7 @@ function Karma (socket, iframe, opener, navigator, location, document) {
200201
}
201202

202203
socket.emit('karma_error', message)
204+
self.updater.updateTestStatus(`karma_error ${message}`)
203205
this.complete()
204206
return false
205207
}
@@ -222,17 +224,20 @@ function Karma (socket, iframe, opener, navigator, location, document) {
222224

223225
if (!startEmitted) {
224226
socket.emit('start', { total: null })
227+
self.updater.updateTestStatus('start')
225228
startEmitted = true
226229
}
227230

228231
if (resultsBufferLimit === 1) {
232+
self.updater.updateTestStatus('result')
229233
return socket.emit('result', convertedResult)
230234
}
231235

232236
resultsBuffer.push(convertedResult)
233237

234238
if (resultsBuffer.length === resultsBufferLimit) {
235239
socket.emit('result', resultsBuffer)
240+
self.updater.updateTestStatus('result')
236241
resultsBuffer = []
237242
}
238243
}
@@ -242,6 +247,7 @@ function Karma (socket, iframe, opener, navigator, location, document) {
242247
socket.emit('result', resultsBuffer)
243248
resultsBuffer = []
244249
}
250+
245251
// A test could have incorrectly issued a navigate. Wait one turn
246252
// to ensure the error from an incorrect navigate is processed.
247253
setTimeout(() => {
@@ -250,6 +256,7 @@ function Karma (socket, iframe, opener, navigator, location, document) {
250256
}
251257

252258
socket.emit('complete', result || {})
259+
self.updater.updateTestStatus('complete')
253260

254261
if (returnUrl) {
255262
location.href = returnUrl
@@ -268,6 +275,7 @@ function Karma (socket, iframe, opener, navigator, location, document) {
268275
}
269276

270277
socket.on('execute', function (cfg) {
278+
self.updater.updateTestStatus('execute')
271279
// reset startEmitted and reload the iframe
272280
startEmitted = false
273281
self.config = cfg
@@ -340,8 +348,8 @@ var socket = io(location.host, {
340348
})
341349

342350
// instantiate the updater of the view
343-
new StatusUpdater(socket, util.elm('title'), util.elm('banner'), util.elm('browsers'))
344-
window.karma = new Karma(socket, util.elm('context'), window.open,
351+
var updater = new StatusUpdater(socket, util.elm('title'), util.elm('banner'), util.elm('browsers'))
352+
window.karma = new Karma(updater, socket, util.elm('context'), window.open,
345353
window.navigator, window.location, window.document)
346354

347355
},{"../common/util":6,"./constants":1,"./karma":2,"./updater":4}],4:[function(require,module,exports){
@@ -368,26 +376,60 @@ function StatusUpdater (socket, titleElement, bannerElement, browsersElement) {
368376
}
369377
}
370378

371-
function updateBanner (status) {
372-
return function (param) {
373-
if (!titleElement || !bannerElement) {
374-
return
375-
}
376-
var paramStatus = param ? status.replace('$', param) : status
377-
titleElement.textContent = 'Karma v' + VERSION + ' - ' + paramStatus
378-
bannerElement.className = status === 'connected' ? 'online' : 'offline'
379+
var connectionText = 'never-connected'
380+
var testText = 'loading'
381+
var pingText = ''
382+
383+
function updateBanner () {
384+
if (!titleElement || !bannerElement) {
385+
return
379386
}
387+
titleElement.textContent = `Karma v ${VERSION} - ${connectionText}; test: ${testText}; ${pingText}`
388+
bannerElement.className = connectionText === 'connected' ? 'online' : 'offline'
380389
}
381390

382-
socket.on('connect', updateBanner('connected'))
383-
socket.on('disconnect', updateBanner('disconnected'))
384-
socket.on('reconnecting', updateBanner('reconnecting in $ seconds...'))
385-
socket.on('reconnect', updateBanner('connected'))
386-
socket.on('reconnect_failed', updateBanner('failed to reconnect'))
391+
function updateConnectionStatus (connectionStatus) {
392+
connectionText = connectionStatus || connectionText
393+
updateBanner()
394+
}
395+
function updateTestStatus (testStatus) {
396+
testText = testStatus || testText
397+
updateBanner()
398+
}
399+
function updatePingStatus (pingStatus) {
400+
pingText = pingStatus || pingText
401+
updateBanner()
402+
}
403+
404+
socket.on('connect', () => {
405+
updateConnectionStatus('connected')
406+
})
407+
socket.on('disconnect', () => {
408+
updateConnectionStatus('disconnected')
409+
})
410+
socket.on('reconnecting', (sec) => {
411+
updateConnectionStatus(`reconnecting in ${sec} seconds`)
412+
})
413+
socket.on('reconnect', () => {
414+
updateConnectionStatus('reconnected')
415+
})
416+
socket.on('reconnect_failed', () => {
417+
updateConnectionStatus('reconnect_failed')
418+
})
419+
387420
socket.on('info', updateBrowsersInfo)
388-
socket.on('disconnect', function () {
421+
socket.on('disconnect', () => {
389422
updateBrowsersInfo([])
390423
})
424+
425+
socket.on('ping', () => {
426+
updatePingStatus('ping...')
427+
})
428+
socket.on('pong', (latency) => {
429+
updatePingStatus(`ping ${latency}ms`)
430+
})
431+
432+
return { updateTestStatus: updateTestStatus }
391433
}
392434

393435
module.exports = StatusUpdater

‎test/client/karma.spec.js

+14-5
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,21 @@ var ContextKarma = require('../../context/karma')
66
var MockSocket = require('./mocks').Socket
77

88
describe('Karma', function () {
9-
var socket, k, ck, windowNavigator, windowLocation, windowStub, startSpy, iframe, clientWindow
10-
var windowDocument, elements
9+
var updater, socket, k, ck, windowNavigator, windowLocation, windowStub, startSpy, iframe, clientWindow
10+
var windowDocument, elements, mockTestStatus
1111

1212
function setTransportTo (transportName) {
1313
socket._setTransportNameTo(transportName)
1414
socket.emit('connect')
1515
}
1616

1717
beforeEach(function () {
18+
mockTestStatus = ''
19+
updater = {
20+
updateTestStatus: (s) => {
21+
mockTestStatus = s
22+
}
23+
}
1824
socket = new MockSocket()
1925
iframe = {}
2026
windowNavigator = {}
@@ -23,7 +29,7 @@ describe('Karma', function () {
2329
elements = [{ style: {} }, { style: {} }]
2430
windowDocument = { querySelectorAll: sinon.stub().returns(elements) }
2531

26-
k = new ClientKarma(socket, iframe, windowStub, windowNavigator, windowLocation, windowDocument)
32+
k = new ClientKarma(updater, socket, iframe, windowStub, windowNavigator, windowLocation, windowDocument)
2733
clientWindow = {
2834
karma: k
2935
}
@@ -217,7 +223,7 @@ describe('Karma', function () {
217223
it('should report browser id', function () {
218224
windowLocation.search = '?id=567'
219225
socket = new MockSocket()
220-
k = new ClientKarma(socket, {}, windowStub, windowNavigator, windowLocation)
226+
k = new ClientKarma(updater, socket, {}, windowStub, windowNavigator, windowLocation)
221227

222228
var spyInfo = sinon.spy(function (info) {
223229
assert(info.id === '567')
@@ -439,7 +445,7 @@ describe('Karma', function () {
439445
it('should navigate the client to return_url if specified', function (done) {
440446
windowLocation.search = '?id=567&return_url=http://return.com'
441447
socket = new MockSocket()
442-
k = new ClientKarma(socket, iframe, windowStub, windowNavigator, windowLocation)
448+
k = new ClientKarma(updater, socket, iframe, windowStub, windowNavigator, windowLocation)
443449
clientWindow = { karma: k }
444450
ck = new ContextKarma(ContextKarma.getDirectCallParentKarmaMethod(clientWindow))
445451
ck.config = {}
@@ -479,11 +485,14 @@ describe('Karma', function () {
479485
}
480486

481487
socket.emit('execute', config)
488+
assert(mockTestStatus === 'execute')
489+
482490
clock.tick(1)
483491
var CURRENT_URL = iframe.src
484492
ck.complete()
485493
clock.tick(1)
486494
assert.strictEqual(iframe.src, CURRENT_URL)
495+
assert(mockTestStatus === 'complete')
487496
})
488497

489498
it('should accept multiple calls to loaded', function () {

0 commit comments

Comments
 (0)
Please sign in to comment.